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

fix: destroy elb #803

Merged
merged 8 commits into from
Dec 1, 2022
Merged
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
8 changes: 8 additions & 0 deletions cmd/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"time"

"github.com/kubefirst/kubefirst/configs"
"github.com/kubefirst/kubefirst/internal/aws"
"github.com/kubefirst/kubefirst/internal/domain"
"github.com/kubefirst/kubefirst/internal/handlers"
"github.com/kubefirst/kubefirst/internal/services"
Expand Down Expand Up @@ -202,6 +203,13 @@ cluster provisioning process spinning up the services, and validates the livenes
}

if viper.GetString("cloud") == flagset.CloudAws {
//POST-install aws cloud census
elbName, sg := aws.GetELBByClusterName(viper.GetString("cluster-name"))
viper.Set("aws.vpcid", aws.GetVPCIdByClusterName(viper.GetString("cluster-name")))
viper.Set("aws.elb.name", elbName)
viper.Set("aws.elb.sg", sg)
viper.WriteConfig()

err = state.UploadKubefirstToStateStore(globalFlags.DryRun)
if err != nil {
log.Println(err)
Expand Down
184 changes: 184 additions & 0 deletions internal/aws/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/feature/s3/manager"
"github.com/aws/aws-sdk-go-v2/service/ec2"
ec2Types "github.com/aws/aws-sdk-go-v2/service/ec2/types"
"github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing"
"github.com/aws/aws-sdk-go-v2/service/route53"
route53Types "github.com/aws/aws-sdk-go-v2/service/route53/types"
Expand Down Expand Up @@ -993,6 +994,102 @@ func ProfileInjection(envs *map[string]string) {
}
}

func DestroyLoadBalancerByName(elbName string) error {
awsConfig, err := NewAws()
if err != nil {
log.Printf("Failed to load config: %v", err)
return err
}
loadBalancerNameString := string(elbName)

if len(loadBalancerNameString) > 0 {
loadBalancerClient := elasticloadbalancing.NewFromConfig(awsConfig)

loadBalancerInput := elasticloadbalancing.DeleteLoadBalancerInput{
LoadBalancerName: &loadBalancerNameString,
}

log.Printf("trying to delete load balancer %s\n", loadBalancerNameString)

_, err = loadBalancerClient.DeleteLoadBalancer(context.Background(), &loadBalancerInput)

if err != nil {
return err
}

log.Printf("deleted load balancer %s\n", loadBalancerNameString)
}

return nil
}

func DestroySecurityGroupById(securityGroupId string) error {
// todo: use method approach to avoid new AWS client initializations
awsRegion := viper.GetString("aws.region")
awsProfile := viper.GetString("aws.profile")
awsConfig, err := config.LoadDefaultConfig(
context.Background(),
config.WithRegion(awsRegion),
config.WithSharedConfigProfile(awsProfile),
)
if err != nil {
log.Println("error: ", err)
}

if len(securityGroupId) > 0 {
securityGroupClient := ec2.NewFromConfig(awsConfig)

securityGroupInput := ec2.DeleteSecurityGroupInput{

GroupId: aws.String(securityGroupId),
}

log.Printf("trying to delete security group %s\n", securityGroupId)

_, err = securityGroupClient.DeleteSecurityGroup(context.Background(), &securityGroupInput)
if err != nil {
return err
}

log.Printf("deleted security group %s\n", securityGroupId)
}

return nil
}

func DestroySecurityGroupByName(securityGroupName string) error {
// todo: use method approach to avoid new AWS client initializations
awsRegion := viper.GetString("aws.region")
awsProfile := viper.GetString("aws.profile")
awsConfig, err := config.LoadDefaultConfig(
context.Background(),
config.WithRegion(awsRegion),
config.WithSharedConfigProfile(awsProfile),
)
if err != nil {
log.Println("error: ", err)
}

if len(securityGroupName) > 0 {
securityGroupClient := ec2.NewFromConfig(awsConfig)

securityGroupInput := ec2.DeleteSecurityGroupInput{

GroupName: &securityGroupName,
}

log.Printf("trying to delete security group %s\n", securityGroupName)

_, err = securityGroupClient.DeleteSecurityGroup(context.Background(), &securityGroupInput)
if err != nil {
return err
}

log.Printf("deleted security group %s\n", securityGroupName)
}

return nil
}
func DestroyLoadBalancer(clusterName string) error {
// todo: use method approach to avoid new AWS client initializations
awsConfig, err := NewAws()
Expand Down Expand Up @@ -1070,3 +1167,90 @@ func DestroySecurityGroup(clusterName string) error {

return nil
}

func GetELBDetails(ingressHost string) (string, string, error) {
elb := strings.Split(ingressHost, "-")[0]
securityGroup := "k8s-elb-" + elb

return elb, securityGroup, nil

}

func GetVPCIdByClusterName(clusterName string) string {
awsConfig, err := NewAws()
if err != nil {
log.Printf("Failed to load config: %v", err)
}

ec2Client := ec2.NewFromConfig(awsConfig)

filterType := "tag:ClusterName"
vpcData, err := ec2Client.DescribeVpcs(context.Background(), &ec2.DescribeVpcsInput{
Filters: []ec2Types.Filter{
{
Name: &filterType,
Values: []string{clusterName},
},
},
})
if err != nil {
log.Printf("%v", err)
}

if len(vpcData.Vpcs) > 0 {
log.Printf("there is no VPC for the cluster %q", clusterName)
}

for _, v := range vpcData.Vpcs {
vpcId := aws.ToString(v.VpcId)
if v.State == "available" {
//it is only expected to have 1 vpc per cluster name
log.Printf("there is a VPC for the %q cluster, the vpcID is %s", clusterName, vpcId)
return vpcId
}
}
return ""
}

// GetELBByClusterName return the elb name and its security groups
func GetELBByClusterName(clusterName string) (string, []string) {
awsConfig, err := NewAws()
if err != nil {
log.Printf("Failed to load config: %v", err)
}

loadBalancerClient := elasticloadbalancing.NewFromConfig(awsConfig)

elbs, err := loadBalancerClient.DescribeLoadBalancers(context.Background(), &elasticloadbalancing.DescribeLoadBalancersInput{})
if err != nil {
log.Printf("%v", err)
}
if len(elbs.LoadBalancerDescriptions) > 0 {
log.Println("there is no ELB for the cluster ", clusterName)
}

for _, elb := range elbs.LoadBalancerDescriptions {
elbName := aws.ToString(elb.LoadBalancerName)
tags, err := loadBalancerClient.DescribeTags(context.Background(), &elasticloadbalancing.DescribeTagsInput{
LoadBalancerNames: []string{elbName},
})
if err != nil {
log.Printf("%v", err)
}
for _, tagDesc := range tags.TagDescriptions {
for _, tag := range tagDesc.Tags {
key := aws.ToString(tag.Key)
value := aws.ToString(tag.Value)
if value == "owned" && key == fmt.Sprintf("kubernetes.io/cluster/%s", clusterName) {
log.Println("Match tag:", key, value)
log.Println("Match ELB Name:", elbName)
log.Println("Match ELB SG:", elb.SecurityGroups)
//found the right ELB
return elbName, elb.SecurityGroups
}

}
}
}
return "", []string{""}
}
16 changes: 16 additions & 0 deletions internal/k8s/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -458,3 +458,19 @@ func SetArgocdCreds(dryRun bool) {
viper.Set("argocd.admin.username", "admin")
viper.WriteConfig()
}

func GetIngressHost(k8sClient *kubernetes.Clientset, namespace string, name string) string {

ingress, err := k8sClient.NetworkingV1().Ingresses(namespace).Get(context.TODO(), name, metaV1.GetOptions{})
if err != nil {
log.Println(fmt.Sprintf("error getting key: %s from ingress: %s", namespace, name), err)
}

if ingress != nil {
if len(ingress.Status.LoadBalancer.Ingress) > 0 {
ingressLB := ingress.Status.LoadBalancer.Ingress[0]
return ingressLB.Hostname
}
}
return ""
}
12 changes: 8 additions & 4 deletions internal/terraform/terraform.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ func DestroyBaseTerraform(skipBaseTerraform bool) {
envs["TF_VAR_instance_type"] = "t4g.medium"
}

err = aws.DestroyLoadBalancer(viper.GetString("cluster-name"))
err = aws.DestroyLoadBalancerByName(viper.GetString("aws.elb.name"))
if err != nil {
log.Panicf("Failed to destroy load balancer: %v", err)
}
Expand All @@ -212,9 +212,13 @@ func DestroyBaseTerraform(skipBaseTerraform bool) {
log.Printf("failed to terraform destroy base %v", err)
}

err = aws.DestroySecurityGroup(viper.GetString("cluster-name"))
if err != nil {
log.Panicf("Failed to destroy security group: %v", err)
//destroy all found sg
for _, sg := range viper.GetStringSlice("aws.elb.sg") {
log.Println("Removing Security Group:", sg)
err = aws.DestroySecurityGroupById(sg)
if err != nil {
log.Panicf("Failed to destroy security group: %v", err)
}
}

err = pkg.ExecShellWithVars(envs, config.TerraformClientPath, "init")
Expand Down