Skip to content

Commit

Permalink
hcp.v2.TelemetryState resource and controller implementation (#20257)
Browse files Browse the repository at this point in the history
* pbhcp: add TelemetryState resource

* agent/hcp: add GetObservabilitySecrets to client

* internal/hcp: add TelemetryState controller logic

* hcp/telemetry-state: added config options for hcp sdk and debug key to skip deletion during reconcile

* pbhcp: update proto documentation

* hcp: address PR feedback, additional validations and code cleanup

* internal/hcp: fix type sig change in test

* update testdata/v2-resource-dependencies
  • Loading branch information
nickethier authored Jan 31, 2024
1 parent 3e8ec8d commit 383d92e
Show file tree
Hide file tree
Showing 25 changed files with 1,547 additions and 55 deletions.
1 change: 1 addition & 0 deletions agent/consul/testdata/v2-resource-dependencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ flowchart TD
demo/v2/album
demo/v2/artist
hcp/v2/link
hcp/v2/telemetrystate --> hcp/v2/link
internal/v1/tombstone
mesh/v2beta1/apigateway
mesh/v2beta1/computedexplicitdestinations --> catalog/v2beta1/service
Expand Down
20 changes: 20 additions & 0 deletions agent/hcp/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const metricsGatewayPath = "/v1/metrics"
type Client interface {
FetchBootstrap(ctx context.Context) (*BootstrapConfig, error)
FetchTelemetryConfig(ctx context.Context) (*TelemetryConfig, error)
GetObservabilitySecret(ctx context.Context) (clientID, clientSecret string, err error)
PushServerStatus(ctx context.Context, status *ServerStatus) error
DiscoverServers(ctx context.Context) ([]string, error)
GetCluster(ctx context.Context) (*Cluster, error)
Expand Down Expand Up @@ -369,3 +370,22 @@ func decodeError(err error) error {

return err
}

func (c *hcpClient) GetObservabilitySecret(ctx context.Context) (string, string, error) {
params := hcpgnm.NewGetObservabilitySecretParamsWithContext(ctx).
WithID(c.resource.ID).
WithLocationOrganizationID(c.resource.Organization).
WithLocationProjectID(c.resource.Project)

resp, err := c.gnm.GetObservabilitySecret(params, nil)
if err != nil {
return "", "", err
}

if len(resp.GetPayload().Keys) == 0 {
return "", "", fmt.Errorf("no observability keys returned for cluster")
}

key := resp.GetPayload().Keys[len(resp.GetPayload().Keys)-1]
return key.ClientID, key.ClientSecret, nil
}
85 changes: 84 additions & 1 deletion agent/hcp/client/mock_Client.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 21 additions & 5 deletions internal/hcp/internal/controllers/link/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package link

import (
"context"
"crypto/tls"
"strings"

gnmmod "github.com/hashicorp/hcp-sdk-go/clients/cloud-global-network-manager-service/preview/2022-02-15/models"
Expand Down Expand Up @@ -149,11 +150,7 @@ func (r *linkReconciler) Reconcile(ctx context.Context, rt controller.Runtime, r
// 1. The HCP configuration (i.e., how to connect to HCP) is preserved
// 2. The Consul agent's node ID and node name are preserved
existingCfg := r.hcpManager.GetCloudConfig()
newCfg := config.CloudConfig{
ResourceID: link.ResourceId,
ClientID: link.ClientId,
ClientSecret: link.ClientSecret,
}
newCfg := CloudConfigFromLink(&link)
cfg := config.Merge(existingCfg, newCfg)
hcpClient, err := r.hcpClientFn(cfg)
if err != nil {
Expand Down Expand Up @@ -274,3 +271,22 @@ func (i *linkInitializer) Initialize(ctx context.Context, rt controller.Runtime)

return nil
}

func CloudConfigFromLink(link *pbhcp.Link) config.CloudConfig {
var cfg config.CloudConfig
if link == nil {
return cfg
}
cfg = config.CloudConfig{
ResourceID: link.GetResourceId(),
ClientID: link.GetClientId(),
ClientSecret: link.GetClientSecret(),
}
if link.GetHcpConfig() != nil {
cfg.AuthURL = link.GetHcpConfig().GetAuthUrl()
cfg.ScadaAddress = link.GetHcpConfig().GetScadaAddress()
cfg.Hostname = link.GetHcpConfig().GetApiAddress()
cfg.TLSConfig = &tls.Config{InsecureSkipVerify: link.GetHcpConfig().GetTlsInsecureSkipVerify()}
}
return cfg
}
19 changes: 19 additions & 0 deletions internal/hcp/internal/controllers/link/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/hashicorp/consul/agent/hcp/client"
"github.com/hashicorp/consul/internal/controller"
"github.com/hashicorp/consul/internal/resource"
pbhcp "github.com/hashicorp/consul/proto-public/pbhcp/v2"
"github.com/hashicorp/consul/proto-public/pbresource"
)

Expand Down Expand Up @@ -102,3 +103,21 @@ func linkingFailed(ctx context.Context, rt controller.Runtime, res *pbresource.R

return nil
}

func IsLinked(res *pbresource.Resource) (linked bool, reason string) {
if !resource.EqualType(res.GetId().GetType(), pbhcp.LinkType) {
return false, "resource is not hcp.Link type"
}

linkStatus, ok := res.GetStatus()[StatusKey]
if !ok {
return false, "link status not set"
}

for _, cond := range linkStatus.GetConditions() {
if cond.Type == StatusLinked && cond.GetState() == pbresource.Condition_STATE_TRUE {
return true, ""
}
}
return false, "link status does not include positive linked condition"
}
3 changes: 3 additions & 0 deletions internal/hcp/internal/controllers/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/hashicorp/consul/agent/hcp/config"
"github.com/hashicorp/consul/internal/controller"
"github.com/hashicorp/consul/internal/hcp/internal/controllers/link"
"github.com/hashicorp/consul/internal/hcp/internal/controllers/telemetrystate"
)

type Dependencies struct {
Expand All @@ -27,4 +28,6 @@ func Register(mgr *controller.Manager, deps Dependencies) {
deps.DataDir,
deps.HCPManager,
))

mgr.Register(telemetrystate.TelemetryStateController(link.DefaultHCPClientFn))
}
Loading

0 comments on commit 383d92e

Please sign in to comment.