constellation/cli/internal/cloudcmd/clients_test.go

483 lines
15 KiB
Go
Raw Normal View History

2022-04-13 07:01:38 -04:00
package cloudcmd
import (
"context"
"errors"
"strconv"
"testing"
2022-04-13 07:01:38 -04:00
2022-06-07 10:30:41 -04:00
azurecl "github.com/edgelesssys/constellation/cli/internal/azure/client"
2022-06-07 08:52:47 -04:00
gcpcl "github.com/edgelesssys/constellation/cli/internal/gcp/client"
2022-06-07 10:27:55 -04:00
"github.com/edgelesssys/constellation/internal/azureshared"
"github.com/edgelesssys/constellation/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/internal/cloud/cloudtypes"
2022-06-07 08:52:06 -04:00
"github.com/edgelesssys/constellation/internal/gcpshared"
2022-04-13 07:01:38 -04:00
"github.com/edgelesssys/constellation/internal/state"
"go.uber.org/goleak"
2022-04-13 07:01:38 -04:00
)
func TestMain(m *testing.M) {
goleak.VerifyTestMain(m,
// https://github.com/census-instrumentation/opencensus-go/issues/1262
goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"),
)
}
2022-04-13 07:01:38 -04:00
type fakeAzureClient struct {
2022-06-07 05:45:36 -04:00
nodes cloudtypes.Instances
coordinators cloudtypes.Instances
2022-04-13 07:01:38 -04:00
resourceGroup string
name string
uid string
location string
subscriptionID string
tenantID string
subnetID string
2022-05-24 04:04:42 -04:00
loadBalancerName string
2022-04-13 07:01:38 -04:00
coordinatorsScaleSet string
nodesScaleSet string
networkSecurityGroup string
adAppObjectID string
}
func (c *fakeAzureClient) GetState() (state.ConstellationState, error) {
stat := state.ConstellationState{
CloudProvider: cloudprovider.Azure.String(),
AzureNodes: c.nodes,
AzureCoordinators: c.coordinators,
Name: c.name,
UID: c.uid,
AzureResourceGroup: c.resourceGroup,
AzureLocation: c.location,
AzureSubscription: c.subscriptionID,
AzureTenant: c.tenantID,
AzureSubnet: c.subnetID,
AzureNetworkSecurityGroup: c.networkSecurityGroup,
AzureNodesScaleSet: c.nodesScaleSet,
AzureCoordinatorsScaleSet: c.coordinatorsScaleSet,
AzureADAppObjectID: c.adAppObjectID,
}
return stat, nil
}
func (c *fakeAzureClient) SetState(stat state.ConstellationState) error {
c.nodes = stat.AzureNodes
c.coordinators = stat.AzureCoordinators
c.name = stat.Name
c.uid = stat.UID
c.resourceGroup = stat.AzureResourceGroup
c.location = stat.AzureLocation
c.subscriptionID = stat.AzureSubscription
c.tenantID = stat.AzureTenant
c.subnetID = stat.AzureSubnet
c.networkSecurityGroup = stat.AzureNetworkSecurityGroup
c.nodesScaleSet = stat.AzureNodesScaleSet
c.coordinatorsScaleSet = stat.AzureCoordinatorsScaleSet
c.adAppObjectID = stat.AzureADAppObjectID
return nil
}
func (c *fakeAzureClient) CreateApplicationInsight(ctx context.Context) error {
return nil
}
2022-04-13 07:01:38 -04:00
func (c *fakeAzureClient) CreateResourceGroup(ctx context.Context) error {
c.resourceGroup = "resource-group"
return nil
}
func (c *fakeAzureClient) CreateVirtualNetwork(ctx context.Context) error {
c.subnetID = "subnet"
return nil
}
2022-05-24 04:04:42 -04:00
func (c *fakeAzureClient) CreateExternalLoadBalancer(ctx context.Context) error {
c.loadBalancerName = "loadBalancer"
return nil
}
2022-04-13 07:01:38 -04:00
func (c *fakeAzureClient) CreateSecurityGroup(ctx context.Context, input azurecl.NetworkSecurityGroupInput) error {
c.networkSecurityGroup = "network-security-group"
return nil
}
func (c *fakeAzureClient) CreateInstances(ctx context.Context, input azurecl.CreateInstancesInput) error {
c.coordinatorsScaleSet = "coordinators-scale-set"
c.nodesScaleSet = "nodes-scale-set"
2022-06-07 05:45:36 -04:00
c.nodes = make(cloudtypes.Instances)
2022-04-13 07:01:38 -04:00
for i := 0; i < input.CountNodes; i++ {
id := "id-" + strconv.Itoa(i)
2022-06-07 05:45:36 -04:00
c.nodes[id] = cloudtypes.Instance{PublicIP: "192.0.2.1", PrivateIP: "192.0.2.1"}
2022-04-13 07:01:38 -04:00
}
2022-06-07 05:45:36 -04:00
c.coordinators = make(cloudtypes.Instances)
2022-04-13 07:01:38 -04:00
for i := 0; i < input.CountCoordinators; i++ {
id := "id-" + strconv.Itoa(i)
2022-06-07 05:45:36 -04:00
c.coordinators[id] = cloudtypes.Instance{PublicIP: "192.0.2.1", PrivateIP: "192.0.2.1"}
2022-04-13 07:01:38 -04:00
}
return nil
}
// TODO: deprecate as soon as scale sets are available.
func (c *fakeAzureClient) CreateInstancesVMs(ctx context.Context, input azurecl.CreateInstancesInput) error {
2022-06-07 05:45:36 -04:00
c.nodes = make(cloudtypes.Instances)
2022-04-13 07:01:38 -04:00
for i := 0; i < input.CountNodes; i++ {
id := "id-" + strconv.Itoa(i)
2022-06-07 05:45:36 -04:00
c.nodes[id] = cloudtypes.Instance{PublicIP: "192.0.2.1", PrivateIP: "192.0.2.1"}
2022-04-13 07:01:38 -04:00
}
2022-06-07 05:45:36 -04:00
c.coordinators = make(cloudtypes.Instances)
2022-04-13 07:01:38 -04:00
for i := 0; i < input.CountCoordinators; i++ {
id := "id-" + strconv.Itoa(i)
2022-06-07 05:45:36 -04:00
c.coordinators[id] = cloudtypes.Instance{PublicIP: "192.0.2.1", PrivateIP: "192.0.2.1"}
2022-04-13 07:01:38 -04:00
}
return nil
}
func (c *fakeAzureClient) CreateServicePrincipal(ctx context.Context) (string, error) {
c.adAppObjectID = "00000000-0000-0000-0000-000000000001"
2022-06-07 10:27:55 -04:00
return azureshared.ApplicationCredentials{
2022-04-13 07:01:38 -04:00
ClientID: "client-id",
ClientSecret: "client-secret",
2022-06-07 10:27:55 -04:00
}.ToCloudServiceAccountURI(), nil
2022-04-13 07:01:38 -04:00
}
func (c *fakeAzureClient) TerminateResourceGroup(ctx context.Context) error {
if c.resourceGroup == "" {
return nil
}
c.nodes = nil
c.coordinators = nil
c.resourceGroup = ""
c.subnetID = ""
c.networkSecurityGroup = ""
c.nodesScaleSet = ""
c.coordinatorsScaleSet = ""
return nil
}
func (c *fakeAzureClient) TerminateServicePrincipal(ctx context.Context) error {
if c.adAppObjectID == "" {
return nil
}
c.adAppObjectID = ""
return nil
}
type stubAzureClient struct {
terminateResourceGroupCalled bool
terminateServicePrincipalCalled bool
getStateErr error
setStateErr error
createApplicationInsightErr error
2022-04-13 07:01:38 -04:00
createResourceGroupErr error
createVirtualNetworkErr error
createSecurityGroupErr error
2022-05-24 04:04:42 -04:00
createLoadBalancerErr error
2022-04-13 07:01:38 -04:00
createInstancesErr error
createServicePrincipalErr error
terminateResourceGroupErr error
terminateServicePrincipalErr error
}
func (c *stubAzureClient) GetState() (state.ConstellationState, error) {
return state.ConstellationState{}, c.getStateErr
}
func (c *stubAzureClient) SetState(state.ConstellationState) error {
return c.setStateErr
}
2022-05-24 04:04:42 -04:00
func (c *stubAzureClient) CreateExternalLoadBalancer(ctx context.Context) error {
return c.createLoadBalancerErr
}
func (c *stubAzureClient) CreateApplicationInsight(ctx context.Context) error {
return c.createApplicationInsightErr
}
2022-04-13 07:01:38 -04:00
func (c *stubAzureClient) CreateResourceGroup(ctx context.Context) error {
return c.createResourceGroupErr
}
func (c *stubAzureClient) CreateVirtualNetwork(ctx context.Context) error {
return c.createVirtualNetworkErr
}
func (c *stubAzureClient) CreateSecurityGroup(ctx context.Context, input azurecl.NetworkSecurityGroupInput) error {
return c.createSecurityGroupErr
}
func (c *stubAzureClient) CreateInstances(ctx context.Context, input azurecl.CreateInstancesInput) error {
return c.createInstancesErr
}
// TODO: deprecate as soon as scale sets are available.
func (c *stubAzureClient) CreateInstancesVMs(ctx context.Context, input azurecl.CreateInstancesInput) error {
return c.createInstancesErr
}
func (c *stubAzureClient) CreateServicePrincipal(ctx context.Context) (string, error) {
2022-06-07 10:27:55 -04:00
return azureshared.ApplicationCredentials{
2022-04-13 07:01:38 -04:00
ClientID: "00000000-0000-0000-0000-000000000000",
ClientSecret: "secret",
2022-06-07 10:27:55 -04:00
}.ToCloudServiceAccountURI(), c.createServicePrincipalErr
2022-04-13 07:01:38 -04:00
}
func (c *stubAzureClient) TerminateResourceGroup(ctx context.Context) error {
c.terminateResourceGroupCalled = true
return c.terminateResourceGroupErr
}
func (c *stubAzureClient) TerminateServicePrincipal(ctx context.Context) error {
c.terminateServicePrincipalCalled = true
return c.terminateServicePrincipalErr
}
type fakeGcpClient struct {
2022-06-07 05:35:08 -04:00
nodes cloudtypes.Instances
coordinators cloudtypes.Instances
2022-04-13 07:01:38 -04:00
nodesInstanceGroup string
coordinatorInstanceGroup string
coordinatorTemplate string
nodeTemplate string
network string
subnetwork string
firewalls []string
project string
uid string
name string
zone string
serviceAccount string
2022-06-09 16:26:36 -04:00
// loadbalancer
healthCheck string
backendService string
forwardingRule string
2022-04-13 07:01:38 -04:00
}
func (c *fakeGcpClient) GetState() (state.ConstellationState, error) {
stat := state.ConstellationState{
CloudProvider: cloudprovider.GCP.String(),
GCPNodes: c.nodes,
GCPCoordinators: c.coordinators,
GCPNodeInstanceGroup: c.nodesInstanceGroup,
GCPCoordinatorInstanceGroup: c.coordinatorInstanceGroup,
GCPNodeInstanceTemplate: c.nodeTemplate,
GCPCoordinatorInstanceTemplate: c.coordinatorTemplate,
GCPNetwork: c.network,
GCPSubnetwork: c.subnetwork,
GCPFirewalls: c.firewalls,
2022-06-09 16:26:36 -04:00
GCPBackendService: c.backendService,
GCPHealthCheck: c.healthCheck,
GCPForwardingRule: c.forwardingRule,
2022-04-13 07:01:38 -04:00
GCPProject: c.project,
Name: c.name,
UID: c.uid,
GCPZone: c.zone,
GCPServiceAccount: c.serviceAccount,
}
return stat, nil
}
func (c *fakeGcpClient) SetState(stat state.ConstellationState) error {
c.nodes = stat.GCPNodes
c.coordinators = stat.GCPCoordinators
c.nodesInstanceGroup = stat.GCPNodeInstanceGroup
c.coordinatorInstanceGroup = stat.GCPCoordinatorInstanceGroup
c.nodeTemplate = stat.GCPNodeInstanceTemplate
c.coordinatorTemplate = stat.GCPCoordinatorInstanceTemplate
c.network = stat.GCPNetwork
c.subnetwork = stat.GCPSubnetwork
c.firewalls = stat.GCPFirewalls
c.project = stat.GCPProject
c.name = stat.Name
c.uid = stat.UID
c.zone = stat.GCPZone
c.serviceAccount = stat.GCPServiceAccount
2022-06-09 16:26:36 -04:00
c.healthCheck = stat.GCPHealthCheck
c.backendService = stat.GCPBackendService
c.forwardingRule = stat.GCPForwardingRule
2022-04-13 07:01:38 -04:00
return nil
}
func (c *fakeGcpClient) CreateVPCs(ctx context.Context) error {
2022-04-13 07:01:38 -04:00
c.network = "network"
c.subnetwork = "subnetwork"
return nil
}
func (c *fakeGcpClient) CreateFirewall(ctx context.Context, input gcpcl.FirewallInput) error {
if c.network == "" {
return errors.New("client has not network")
}
for _, rule := range input.Ingress {
2022-05-24 04:04:42 -04:00
c.firewalls = append(c.firewalls, rule.Name)
2022-04-13 07:01:38 -04:00
}
return nil
}
func (c *fakeGcpClient) CreateInstances(ctx context.Context, input gcpcl.CreateInstancesInput) error {
c.coordinatorInstanceGroup = "coordinator-group"
c.nodesInstanceGroup = "nodes-group"
c.nodeTemplate = "node-template"
c.coordinatorTemplate = "coordinator-template"
2022-06-07 05:35:08 -04:00
c.nodes = make(cloudtypes.Instances)
2022-04-13 07:01:38 -04:00
for i := 0; i < input.CountNodes; i++ {
id := "id-" + strconv.Itoa(i)
2022-06-07 05:35:08 -04:00
c.nodes[id] = cloudtypes.Instance{PublicIP: "192.0.2.1", PrivateIP: "192.0.2.1"}
2022-04-13 07:01:38 -04:00
}
2022-06-07 05:35:08 -04:00
c.coordinators = make(cloudtypes.Instances)
2022-04-13 07:01:38 -04:00
for i := 0; i < input.CountCoordinators; i++ {
id := "id-" + strconv.Itoa(i)
2022-06-07 05:35:08 -04:00
c.coordinators[id] = cloudtypes.Instance{PublicIP: "192.0.2.1", PrivateIP: "192.0.2.1"}
2022-04-13 07:01:38 -04:00
}
return nil
}
func (c *fakeGcpClient) CreateServiceAccount(ctx context.Context, input gcpcl.ServiceAccountInput) (string, error) {
c.serviceAccount = "service-account@" + c.project + ".iam.gserviceaccount.com"
2022-06-07 08:52:06 -04:00
return gcpshared.ServiceAccountKey{
2022-04-13 07:01:38 -04:00
Type: "service_account",
ProjectID: c.project,
PrivateKeyID: "key-id",
PrivateKey: "-----BEGIN PRIVATE KEY-----\nprivate-key\n-----END PRIVATE KEY-----\n",
ClientEmail: c.serviceAccount,
ClientID: "client-id",
AuthURI: "https://accounts.google.com/o/oauth2/auth",
TokenURI: "https://accounts.google.com/o/oauth2/token",
AuthProviderX509CertURL: "https://www.googleapis.com/oauth2/v1/certs",
ClientX509CertURL: "https://www.googleapis.com/robot/v1/metadata/x509/service-account-email",
2022-06-07 08:52:06 -04:00
}.ToCloudServiceAccountURI(), nil
2022-04-13 07:01:38 -04:00
}
2022-06-09 16:26:36 -04:00
func (c *fakeGcpClient) CreateLoadBalancer(ctx context.Context) error {
c.healthCheck = "health-check"
c.backendService = "backend-service"
c.forwardingRule = "forwarding-rule"
return nil
}
2022-04-13 07:01:38 -04:00
func (c *fakeGcpClient) TerminateFirewall(ctx context.Context) error {
if len(c.firewalls) == 0 {
return nil
}
c.firewalls = nil
return nil
}
func (c *fakeGcpClient) TerminateVPCs(context.Context) error {
if len(c.firewalls) != 0 {
return errors.New("client has firewalls, which must be deleted first")
}
c.network = ""
c.subnetwork = ""
return nil
}
func (c *fakeGcpClient) TerminateInstances(context.Context) error {
c.nodeTemplate = ""
c.coordinatorTemplate = ""
c.nodesInstanceGroup = ""
c.coordinatorInstanceGroup = ""
c.nodes = nil
c.coordinators = nil
return nil
}
func (c *fakeGcpClient) TerminateServiceAccount(context.Context) error {
c.serviceAccount = ""
return nil
}
2022-06-09 16:26:36 -04:00
func (c *fakeGcpClient) TerminateLoadBalancer(context.Context) error {
c.healthCheck = ""
c.backendService = ""
c.forwardingRule = ""
return nil
}
2022-04-13 07:01:38 -04:00
func (c *fakeGcpClient) Close() error {
return nil
}
type stubGcpClient struct {
terminateFirewallCalled bool
terminateInstancesCalled bool
terminateVPCsCalled bool
terminateServiceAccountCalled bool
closeCalled bool
getStateErr error
setStateErr error
createVPCsErr error
createFirewallErr error
createInstancesErr error
createServiceAccountErr error
2022-06-09 16:26:36 -04:00
createLoadBalancerErr error
2022-04-13 07:01:38 -04:00
terminateFirewallErr error
terminateVPCsErr error
terminateInstancesErr error
terminateServiceAccountErr error
2022-06-09 16:26:36 -04:00
terminateLoadBalancerErr error
2022-04-13 07:01:38 -04:00
closeErr error
}
func (c *stubGcpClient) GetState() (state.ConstellationState, error) {
return state.ConstellationState{}, c.getStateErr
}
func (c *stubGcpClient) SetState(state.ConstellationState) error {
return c.setStateErr
}
func (c *stubGcpClient) CreateVPCs(ctx context.Context) error {
2022-04-13 07:01:38 -04:00
return c.createVPCsErr
}
func (c *stubGcpClient) CreateFirewall(ctx context.Context, input gcpcl.FirewallInput) error {
return c.createFirewallErr
}
func (c *stubGcpClient) CreateInstances(ctx context.Context, input gcpcl.CreateInstancesInput) error {
return c.createInstancesErr
}
func (c *stubGcpClient) CreateServiceAccount(ctx context.Context, input gcpcl.ServiceAccountInput) (string, error) {
2022-06-07 08:52:06 -04:00
return gcpshared.ServiceAccountKey{}.ToCloudServiceAccountURI(), c.createServiceAccountErr
2022-04-13 07:01:38 -04:00
}
2022-06-09 16:26:36 -04:00
func (c *stubGcpClient) CreateLoadBalancer(ctx context.Context) error {
return c.createLoadBalancerErr
}
2022-04-13 07:01:38 -04:00
func (c *stubGcpClient) TerminateFirewall(ctx context.Context) error {
c.terminateFirewallCalled = true
return c.terminateFirewallErr
}
func (c *stubGcpClient) TerminateVPCs(context.Context) error {
c.terminateVPCsCalled = true
return c.terminateVPCsErr
}
func (c *stubGcpClient) TerminateInstances(context.Context) error {
c.terminateInstancesCalled = true
return c.terminateInstancesErr
}
func (c *stubGcpClient) TerminateServiceAccount(context.Context) error {
c.terminateServiceAccountCalled = true
return c.terminateServiceAccountErr
}
2022-06-09 16:26:36 -04:00
func (c *stubGcpClient) TerminateLoadBalancer(context.Context) error {
return c.terminateLoadBalancerErr
}
2022-04-13 07:01:38 -04:00
func (c *stubGcpClient) Close() error {
c.closeCalled = true
return c.closeErr
}