Skip to content

Commit

Permalink
#29 - implement support Azure provider for Cluster API
Browse files Browse the repository at this point in the history
  • Loading branch information
apanasiuk-el committed Oct 23, 2024
1 parent 116bd15 commit e7a2085
Show file tree
Hide file tree
Showing 16 changed files with 1,203 additions and 330 deletions.
405 changes: 380 additions & 25 deletions cmd/cluster.go

Large diffs are not rendered by default.

38 changes: 38 additions & 0 deletions cmd/cluster_capa.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package cmd

import (
"strings"

"rmk/util"
)

const (
awsFlagsCategory = "AWS authentication"
)

func (cc *ClusterCommands) getAWSEksKubeConfig() *util.SpecCMD {
return &util.SpecCMD{
Envs: []string{
"AWS_PROFILE=" + cc.Conf.Profile,
"AWS_CONFIG_FILE=" + strings.Join(cc.Conf.AWSSharedConfigFile(cc.Conf.Profile), ""),
"AWS_SHARED_CREDENTIALS_FILE=" + strings.Join(cc.Conf.AWSSharedCredentialsFile(cc.Conf.Profile), ""),
},
Args: []string{"eks", "--region",
cc.Conf.Region,
"update-kubeconfig",
"--name",
cc.Conf.Name + "-eks",
"--profile",
cc.Conf.Profile,
},
Command: "aws",
Ctx: cc.Ctx.Context,
Dir: cc.WorkDir,
Debug: true,
}
}

func (cc *ClusterCommands) awsClusterContext() error {
cc.SpecCMD = cc.getAWSEksKubeConfig()
return releaseRunner(cc).runCMD()
}
155 changes: 155 additions & 0 deletions cmd/cluster_capz.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
package cmd

import (
"os"
"path/filepath"

corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/json"
v1 "k8s.io/client-go/applyconfigurations/core/v1"

"rmk/providers/azure_provider"
"rmk/util"
)

const (
azureClusterIdentityName = "azure-cluster-identity"
azureClusterIdentityNamespace = "capz-system"
azureClusterIdentitySecret = "azure-cluster-identity-secret"
azureFlagsCategory = "Azure authentication"
)

var azureClusterIdentitySecretType = corev1.SecretTypeOpaque

type AzureClusterIdentityConfig struct {
*AzureClusterIdentity
*v1.SecretApplyConfiguration
ManifestFilesDir string
ManifestFiles []string
}

type AzureClusterIdentity struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec AzureClusterIdentitySpec `json:"spec,omitempty"`
}

type AzureClusterIdentitySpec struct {
AllowedNamespaces struct {
NamespaceList []string `json:"list"`
Selector *metav1.LabelSelector `json:"selector,omitempty"`
} `json:"allowedNamespaces,omitempty"`
ClientID string `json:"clientID"`
ClientSecret corev1.SecretReference `json:"clientSecret,omitempty"`
TenantID string `json:"tenantID"`
Type string `json:"type"`
}

func NewAzureClusterIdentityConfig(ac *azure_provider.AzureConfigure) *AzureClusterIdentityConfig {
acic := &AzureClusterIdentityConfig{
AzureClusterIdentity: &AzureClusterIdentity{
TypeMeta: metav1.TypeMeta{
Kind: "AzureClusterIdentity",
APIVersion: "infrastructure.cluster.x-k8s.io/v1beta1",
},
ObjectMeta: metav1.ObjectMeta{
Name: azureClusterIdentityName,
Namespace: azureClusterIdentityNamespace,
Labels: map[string]string{"clusterctl.cluster.x-k8s.io/move-hierarchy": "true"},
},
Spec: AzureClusterIdentitySpec{
AllowedNamespaces: struct {
NamespaceList []string `json:"list"`
Selector *metav1.LabelSelector `json:"selector,omitempty"`
}(struct {
NamespaceList []string
Selector *metav1.LabelSelector
}{
NamespaceList: []string{azureClusterIdentityNamespace},
}),
ClientID: ac.ClientID,
ClientSecret: corev1.SecretReference{
Name: azureClusterIdentitySecret,
Namespace: azureClusterIdentityNamespace,
},
TenantID: ac.TenantID,
Type: "ServicePrincipal",
},
},
SecretApplyConfiguration: v1.Secret(azureClusterIdentitySecret, azureClusterIdentityNamespace),
ManifestFilesDir: filepath.Join("/tmp", azureClusterIdentityName),
}

acic.SecretApplyConfiguration.Type = &azureClusterIdentitySecretType
acic.SecretApplyConfiguration.Data = map[string][]byte{"clientSecret": []byte(ac.ClientSecret)}

return acic
}

func createManifestFile(object interface{}, dir, fileName string) (string, error) {
data, err := json.Marshal(object)
if err != nil {
return "", err
}

return util.CreateTempYAMLFile(dir, fileName, data)
}

func (acic *AzureClusterIdentityConfig) createAzureClusterIdentityManifestFiles() error {
if err := os.MkdirAll(acic.ManifestFilesDir, 0775); err != nil {
return err
}

fileCR, err := createManifestFile(acic.AzureClusterIdentity, acic.ManifestFilesDir, azureClusterIdentityName)
if err != nil {
return err
}

acic.ManifestFiles = append(acic.ManifestFiles, fileCR)

fileSecret, err := createManifestFile(acic.SecretApplyConfiguration, acic.ManifestFilesDir, azureClusterIdentitySecret)
if err != nil {
return err
}

acic.ManifestFiles = append(acic.ManifestFiles, fileSecret)

return nil
}

func (cc *ClusterCommands) applyAzureClusterIdentity() error {
var kubectlArgs = []string{"apply"}

ac := azure_provider.NewAzureConfigure()
if err := ac.ReadSPCredentials(cc.Conf.Name); err != nil {
return err
}

acic := NewAzureClusterIdentityConfig(ac)
if err := acic.createAzureClusterIdentityManifestFiles(); err != nil {
return err
}

for _, val := range acic.ManifestFiles {
kubectlArgs = append(kubectlArgs, "-f", val)
}

cc.SpecCMD = cc.kubectl(kubectlArgs...)
if err := releaseRunner(cc).runCMD(); err != nil {
return err
}

return os.RemoveAll(acic.ManifestFilesDir)
}

func (cc *ClusterCommands) azureClusterContext() ([]byte, error) {
ac := azure_provider.NewAzureConfigure()

if err := ac.NewAzureManagedClustersClient(cc.Ctx.Context, cc.Conf.Name); err != nil {
return nil, err
}

return ac.GetAzureClusterContext(cc.Conf.Tenant, cc.Conf.Name)
}
36 changes: 33 additions & 3 deletions cmd/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,34 +116,64 @@ func Commands() []*cli.Command {
Subcommands: []*cli.Command{
{
Name: "create",
Usage: "Create CAPI cluster",
Usage: "Create CAPI management cluster",
Aliases: []string{"c"},
Before: readInputSourceWithContext(gitSpec, conf, flags["clusterK3DCreate"]),
Flags: flags["clusterK3DCreate"],
Category: "capi",
BashComplete: util.ShellCompleteCustomOutput,
Action: K3DCreateAction(conf),
After: CAPIInitAction(conf),
},
{
Name: "delete",
Usage: "Delete CAPI cluster",
Usage: "Delete CAPI management cluster",
Aliases: []string{"d"},
Before: readInputSourceWithContext(gitSpec, conf, flags["hidden"]),
Flags: flags["hidden"],
Category: "capi",
BashComplete: util.ShellCompleteCustomOutput,
Action: K3DAction(conf, K3DRunner.createDeleteK3DCluster),
},
{
Name: "destroy",
Usage: "Destroy K8S target (workload) cluster",
Before: readInputSourceWithContext(gitSpec, conf, flags["hidden"]),
Flags: flags["hidden"],
Category: "capi",
BashComplete: util.ShellCompleteCustomOutput,
Action: CAPIProvisionDestroyAction(conf),
},
{
Name: "list",
Usage: "List CAPI clusters",
Usage: "List CAPI management clusters",
Aliases: []string{"l"},
Before: readInputSourceWithContext(gitSpec, conf, flags["hidden"]),
Flags: flags["hidden"],
Category: "capi",
BashComplete: util.ShellCompleteCustomOutput,
Action: K3DAction(conf, K3DRunner.listK3DClusters),
},
{
Name: "provision",
Usage: "Provision K8S target (workload) cluster",
Aliases: []string{"p"},
Before: readInputSourceWithContext(gitSpec, conf, flags["hidden"]),
Flags: flags["hidden"],
Category: "capi",
BashComplete: util.ShellCompleteCustomOutput,
Action: CAPIProvisionDestroyAction(conf),
},
{
Name: "update",
Usage: "Update CAPI management cluster",
Aliases: []string{"u"},
Before: readInputSourceWithContext(gitSpec, conf, flags["hidden"]),
Flags: flags["hidden"],
Category: "capi",
BashComplete: util.ShellCompleteCustomOutput,
Action: CAPIUpdateAction(conf),
},
},
},
{
Expand Down
Loading

0 comments on commit e7a2085

Please sign in to comment.