Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove the hook in favour of inline processing #813

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/clm/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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),
},
),
}
Expand Down
61 changes: 54 additions & 7 deletions provisioner/clusterpy.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package provisioner
import (
"bytes"
"context"
"encoding/base64"
"fmt"
"io"
"net/http"
Expand All @@ -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"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
}
Expand Down
21 changes: 0 additions & 21 deletions provisioner/provisioner.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -69,7 +49,6 @@ type (
UpdateStrategy config.UpdateStrategy
RemoveVolumes bool
ManageEtcdStack bool
Hook CreationHook
}
)

Expand Down
82 changes: 2 additions & 80 deletions provisioner/zalando_eks.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ func NewZalandoEKSProvisioner(
secretDecrypter decrypter.Decrypter,
assumedRole string,
awsConfig *aws.Config,
clusterRegistry registry.Registry,
options *Options,
) Provisioner {
provisioner := &ZalandoEKSProvisioner{
Expand All @@ -49,6 +50,7 @@ func NewZalandoEKSProvisioner(
secretDecrypter: secretDecrypter,
manageMasterNodes: false,
manageEtcdStack: false,
clusterRegistry: clusterRegistry,
},
}

Expand All @@ -57,7 +59,6 @@ func NewZalandoEKSProvisioner(
provisioner.applyOnly = options.ApplyOnly
provisioner.updateStrategy = options.UpdateStrategy
provisioner.removeVolumes = options.RemoveVolumes
provisioner.hook = options.Hook
}

return provisioner
Expand Down Expand Up @@ -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
}
53 changes: 0 additions & 53 deletions provisioner/zalando_eks_test.go
Original file line number Diff line number Diff line change
@@ -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"
)
Expand Down Expand Up @@ -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)
}
}
Loading