diff --git a/cluster/cloud-provider.go b/cluster/cloud-provider.go index fc8b75ec..70cbad79 100644 --- a/cluster/cloud-provider.go +++ b/cluster/cloud-provider.go @@ -2,9 +2,7 @@ package cluster import ( "context" - "encoding/json" "fmt" - "strconv" "github.com/docker/docker/api/types/container" "github.com/rancher/rke/docker" @@ -21,11 +19,7 @@ const ( CloudConfigEnv = "RKE_CLOUD_CONFIG" ) -func deployCloudProviderConfig(ctx context.Context, uniqueHosts []*hosts.Host, cloudProvider v3.CloudProvider, alpineImage string, prsMap map[string]v3.PrivateRegistry) error { - cloudConfig, err := getCloudConfigFile(ctx, cloudProvider) - if err != nil { - return err - } +func deployCloudProviderConfig(ctx context.Context, uniqueHosts []*hosts.Host, alpineImage string, prsMap map[string]v3.PrivateRegistry, cloudConfig string) error { for _, host := range uniqueHosts { log.Infof(ctx, "[%s] Deploying cloud config file to node [%s]", CloudConfigServiceName, host.Address) if err := doDeployConfigFile(ctx, host, cloudConfig, alpineImage, prsMap); err != nil { @@ -35,36 +29,6 @@ func deployCloudProviderConfig(ctx context.Context, uniqueHosts []*hosts.Host, c return nil } -func getCloudConfigFile(ctx context.Context, cloudProvider v3.CloudProvider) (string, error) { - if len(cloudProvider.CloudConfig) == 0 { - return "", nil - } - tmpMap := make(map[string]interface{}) - for key, value := range cloudProvider.CloudConfig { - tmpBool, err := strconv.ParseBool(value) - if err == nil { - tmpMap[key] = tmpBool - continue - } - tmpInt, err := strconv.ParseInt(value, 10, 64) - if err == nil { - tmpMap[key] = tmpInt - continue - } - tmpFloat, err := strconv.ParseFloat(value, 64) - if err == nil { - tmpMap[key] = tmpFloat - continue - } - tmpMap[key] = value - } - jsonString, err := json.MarshalIndent(tmpMap, "", "\n") - if err != nil { - return "", err - } - return string(jsonString), nil -} - func doDeployConfigFile(ctx context.Context, host *hosts.Host, cloudConfig, alpineImage string, prsMap map[string]v3.PrivateRegistry) error { // remove existing container. Only way it's still here is if previous deployment failed if err := docker.DoRemoveContainer(ctx, host.DClient, CloudConfigDeployer, host.Address); err != nil { diff --git a/cluster/cluster.go b/cluster/cluster.go index d1a5ddff..cd2cbde8 100644 --- a/cluster/cluster.go +++ b/cluster/cluster.go @@ -2,8 +2,10 @@ package cluster import ( "context" + "encoding/json" "fmt" "net" + "strconv" "strings" "github.com/rancher/rke/authz" @@ -42,6 +44,7 @@ type Cluster struct { K8sWrapTransport k8s.WrapTransport UseKubectlDeploy bool UpdateWorkersOnly bool + CloudConfigFile string } const ( @@ -54,6 +57,9 @@ const ( LocalNodeAddress = "127.0.0.1" LocalNodeHostname = "localhost" LocalNodeUser = "root" + CloudProvider = "CloudProvider" + AzureCloudProvider = "azure" + AWSCloudProvider = "aws" ) func (c *Cluster) DeployControlPlane(ctx context.Context) error { @@ -165,7 +171,11 @@ func ParseCluster( } c.PrivateRegistriesMap[pr.URL] = pr } - + // parse the cluster config file + c.CloudConfigFile, err = c.parseCloudConfig(ctx) + if err != nil { + return nil, fmt.Errorf("Failed to parse cloud config file: %v", err) + } return c, nil } @@ -317,7 +327,13 @@ func (c *Cluster) PrePullK8sImages(ctx context.Context) error { return nil } -func ConfigureCluster(ctx context.Context, rkeConfig v3.RancherKubernetesEngineConfig, crtBundle map[string]pki.CertificatePKI, clusterFilePath, configDir string, k8sWrapTransport k8s.WrapTransport, useKubectl bool) error { +func ConfigureCluster( + ctx context.Context, + rkeConfig v3.RancherKubernetesEngineConfig, + crtBundle map[string]pki.CertificatePKI, + clusterFilePath, configDir string, + k8sWrapTransport k8s.WrapTransport, + useKubectl bool) error { // dialer factories are not needed here since we are not uses docker only k8s jobs kubeCluster, err := ParseCluster(ctx, &rkeConfig, clusterFilePath, configDir, nil, nil, k8sWrapTransport) if err != nil { @@ -343,3 +359,43 @@ func (c *Cluster) getEtcdProcessHostMap(readyEtcdHosts []*hosts.Host) map[*hosts } return etcdProcessHostMap } + +func (c *Cluster) parseCloudConfig(ctx context.Context) (string, error) { + // check for azure cloud provider + if c.AzureCloudProvider.TenantID != "" { + c.CloudProvider.Name = AzureCloudProvider + jsonString, err := json.MarshalIndent(c.AzureCloudProvider, "", "\n") + if err != nil { + return "", err + } + return string(jsonString), nil + } + if len(c.CloudProvider.CloudConfig) == 0 { + return "", nil + } + // handle generic cloud config + tmpMap := make(map[string]interface{}) + for key, value := range c.CloudProvider.CloudConfig { + tmpBool, err := strconv.ParseBool(value) + if err == nil { + tmpMap[key] = tmpBool + continue + } + tmpInt, err := strconv.ParseInt(value, 10, 64) + if err == nil { + tmpMap[key] = tmpInt + continue + } + tmpFloat, err := strconv.ParseFloat(value, 64) + if err == nil { + tmpMap[key] = tmpFloat + continue + } + tmpMap[key] = value + } + jsonString, err := json.MarshalIndent(tmpMap, "", "\n") + if err != nil { + return "", err + } + return string(jsonString), nil +} diff --git a/cluster/defaults.go b/cluster/defaults.go index ae7aab25..9cce36ce 100644 --- a/cluster/defaults.go +++ b/cluster/defaults.go @@ -175,6 +175,12 @@ func (c *Cluster) setClusterNetworkDefaults() { CalicoCloudProvider: DefaultNetworkCloudProvider, } } + if c.CalicoNetworkProvider.CloudProvider != "" { + networkPluginConfigDefaultsMap[CalicoCloudProvider] = c.CalicoNetworkProvider.CloudProvider + } + if c.FlannelNetworkProvider.Iface != "" { + networkPluginConfigDefaultsMap[FlannelIface] = c.FlannelNetworkProvider.Iface + } for k, v := range networkPluginConfigDefaultsMap { setDefaultIfEmptyMapValue(c.Network.Options, k, v) } diff --git a/cluster/hosts.go b/cluster/hosts.go index 032758cc..c9945087 100644 --- a/cluster/hosts.go +++ b/cluster/hosts.go @@ -121,7 +121,7 @@ func (c *Cluster) SetUpHosts(ctx context.Context) error { } log.Infof(ctx, "[certificates] Successfully deployed kubernetes certificates to Cluster nodes") if c.CloudProvider.Name != "" { - if err := deployCloudProviderConfig(ctx, hosts, c.CloudProvider, c.SystemImages.Alpine, c.PrivateRegistriesMap); err != nil { + if err := deployCloudProviderConfig(ctx, hosts, c.SystemImages.Alpine, c.PrivateRegistriesMap, c.CloudConfigFile); err != nil { return err } log.Infof(ctx, "[%s] Successfully deployed kubernetes cloud config to Cluster nodes", CloudConfigServiceName) diff --git a/cluster/network.go b/cluster/network.go index 969b728d..a1630cef 100644 --- a/cluster/network.go +++ b/cluster/network.go @@ -94,8 +94,6 @@ const ( Calicoctl = "Calicoctl" FlannelInterface = "FlannelInterface" - CloudProvider = "CloudProvider" - AWSCloudProvider = "aws" RBACConfig = "RBACConfig" ) diff --git a/cluster/plan.go b/cluster/plan.go index 7ea71dfe..e92a006f 100644 --- a/cluster/plan.go +++ b/cluster/plan.go @@ -6,6 +6,8 @@ import ( "strconv" "strings" + b64 "encoding/base64" + "github.com/rancher/rke/hosts" "github.com/rancher/rke/pki" "github.com/rancher/rke/services" @@ -52,10 +54,15 @@ func BuildRKEConfigNodePlan(ctx context.Context, myCluster *Cluster, host *hosts portChecks = append(portChecks, BuildPortChecksFromPortList(host, EtcdPortList, ProtocolTCP)...) } + cloudConfig := v3.File{ + Name: CloudConfigPath, + Contents: b64.StdEncoding.EncodeToString([]byte(myCluster.CloudConfigFile)), + } return v3.RKEConfigNodePlan{ Address: host.Address, Processes: processes, PortChecks: portChecks, + Files: []v3.File{cloudConfig}, } }