diff --git a/bootstrapper/cmd/bootstrapper/main.go b/bootstrapper/cmd/bootstrapper/main.go index 3d15fb4ba..fbcf7c513 100644 --- a/bootstrapper/cmd/bootstrapper/main.go +++ b/bootstrapper/cmd/bootstrapper/main.go @@ -98,8 +98,12 @@ func main() { if err != nil { log.With(zap.Error(err)).Fatalf("Failed to marshal PCRs") } + cloudControllerManager, err := gcpcloud.NewCloudControllerManager(metadata) + if err != nil { + log.With(zap.Error(err)).Fatalf("Failed to create cloud controller manager") + } clusterInitJoiner = kubernetes.New( - "gcp", k8sapi.NewKubernetesUtil(), &k8sapi.CoreOSConfiguration{}, kubectl.New(), &gcpcloud.CloudControllerManager{}, + "gcp", k8sapi.NewKubernetesUtil(), &k8sapi.CoreOSConfiguration{}, kubectl.New(), cloudControllerManager, &gcpcloud.CloudNodeManager{}, &gcpcloud.Autoscaler{}, metadata, pcrsJSON, ) openTPM = vtpm.OpenVTPM diff --git a/bootstrapper/internal/kubernetes/cloud_provider.go b/bootstrapper/internal/kubernetes/cloud_provider.go index 48261241c..d2686b3a9 100644 --- a/bootstrapper/internal/kubernetes/cloud_provider.go +++ b/bootstrapper/internal/kubernetes/cloud_provider.go @@ -47,7 +47,7 @@ type CloudControllerManager interface { ExtraArgs() []string // ConfigMaps returns a list of ConfigMaps to deploy together with the k8s cloud-controller-manager // Reference: https://kubernetes.io/docs/concepts/configuration/configmap/ . - ConfigMaps(instance metadata.InstanceMetadata) (kubernetes.ConfigMaps, error) + ConfigMaps() (kubernetes.ConfigMaps, error) // Secrets returns a list of secrets to deploy together with the k8s cloud-controller-manager. // Reference: https://kubernetes.io/docs/concepts/configuration/secret/ . Secrets(ctx context.Context, providerID, cloudServiceAccountURI string) (kubernetes.Secrets, error) @@ -165,7 +165,7 @@ func (m *stubCloudControllerManager) ExtraArgs() []string { return []string{} } -func (m *stubCloudControllerManager) ConfigMaps(instance metadata.InstanceMetadata) (kubernetes.ConfigMaps, error) { +func (m *stubCloudControllerManager) ConfigMaps() (kubernetes.ConfigMaps, error) { return []*k8s.ConfigMap{}, nil } diff --git a/bootstrapper/internal/kubernetes/kubernetes.go b/bootstrapper/internal/kubernetes/kubernetes.go index 1026e2f05..8e1acb074 100644 --- a/bootstrapper/internal/kubernetes/kubernetes.go +++ b/bootstrapper/internal/kubernetes/kubernetes.go @@ -339,7 +339,7 @@ func (k *KubeWrapper) setupCCM(ctx context.Context, subnetworkPodCIDR, cloudServ if !k.cloudControllerManager.Supported() { return nil } - ccmConfigMaps, err := k.cloudControllerManager.ConfigMaps(instance) + ccmConfigMaps, err := k.cloudControllerManager.ConfigMaps() if err != nil { return fmt.Errorf("defining ConfigMaps for CCM: %w", err) } diff --git a/internal/cloud/azure/ccm.go b/internal/cloud/azure/ccm.go index 874f7f7db..4d99f7598 100644 --- a/internal/cloud/azure/ccm.go +++ b/internal/cloud/azure/ccm.go @@ -11,7 +11,6 @@ import ( "encoding/json" "github.com/edgelesssys/constellation/v2/internal/azureshared" - "github.com/edgelesssys/constellation/v2/internal/cloud/metadata" "github.com/edgelesssys/constellation/v2/internal/kubernetes" "github.com/edgelesssys/constellation/v2/internal/versions" k8s "k8s.io/api/core/v1" @@ -61,7 +60,7 @@ func (c *CloudControllerManager) ExtraArgs() []string { // ConfigMaps returns a list of ConfigMaps to deploy together with the k8s cloud-controller-manager // Reference: https://kubernetes.io/docs/concepts/configuration/configmap/ . -func (c *CloudControllerManager) ConfigMaps(instance metadata.InstanceMetadata) (kubernetes.ConfigMaps, error) { +func (c *CloudControllerManager) ConfigMaps() (kubernetes.ConfigMaps, error) { return kubernetes.ConfigMaps{}, nil } diff --git a/internal/cloud/azure/ccm_test.go b/internal/cloud/azure/ccm_test.go index 8f14d4e67..0e27122df 100644 --- a/internal/cloud/azure/ccm_test.go +++ b/internal/cloud/azure/ccm_test.go @@ -11,7 +11,6 @@ import ( "errors" "testing" - "github.com/edgelesssys/constellation/v2/internal/cloud/metadata" "github.com/edgelesssys/constellation/v2/internal/kubernetes" "github.com/edgelesssys/constellation/v2/internal/versions" "github.com/stretchr/testify/assert" @@ -99,7 +98,7 @@ func TestTrivialCCMFunctions(t *testing.T) { assert.NotEmpty(cloud.Path()) assert.NotEmpty(cloud.Name()) assert.NotEmpty(cloud.ExtraArgs()) - assert.Empty(cloud.ConfigMaps(metadata.InstanceMetadata{})) + assert.Empty(cloud.ConfigMaps()) assert.NotEmpty(cloud.Volumes()) assert.NotEmpty(cloud.VolumeMounts()) assert.Empty(cloud.Env()) diff --git a/internal/cloud/gcp/ccm.go b/internal/cloud/gcp/ccm.go index 6229f0992..b3d43d9b6 100644 --- a/internal/cloud/gcp/ccm.go +++ b/internal/cloud/gcp/ccm.go @@ -12,7 +12,6 @@ import ( "fmt" "strings" - "github.com/edgelesssys/constellation/v2/internal/cloud/metadata" "github.com/edgelesssys/constellation/v2/internal/gcpshared" "github.com/edgelesssys/constellation/v2/internal/kubernetes" "github.com/edgelesssys/constellation/v2/internal/versions" @@ -21,7 +20,27 @@ import ( ) // CloudControllerManager holds the gcp cloud-controller-manager configuration. -type CloudControllerManager struct{} +type CloudControllerManager struct { + uid string + projectID string +} + +// NewCloudControllerManager returns an initialized cloud controller manager configuration struct for GCP. +func NewCloudControllerManager(metadata *Metadata) (*CloudControllerManager, error) { + uid, err := metadata.api.UID() + if err != nil { + return nil, fmt.Errorf("getting uid from metadata: %w", err) + } + projectID, err := metadata.api.RetrieveProjectID() + if err != nil { + return nil, fmt.Errorf("getting project id from metadata: %w", err) + } + + return &CloudControllerManager{ + uid: uid, + projectID: projectID, + }, nil +} // Image returns the container image used to provide cloud-controller-manager for the cloud-provider. func (c *CloudControllerManager) Image(k8sVersion versions.ValidK8sVersion) (string, error) { @@ -52,20 +71,14 @@ func (c *CloudControllerManager) ExtraArgs() []string { // ConfigMaps returns a list of ConfigMaps to deploy together with the k8s cloud-controller-manager // Reference: https://kubernetes.io/docs/concepts/configuration/configmap/ . -func (c *CloudControllerManager) ConfigMaps(instance metadata.InstanceMetadata) (kubernetes.ConfigMaps, error) { +func (c *CloudControllerManager) ConfigMaps() (kubernetes.ConfigMaps, error) { // GCP CCM expects cloud config to contain the GCP project-id and other configuration. // reference: https://github.com/kubernetes/cloud-provider-gcp/blob/master/cluster/gce/gci/configure-helper.sh#L791-L892 var config strings.Builder config.WriteString("[global]\n") - projectID, _, _, err := gcpshared.SplitProviderID(instance.ProviderID) - if err != nil { - return kubernetes.ConfigMaps{}, err - } - config.WriteString(fmt.Sprintf("project-id = %s\n", projectID)) + config.WriteString(fmt.Sprintf("project-id = %s\n", c.projectID)) config.WriteString("use-metadata-server = true\n") - - nameParts := strings.Split(instance.Name, "-") - config.WriteString("node-tags = constellation-" + nameParts[len(nameParts)-2] + "\n") + config.WriteString(fmt.Sprintf("node-tags = constellation-%s\n", c.uid)) return kubernetes.ConfigMaps{ &k8s.ConfigMap{ @@ -86,7 +99,7 @@ func (c *CloudControllerManager) ConfigMaps(instance metadata.InstanceMetadata) // Secrets returns a list of secrets to deploy together with the k8s cloud-controller-manager. // Reference: https://kubernetes.io/docs/concepts/configuration/secret/ . -func (c *CloudControllerManager) Secrets(ctx context.Context, _ string, cloudServiceAccountURI string) (kubernetes.Secrets, error) { +func (c *CloudControllerManager) Secrets(_ context.Context, _ string, cloudServiceAccountURI string) (kubernetes.Secrets, error) { serviceAccountKey, err := gcpshared.ServiceAccountKeyFromURI(cloudServiceAccountURI) if err != nil { return kubernetes.Secrets{}, err diff --git a/internal/cloud/gcp/ccm_test.go b/internal/cloud/gcp/ccm_test.go index 3d2b3e4ff..7fbb1a1a5 100644 --- a/internal/cloud/gcp/ccm_test.go +++ b/internal/cloud/gcp/ccm_test.go @@ -28,7 +28,6 @@ func TestConfigMaps(t *testing.T) { wantErr bool }{ "ConfigMaps works": { - instance: metadata.InstanceMetadata{ProviderID: "gce://project-id/zone/instanceName-UID-0", Name: "instanceName-UID-0"}, wantConfigMaps: kubernetes.ConfigMaps{ &k8s.ConfigMap{ TypeMeta: v1.TypeMeta{ @@ -49,10 +48,6 @@ node-tags = constellation-UID }, }, }, - "invalid providerID fails": { - instance: metadata.InstanceMetadata{ProviderID: "invalid"}, - wantErr: true, - }, } for name, tc := range testCases { @@ -60,8 +55,11 @@ node-tags = constellation-UID assert := assert.New(t) require := require.New(t) - cloud := CloudControllerManager{} - configMaps, err := cloud.ConfigMaps(tc.instance) + cloud := CloudControllerManager{ + projectID: "project-id", + uid: "UID", + } + configMaps, err := cloud.ConfigMaps() if tc.wantErr { assert.Error(err) diff --git a/internal/cloud/qemu/ccm.go b/internal/cloud/qemu/ccm.go index a975e73d6..6763a674d 100644 --- a/internal/cloud/qemu/ccm.go +++ b/internal/cloud/qemu/ccm.go @@ -40,7 +40,7 @@ func (c CloudControllerManager) ExtraArgs() []string { // ConfigMaps returns a list of ConfigMaps to deploy together with the k8s cloud-controller-manager // Reference: https://kubernetes.io/docs/concepts/configuration/configmap/ . -func (c CloudControllerManager) ConfigMaps(instance metadata.InstanceMetadata) (kubernetes.ConfigMaps, error) { +func (c CloudControllerManager) ConfigMaps() (kubernetes.ConfigMaps, error) { return kubernetes.ConfigMaps{}, nil } diff --git a/operators/constellation-node-operator/internal/gcp/client/instancegroupmanagers.go b/operators/constellation-node-operator/internal/gcp/client/instancegroupmanagers.go index 4eca3a45d..fa81bd58c 100644 --- a/operators/constellation-node-operator/internal/gcp/client/instancegroupmanagers.go +++ b/operators/constellation-node-operator/internal/gcp/client/instancegroupmanagers.go @@ -10,13 +10,10 @@ import ( "context" "fmt" "regexp" + "strings" ) -var ( - instanceGroupIDRegex = regexp.MustCompile(`^projects/([^/]+)/zones/([^/]+)/instanceGroupManagers/([^/]+)$`) - controlPlaneInstanceGroupNameRegex = regexp.MustCompile(`^(.*)control-plane(.*)$`) - workerInstanceGroupNameRegex = regexp.MustCompile(`^(.*)worker(.*)$`) -) +var instanceGroupIDRegex = regexp.MustCompile(`^projects/([^/]+)/zones/([^/]+)/instanceGroupManagers/([^/]+)$`) func (c *Client) canonicalInstanceGroupID(ctx context.Context, instanceGroupID string) (string, error) { project, zone, instanceGroup, err := splitInstanceGroupID(uriNormalize(instanceGroupID)) @@ -41,12 +38,12 @@ func splitInstanceGroupID(instanceGroupID string) (project, zone, instanceGroup // isControlPlaneInstanceGroup returns true if the instance group is a control plane instance group. func isControlPlaneInstanceGroup(instanceGroupName string) bool { - return controlPlaneInstanceGroupNameRegex.MatchString(instanceGroupName) + return strings.Contains(instanceGroupName, "control-plane") } // isWorkerInstanceGroup returns true if the instance group is a worker instance group. func isWorkerInstanceGroup(instanceGroupName string) bool { - return workerInstanceGroupNameRegex.MatchString(instanceGroupName) + return strings.Contains(instanceGroupName, "worker") } // generateInstanceName generates a random instance name.