consul/agent/hcp/scada/scada.go
Melissa Kam 5dc8eabcce
[CC-7041] Update and start the SCADA provider in HCP manager (#19976)
* Update SCADA provider version

Also update mocks for SCADA provider.

* Create SCADA provider w/o HCP config, then update

Adds a placeholder config option to allow us to initialize a SCADA provider
without the HCP configuration. Also adds an update method to then add the
HCP configuration. We need this to be able to eventually always register a
SCADA listener at startup before the HCP config values are known.

* Pass cloud configuration to HCP manager

Save the entire cloud configuration and pass it to the HCP
manager.

* Update and start SCADA provider in HCP manager

Move config updating and starting to the HCP manager. The HCP manager
will eventually be responsible for all processes that contribute
to linking to HCP.
2024-01-08 09:49:29 -06:00

98 lines
2.5 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package scada
import (
"fmt"
"net"
"github.com/hashicorp/consul/agent/hcp/config"
"github.com/hashicorp/go-hclog"
libscada "github.com/hashicorp/hcp-scada-provider"
"github.com/hashicorp/hcp-scada-provider/capability"
cloud "github.com/hashicorp/hcp-sdk-go/clients/cloud-shared/v1/models"
hcpcfg "github.com/hashicorp/hcp-sdk-go/config"
)
// Provider is the interface used in the rest of Consul core when using SCADA, it is aliased here to the same interface
// provided by the hcp-scada-provider library. If the interfaces needs to be extended in the future it can be done so
// with minimal impact on the rest of the codebase.
//
//go:generate mockery --name Provider --with-expecter --inpackage
type Provider interface {
libscada.SCADAProvider
UpdateHCPConfig(cfg config.CloudConfig) error
}
const (
scadaConsulServiceKey = "consul"
)
type scadaProvider struct {
libscada.SCADAProvider
logger hclog.Logger
}
// New returns an initialized SCADA provider with a zero configuration.
// It can listen but cannot start until UpdateHCPConfig is called with
// a configuration that provides credentials to contact HCP.
func New(logger hclog.Logger) (*scadaProvider, error) {
// Create placeholder resource link
resourceLink := cloud.HashicorpCloudLocationLink{
Type: "no-op",
ID: "no-op",
Location: &cloud.HashicorpCloudLocationLocation{},
}
// Configure with an empty HCP configuration
hcpConfig, err := hcpcfg.NewHCPConfig(hcpcfg.WithoutBrowserLogin())
if err != nil {
return nil, fmt.Errorf("failed to configure SCADA provider: %w", err)
}
pvd, err := libscada.New(&libscada.Config{
Service: scadaConsulServiceKey,
HCPConfig: hcpConfig,
Resource: resourceLink,
Logger: logger,
})
if err != nil {
return nil, err
}
return &scadaProvider{pvd, logger}, nil
}
// UpdateHCPConfig updates the SCADA provider with the given HCP
// configurations.
func (p *scadaProvider) UpdateHCPConfig(cfg config.CloudConfig) error {
resource, err := cfg.Resource()
if err != nil {
return err
}
hcpCfg, err := cfg.HCPConfig()
if err != nil {
return err
}
err = p.UpdateConfig(&libscada.Config{
Service: scadaConsulServiceKey,
HCPConfig: hcpCfg,
Resource: *resource.Link(),
Logger: p.logger,
})
if err != nil {
return err
}
return nil
}
// IsCapability takes a net.Addr and returns true if it is a SCADA capability.Addr
func IsCapability(a net.Addr) bool {
_, ok := a.(*capability.Addr)
return ok
}