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

Feature/rmk 29 refactor internal logic of rmk cluster provider initialization and selection #40

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
654e3b0
#29 - restructuring code files, refactoring
apanasiuk-el Aug 1, 2024
ba97fb5
#29 - fix command "config list" output for adjacent tenant names
apanasiuk-el Aug 5, 2024
b23a916
#29 - delete artifact-mode functionality
apanasiuk-el Aug 7, 2024
8d4acd5
#29 - draft refactoring 'rmk config init'
apanasiuk-el Aug 8, 2024
7da2c5f
#29 - deprecate Terraform commands, add commands for managing CAPI
apanasiuk-el Sep 25, 2024
5318f79
#29 - refactoring latest changes
apanasiuk-el Sep 26, 2024
12b1761
#29 - refactoring k3d list command
apanasiuk-el Sep 30, 2024
f1fd76b
#29 - change root-domain configuration
apanasiuk-el Oct 1, 2024
5ae37e4
#29 - refactoring
apanasiuk-el Oct 1, 2024
116bd15
#29 - refactoring
apanasiuk-el Oct 2, 2024
e7a2085
#29 - implement support Azure provider for Cluster API
apanasiuk-el Oct 23, 2024
0100612
#29 - implement support AWS provider for Cluster API
apanasiuk-el Oct 31, 2024
2204611
#29 - refactoring
apanasiuk-el Oct 31, 2024
8b518de
#29 - add creating SSH keys pair for AWS provider
apanasiuk-el Nov 6, 2024
1c0ca2f
#29 - refactoring
apanasiuk-el Nov 6, 2024
c4e02de
#29 - refactoring
apanasiuk-el Nov 6, 2024
016ac74
#29 - refactoring
apanasiuk-el Nov 6, 2024
c5fedc5
#29 - refactoring
apanasiuk-el Nov 7, 2024
8597c60
#29 - refactoring
apanasiuk-el Nov 8, 2024
57d810c
#29 - implement support GCP provider for Cluster API
apanasiuk-el Nov 21, 2024
1d7baf1
#29 - refactoring
apanasiuk-el Nov 21, 2024
a00f79d
#29 - refactoring
apanasiuk-el Nov 21, 2024
358d4e6
#29 - refactoring Google provider environment variables
apanasiuk-el Nov 25, 2024
57c742a
#29 - implement support Azure key vault for store SOPS Age keys
apanasiuk-el Dec 11, 2024
e37b7e3
#29 - refactoring
apanasiuk-el Dec 11, 2024
92ed29e
#29 - refactoring
apanasiuk-el Dec 11, 2024
81db188
#29 - implement support GCP secrets manager for store SOPS Age keys
apanasiuk-el Dec 16, 2024
50d34cf
#29 - refactoring
apanasiuk-el Dec 16, 2024
bf028e7
#29 - implement support AWS secrets manager for store SOPS Age keys
apanasiuk-el Dec 17, 2024
20e0ccf
#29 - refactoring
apanasiuk-el Dec 17, 2024
e1b43a7
#29 - add release notes
apanasiuk-el Dec 17, 2024
8b0d70f
#29 - refactoring release notes
apanasiuk-el Dec 17, 2024
6c9c60f
#29 - fix project generate behavior
apanasiuk-el Dec 18, 2024
cc25491
#29 - refactoring
apanasiuk-el Dec 18, 2024
ff3f732
#29 - resolved conflicts
apanasiuk-el Dec 19, 2024
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
580 changes: 0 additions & 580 deletions aws_provider/aws.go

This file was deleted.

528 changes: 528 additions & 0 deletions cmd/cluster.go

Large diffs are not rendered by default.

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

import (
"os"
"path/filepath"
"strings"

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

"rmk/providers/aws_provider"
"rmk/util"
)

const (
awsFlagsCategory = "AWS authentication"

awsIAMControllerCredentialsTemplate = `[default]
aws_access_key_id = {{ .AwsCredentialsProfile.AccessKeyID }}
aws_secret_access_key = {{ .AwsCredentialsProfile.SecretAccessKey }}
region = {{ .Region }}
{{- if .AwsCredentialsProfile.SessionToken }}
aws_session_token = {{ .AwsCredentialsProfile.SessionToken }}
{{- end }}
`
awsIAMControllerSecret = "aws-iam-controller-secret"
awsClusterStaticIdentityName = "aws-cluster-identity"
awsClusterStaticIdentityNamespace = "capa-system"
awsClusterStaticIdentitySecret = "aws-cluster-identity-secret"
)

var awsClusterStaticIdentitySecretType = corev1.SecretTypeOpaque

type AWSClusterStaticIdentityConfig struct {
*AWSClusterStaticIdentity
*v1.SecretApplyConfiguration
AWSIAMControllerSecret *v1.SecretApplyConfiguration
ManifestFiles []string
ManifestFilesDir string
}

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

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

type AWSClusterStaticIdentitySpec struct {
AllowedNamespaces struct {
NamespaceList []string `json:"list"`
Selector *metav1.LabelSelector `json:"selector,omitempty"`
} `json:"allowedNamespaces,omitempty"`
SecretRef string `json:"secretRef"`
}

func NewAWSClusterStaticIdentityConfig(ac *aws_provider.AwsConfigure) *AWSClusterStaticIdentityConfig {
acic := &AWSClusterStaticIdentityConfig{
AWSClusterStaticIdentity: &AWSClusterStaticIdentity{
TypeMeta: metav1.TypeMeta{
Kind: "AWSClusterStaticIdentity",
APIVersion: "infrastructure.cluster.x-k8s.io/v1beta2",
},
ObjectMeta: metav1.ObjectMeta{
Name: awsClusterStaticIdentityName,
Namespace: awsClusterStaticIdentityNamespace,
Labels: map[string]string{"clusterctl.cluster.x-k8s.io/move-hierarchy": "true"},
},
Spec: AWSClusterStaticIdentitySpec{
AllowedNamespaces: struct {
NamespaceList []string `json:"list"`
Selector *metav1.LabelSelector `json:"selector,omitempty"`
}(struct {
NamespaceList []string
Selector *metav1.LabelSelector
}{
NamespaceList: []string{awsClusterStaticIdentityNamespace},
}),
SecretRef: awsClusterStaticIdentitySecret,
},
},
AWSIAMControllerSecret: v1.Secret(awsIAMControllerSecret, awsClusterStaticIdentityNamespace),
SecretApplyConfiguration: v1.Secret(awsClusterStaticIdentitySecret, awsClusterStaticIdentityNamespace),
ManifestFilesDir: filepath.Join(os.TempDir(), awsClusterStaticIdentityName),
}

profile, err := ac.RenderAWSConfigProfile(awsIAMControllerCredentialsTemplate)
if err != nil {
return nil
}

acic.AWSIAMControllerSecret.Type = &awsClusterStaticIdentitySecretType
acic.AWSIAMControllerSecret.Data = map[string][]byte{"credentials": profile}

acic.SecretApplyConfiguration.Type = &awsClusterStaticIdentitySecretType
acic.SecretApplyConfiguration.Data = map[string][]byte{
"AccessKeyID": []byte(ac.AwsCredentialsProfile.AccessKeyID),
"SecretAccessKey": []byte(ac.AwsCredentialsProfile.SecretAccessKey),
}

if len(ac.AwsCredentialsProfile.SessionToken) > 0 {
acic.SecretApplyConfiguration.Data["SessionToken"] = []byte(ac.AwsCredentialsProfile.SessionToken)
}

return acic
}

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

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

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

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

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

fileIAMControllerSecret, err := createManifestFile(acic.AWSIAMControllerSecret, acic.ManifestFilesDir, awsIAMControllerSecret)
if err != nil {
return err
}

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

return nil
}

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

ac := aws_provider.NewAwsConfigure(cc.Ctx.Context, cc.Conf.Profile)
if err := ac.ReadAWSConfigProfile(); err != nil {
return err
}

acic := NewAWSClusterStaticIdentityConfig(ac)
if err := acic.createAWSClusterIdentityManifestFiles(); 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 {
if err := os.RemoveAll(acic.ManifestFilesDir); err != nil {
return err
}

return err
}

return os.RemoveAll(acic.ManifestFilesDir)
}

func (cc *ClusterCommands) getAWSClusterContext() ([]byte, error) {
return aws_provider.NewAwsConfigure(cc.Ctx.Context, cc.Conf.Profile).GetAWSClusterContext(cc.Conf.Name)
}

func (cc *ClusterCommands) createAWSClusterSSHKey() error {
return aws_provider.NewAwsConfigure(cc.Ctx.Context, cc.Conf.Profile).CreateAWSEC2SSHKey(cc.Conf.Name)
}

func (cc *ClusterCommands) deleteAWSClusterSSHKey() error {
return aws_provider.NewAwsConfigure(cc.Ctx.Context, cc.Conf.Profile).DeleteAWSEC2SSHKey(cc.Conf.Name)
}

func (cc *ClusterCommands) createAWSSecrets() error {
a := aws_provider.NewAwsConfigure(cc.Ctx.Context, cc.Conf.Profile)

secrets, err := a.GetAWSSecrets(cc.Conf.Tenant)
if err != nil {
return err
}

if len(secrets) > 0 {
return nil
}

walkMatch, err := util.WalkMatch(cc.Conf.SopsAgeKeys, cc.Conf.Tenant+"*"+util.SopsAgeKeyExt)
if err != nil {
return err
}

for _, val := range walkMatch {
file, err := os.ReadFile(val)
if err != nil {
return err
}

keyName := strings.TrimSuffix(filepath.Base(val), util.SopsAgeKeyExt)

if err := a.SetAWSSecret(cc.Conf.Tenant, keyName, file); err != nil {
return err
}
}

return nil
}
132 changes: 132 additions & 0 deletions cmd/cluster_capg.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package cmd

import (
"os"
"path/filepath"
"strings"

corev1 "k8s.io/api/core/v1"
v1 "k8s.io/client-go/applyconfigurations/core/v1"

"rmk/providers/google_provider"
"rmk/util"
)

const (
gcpClusterIdentityName = "gcp-cluster-identity"
gcpClusterIdentityNamespace = "capg-system"
gcpClusterIdentitySecret = "gcp-cluster-identity-secret"
gcpFlagsCategory = "GCP authentication"
)

var gcpClusterIdentitySecretType = corev1.SecretTypeOpaque

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

func NewGCPClusterIdentityConfig(gcp *google_provider.GCPConfigure) *GCPClusterIdentityConfig {
gcpcc := &GCPClusterIdentityConfig{
SecretApplyConfiguration: v1.Secret(gcpClusterIdentitySecret, gcpClusterIdentityNamespace),
ManifestFilesDir: filepath.Join(os.TempDir(), gcpClusterIdentityName),
}

gcpcc.SecretApplyConfiguration.Type = &gcpClusterIdentitySecretType
gcpcc.SecretApplyConfiguration.Data = map[string][]byte{"credentials": gcp.AppCredentials.JSON()}

return gcpcc
}

func (gic *GCPClusterIdentityConfig) createGCPClusterIdentitySecretManifestFiles() error {
if err := os.MkdirAll(gic.ManifestFilesDir, 0775); err != nil {
return err
}

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

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

return nil
}

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

gcp := google_provider.NewGCPConfigure(cc.Ctx.Context, cc.Conf.GCPConfigure.AppCredentialsPath)
if err := gcp.ReadSACredentials(); err != nil {
return err
}

gic := NewGCPClusterIdentityConfig(gcp)
if err := gic.createGCPClusterIdentitySecretManifestFiles(); err != nil {
return err
}

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

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

return err
}

return os.RemoveAll(gic.ManifestFilesDir)
}

func (cc *ClusterCommands) getGCPClusterContext() ([]byte, error) {
return google_provider.NewGCPConfigure(cc.Ctx.Context, cc.Conf.GCPConfigure.AppCredentialsPath).
GetGCPClusterContext(cc.Conf.Name)
}

func (cc *ClusterCommands) createGCPNATGateway() error {
return google_provider.NewGCPConfigure(cc.Ctx.Context, cc.Conf.GCPConfigure.AppCredentialsPath).
CreateGCPCloudNATGateway(cc.Conf.GCPRegion)
}

func (cc *ClusterCommands) deleteGCPNATGateway() error {
return google_provider.NewGCPConfigure(cc.Ctx.Context, cc.Conf.GCPConfigure.AppCredentialsPath).
DeleteGCPCloudNATGateway(cc.Conf.GCPRegion)
}

func (cc *ClusterCommands) createGCPSecrets() error {
gcp := google_provider.NewGCPConfigure(cc.Ctx.Context, cc.Conf.GCPConfigure.AppCredentialsPath)

secrets, err := gcp.GetGCPSecrets(cc.Conf.Tenant)
if err != nil {
return err
}

if len(secrets) > 0 {
return nil
}

walkMatch, err := util.WalkMatch(cc.Conf.SopsAgeKeys, cc.Conf.Tenant+"*"+util.SopsAgeKeyExt)
if err != nil {
return err
}

for _, val := range walkMatch {
file, err := os.ReadFile(val)
if err != nil {
return err
}

keyName := strings.TrimSuffix(filepath.Base(val), util.SopsAgeKeyExt)

if err := gcp.SetGCPSecret(cc.Conf.Tenant, cc.Conf.GCPRegion, keyName, file); err != nil {
return err
}
}

return nil
}
Loading