diff --git a/cmd/clm/main.go b/cmd/clm/main.go index 9e6ebfdb..4e3a5d70 100644 --- a/cmd/clm/main.go +++ b/cmd/clm/main.go @@ -135,12 +135,12 @@ func main() { secretDecrypter, cfg.AssumedRole, awsConfig, + clusterRegistry, &provisioner.Options{ DryRun: cfg.DryRun, ApplyOnly: cfg.ApplyOnly, UpdateStrategy: cfg.UpdateStrategy, RemoveVolumes: cfg.RemoveVolumes, - Hook: provisioner.NewZalandoEKSCreationHook(clusterRegistry), }, ), } diff --git a/provisioner/clusterpy.go b/provisioner/clusterpy.go index 8bca9506..5b3a9a99 100644 --- a/provisioner/clusterpy.go +++ b/provisioner/clusterpy.go @@ -3,6 +3,7 @@ package provisioner import ( "bytes" "context" + "encoding/base64" "fmt" "io" "net/http" @@ -25,6 +26,7 @@ import ( "github.com/zalando-incubator/cluster-lifecycle-manager/pkg/kubernetes" "github.com/zalando-incubator/cluster-lifecycle-manager/pkg/updatestrategy" "github.com/zalando-incubator/cluster-lifecycle-manager/pkg/util/command" + "github.com/zalando-incubator/cluster-lifecycle-manager/registry" "github.com/zalando-incubator/kube-ingress-aws-controller/certs" "golang.org/x/oauth2" "gopkg.in/yaml.v2" @@ -71,7 +73,7 @@ type clusterpyProvisioner struct { tokenSource oauth2.TokenSource applyOnly bool updateStrategy config.UpdateStrategy - hook CreationHook + clusterRegistry registry.Registry removeVolumes bool manageEtcdStack bool manageMasterNodes bool @@ -298,17 +300,62 @@ func (p *clusterpyProvisioner) provision( return err } - var postOptions *HookResponse - if p.hook != nil { - postOptions, err = p.hook.Execute( - awsAdapter, - cluster, - outputs, + postOptions := &HookResponse{} + + if cluster.Provider == string(ZalandoEKSProvider) { + clusterDetails, err := awsAdapter.GetEKSClusterDetails(cluster) + if err != nil { + return err + } + decodedCA, err := base64.StdEncoding.DecodeString( + clusterDetails.CertificateAuthority, ) if err != nil { return err } + if cluster.ConfigItems == nil { + cluster.ConfigItems = map[string]string{} + } + + toUpdate := map[string]string{} + if cluster.ConfigItems[KeyEKSEndpoint] != clusterDetails.Endpoint { + toUpdate[KeyEKSEndpoint] = clusterDetails.Endpoint + } + if cluster.ConfigItems[KeyEKSCAData] != clusterDetails.CertificateAuthority { + toUpdate[KeyEKSCAData] = clusterDetails.CertificateAuthority + } + if cluster.ConfigItems[KeyEKSOIDCIssuerURL] != clusterDetails.OIDCIssuerURL { + toUpdate[KeyEKSOIDCIssuerURL] = clusterDetails.OIDCIssuerURL + } + + err = p.clusterRegistry.UpdateConfigItems(cluster, toUpdate) + if err != nil { + return err + } + + postOptions.APIServerURL = clusterDetails.Endpoint + postOptions.CAData = decodedCA + + subnets := map[string]string{} + for key, az := range map[string]string{ + "EKSSubneta": "eu-central-1a", + "EKSSubnetb": "eu-central-1b", + "EKSSubnetc": "eu-central-1c", + } { + if v, ok := outputs[key]; ok { + subnets[az] = v + } + } + if len(subnets) > 0 { + postOptions.AZInfo = &AZInfo{ + subnets: subnets, + } + postOptions.TemplateValues = map[string]interface{}{ + subnetsValueKey: subnets, + } + } + if postOptions.APIServerURL != "" { cluster.APIServerURL = postOptions.APIServerURL } diff --git a/provisioner/provisioner.go b/provisioner/provisioner.go index 6d0c2b2a..a7443919 100644 --- a/provisioner/provisioner.go +++ b/provisioner/provisioner.go @@ -33,26 +33,6 @@ type ( ) error } - // CreationHook is an interface that provisioners can use while provisioning - // a cluster. - // - // This is useful for example to pass additional configuration only known at - // a later stage of provisioning. For example, when provisioning an EKS - // cluster, the provisioner only knows what is the API Server URL after - // applying the initial CloudFormation. - CreationHook interface { - // Execute performs updates used by a provisioner during cluster - // creation. - Execute( - adapter awsInterface, - cluster *api.Cluster, - cloudFormationOutput map[string]string, - ) ( - *HookResponse, - error, - ) - } - // HookResponse contain configuration parameters that a provisioner can use // at a later stage. HookResponse struct { @@ -69,7 +49,6 @@ type ( UpdateStrategy config.UpdateStrategy RemoveVolumes bool ManageEtcdStack bool - Hook CreationHook } ) diff --git a/provisioner/zalando_eks.go b/provisioner/zalando_eks.go index da6df613..9deebe1d 100644 --- a/provisioner/zalando_eks.go +++ b/provisioner/zalando_eks.go @@ -39,6 +39,7 @@ func NewZalandoEKSProvisioner( secretDecrypter decrypter.Decrypter, assumedRole string, awsConfig *aws.Config, + clusterRegistry registry.Registry, options *Options, ) Provisioner { provisioner := &ZalandoEKSProvisioner{ @@ -49,6 +50,7 @@ func NewZalandoEKSProvisioner( secretDecrypter: secretDecrypter, manageMasterNodes: false, manageEtcdStack: false, + clusterRegistry: clusterRegistry, }, } @@ -57,7 +59,6 @@ func NewZalandoEKSProvisioner( provisioner.applyOnly = options.ApplyOnly provisioner.updateStrategy = options.UpdateStrategy provisioner.removeVolumes = options.RemoveVolumes - provisioner.hook = options.Hook } return provisioner @@ -138,82 +139,3 @@ func (z *ZalandoEKSProvisioner) Decommission( caData, ) } - -// NewZalandoEKSCreationHook returns a new hook for EKS cluster provisioning, -// configured to use the given cluster registry. -func NewZalandoEKSCreationHook( - clusterRegistry registry.Registry, -) CreationHook { - return &ZalandoEKSCreationHook{ - clusterRegistry: clusterRegistry, - } -} - -// Execute updates the configuration only known after deploying the first -// CloudFormation stack. -// -// The method returns the API server URL, the Certificate Authority data, -// and the subnets. Additionally Execute updates the configured cluster -// registry with the EKS API Server URL and the Certificate Authority data. -func (z *ZalandoEKSCreationHook) Execute( - adapter awsInterface, - cluster *api.Cluster, - cloudFormationOutput map[string]string, -) (*HookResponse, error) { - res := &HookResponse{} - - clusterDetails, err := adapter.GetEKSClusterDetails(cluster) - if err != nil { - return nil, err - } - decodedCA, err := base64.StdEncoding.DecodeString( - clusterDetails.CertificateAuthority, - ) - if err != nil { - return nil, err - } - - if cluster.ConfigItems == nil { - cluster.ConfigItems = map[string]string{} - } - - toUpdate := map[string]string{} - if cluster.ConfigItems[KeyEKSEndpoint] != clusterDetails.Endpoint { - toUpdate[KeyEKSEndpoint] = clusterDetails.Endpoint - } - if cluster.ConfigItems[KeyEKSCAData] != clusterDetails.CertificateAuthority { - toUpdate[KeyEKSCAData] = clusterDetails.CertificateAuthority - } - if cluster.ConfigItems[KeyEKSOIDCIssuerURL] != clusterDetails.OIDCIssuerURL { - toUpdate[KeyEKSOIDCIssuerURL] = clusterDetails.OIDCIssuerURL - } - - err = z.clusterRegistry.UpdateConfigItems(cluster, toUpdate) - if err != nil { - return nil, err - } - - res.APIServerURL = clusterDetails.Endpoint - res.CAData = decodedCA - - subnets := map[string]string{} - for key, az := range map[string]string{ - "EKSSubneta": "eu-central-1a", - "EKSSubnetb": "eu-central-1b", - "EKSSubnetc": "eu-central-1c", - } { - if v, ok := cloudFormationOutput[key]; ok { - subnets[az] = v - } - } - if len(subnets) > 0 { - res.AZInfo = &AZInfo{ - subnets: subnets, - } - res.TemplateValues = map[string]interface{}{ - subnetsValueKey: subnets, - } - } - - return res, nil -} diff --git a/provisioner/zalando_eks_test.go b/provisioner/zalando_eks_test.go index 3245aabd..ab32314e 100644 --- a/provisioner/zalando_eks_test.go +++ b/provisioner/zalando_eks_test.go @@ -1,9 +1,6 @@ package provisioner import ( - "testing" - - "github.com/stretchr/testify/require" "github.com/zalando-incubator/cluster-lifecycle-manager/api" "github.com/zalando-incubator/cluster-lifecycle-manager/registry" ) @@ -38,53 +35,3 @@ func (r *mockRegistry) UpdateLifecycleStatus(_ *api.Cluster) error { func (r *mockRegistry) UpdateConfigItems(_ *api.Cluster, _ map[string]string) error { return nil } - -func TestCreationHookExecute(t *testing.T) { - for _, tc := range []struct { - cfOutput map[string]string - expected *HookResponse - }{ - { - cfOutput: map[string]string{ - "EKSSubneta": "subnet-123", - "EKSSubnetb": "subnet-456", - "EKSSubnetc": "subnet-789", - }, - expected: &HookResponse{ - APIServerURL: "https://api.cluster.local", - CAData: []byte("blah"), - AZInfo: &AZInfo{ - subnets: map[string]string{ - "eu-central-1a": "subnet-123", - "eu-central-1b": "subnet-456", - "eu-central-1c": "subnet-789", - }, - }, - TemplateValues: map[string]interface{}{ - subnetsValueKey: map[string]string{ - "eu-central-1a": "subnet-123", - "eu-central-1b": "subnet-456", - "eu-central-1c": "subnet-789", - }, - }, - }, - }, - { - cfOutput: map[string]string{}, - expected: &HookResponse{ - APIServerURL: "https://api.cluster.local", - CAData: []byte("blah"), - }, - }, - } { - z := NewZalandoEKSCreationHook(&mockRegistry{}) - res, err := z.Execute( - &mockAWSAdapter{}, - &api.Cluster{}, - tc.cfOutput, - ) - - require.NoError(t, err) - require.Equal(t, tc.expected, res) - } -}