mirror of https://github.com/kubernetes/kops.git
820 lines
22 KiB
Go
820 lines
22 KiB
Go
/*
|
|
Copyright 2019 The Kubernetes Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package ali
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"k8s.io/klog/v2"
|
|
|
|
common "github.com/denverdino/aliyungo/common"
|
|
ecs "github.com/denverdino/aliyungo/ecs"
|
|
ess "github.com/denverdino/aliyungo/ess"
|
|
ram "github.com/denverdino/aliyungo/ram"
|
|
slb "github.com/denverdino/aliyungo/slb"
|
|
|
|
"k8s.io/kops/pkg/resources"
|
|
"k8s.io/kops/upup/pkg/fi"
|
|
"k8s.io/kops/upup/pkg/fi/cloudup/alitasks"
|
|
"k8s.io/kops/upup/pkg/fi/cloudup/aliup"
|
|
)
|
|
|
|
type aliListFn func() ([]*resources.Resource, error)
|
|
|
|
const (
|
|
typeScalingGroup = "ScalingGroup"
|
|
typeLoadBalancer = "LoadBalancer"
|
|
typeSecurityGroup = "SecurityGroup"
|
|
typeSecurityGroupRole = "SecurityGroupRole"
|
|
typeVswitch = "Vswitch"
|
|
typeRamRole = "RamRole"
|
|
typeVolume = "Volume"
|
|
typeSSHKey = "SSHKey"
|
|
typeVPC = "VPC"
|
|
typeNatGateway = "NatGateway"
|
|
typeEIP = "EIP"
|
|
)
|
|
|
|
type clusterDiscoveryALI struct {
|
|
aliCloud aliup.ALICloud
|
|
clusterName string
|
|
scalingGroup map[string]string
|
|
}
|
|
|
|
func ListResourcesALI(aliCloud aliup.ALICloud, clusterName string, region string) (map[string]*resources.Resource, error) {
|
|
|
|
resources := make(map[string]*resources.Resource)
|
|
|
|
d := clusterDiscoveryALI{
|
|
aliCloud: aliCloud,
|
|
clusterName: clusterName,
|
|
}
|
|
d.scalingGroup = make(map[string]string)
|
|
|
|
// SecurityGroup and VPC should be deleted after ScalingGroup.
|
|
// We list ScalingGroups first to configure dependencies' blocked parameter.
|
|
resourceTrackers, err := d.ListScalingGroups()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for _, t := range resourceTrackers {
|
|
d.scalingGroup[t.Name] = t.ID
|
|
resources[t.Type+":"+t.ID] = t
|
|
}
|
|
|
|
listFunctions := []aliListFn{
|
|
d.ListLoadBalancer,
|
|
d.ListRam,
|
|
d.ListSecurityGroup,
|
|
d.ListSSHKey,
|
|
d.ListVPC,
|
|
d.ListVolume,
|
|
}
|
|
|
|
for _, fn := range listFunctions {
|
|
resourceTrackers, err := fn()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for _, t := range resourceTrackers {
|
|
resources[t.Type+":"+t.ID] = t
|
|
}
|
|
}
|
|
|
|
for k, t := range resources {
|
|
if t.Done {
|
|
delete(resources, k)
|
|
}
|
|
}
|
|
|
|
return resources, nil
|
|
}
|
|
|
|
func (d *clusterDiscoveryALI) ListScalingGroups() ([]*resources.Resource, error) {
|
|
var resourceTrackers []*resources.Resource
|
|
|
|
// ScalingGroup Name defined in /pkg/model/alimodel/context.go
|
|
// The should be changed at the same time.
|
|
remove := []string{
|
|
"masters." + d.clusterName,
|
|
"nodes." + d.clusterName,
|
|
"bastions." + d.clusterName,
|
|
}
|
|
pageNumber := 1
|
|
pageSize := 50
|
|
|
|
for {
|
|
describeScalingGroupsArgs := &ess.DescribeScalingGroupsArgs{
|
|
RegionId: common.Region(d.aliCloud.Region()),
|
|
Pagination: common.Pagination{
|
|
PageNumber: pageNumber,
|
|
PageSize: pageSize,
|
|
},
|
|
}
|
|
groups, _, err := d.aliCloud.EssClient().DescribeScalingGroups(describeScalingGroupsArgs)
|
|
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error listing ScalingGroup: %v", err)
|
|
}
|
|
|
|
scalingGroups := []ess.ScalingGroupItemType{}
|
|
|
|
for _, group := range groups {
|
|
for _, r := range remove {
|
|
if strings.Contains(group.ScalingGroupName, r) {
|
|
scalingGroups = append(scalingGroups, group)
|
|
}
|
|
}
|
|
}
|
|
|
|
for _, scalingGroup := range scalingGroups {
|
|
|
|
resourceTracker := &resources.Resource{
|
|
Name: scalingGroup.ScalingGroupName,
|
|
ID: scalingGroup.ScalingGroupId,
|
|
Type: typeScalingGroup,
|
|
Deleter: DeleteScalingGroup,
|
|
}
|
|
|
|
d.scalingGroup[scalingGroup.ScalingGroupName] = scalingGroup.ScalingGroupId
|
|
resourceTrackers = append(resourceTrackers, resourceTracker)
|
|
}
|
|
|
|
if len(groups) < pageSize {
|
|
break
|
|
} else {
|
|
pageNumber++
|
|
}
|
|
}
|
|
|
|
return resourceTrackers, nil
|
|
}
|
|
|
|
func DeleteScalingGroup(cloud fi.Cloud, r *resources.Resource) error {
|
|
c := cloud.(aliup.ALICloud)
|
|
klog.V(2).Infof("Removing ScalingGroup with Id %s", r.ID)
|
|
|
|
// Force to delete the ScalingGroup
|
|
// TODO: Should we delete the group softly? Like set ForceDelete to false.
|
|
// That will be safer.
|
|
|
|
// All the resource of the ScalingGroup will be deleted.
|
|
deleteScalingGroupArgs := &ess.DeleteScalingGroupArgs{
|
|
ScalingGroupId: r.ID,
|
|
ForceDelete: true,
|
|
}
|
|
|
|
_, err := c.EssClient().DeleteScalingGroup(deleteScalingGroupArgs)
|
|
if err != nil {
|
|
return fmt.Errorf("error deleting ScalingGroup: %v", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (d *clusterDiscoveryALI) ListLoadBalancer() ([]*resources.Resource, error) {
|
|
var resourceTrackers []*resources.Resource
|
|
|
|
// LoadBalancer has the cluster tag: KubernetesCluster:$ClusterName
|
|
// Find the cluster loadBalancer by this key value pair.
|
|
// TODO: Should we check the tags of loadbalancer?
|
|
|
|
// ScalingGroup Name defined in /pkg/model/alimodel/context.go
|
|
// The should be changed at the same time.
|
|
// ScalingGroup can not be renamed in alicloud, so we recognize by name
|
|
loadBalancerName := "api." + d.clusterName
|
|
|
|
describeLoadBalancersArgs := &slb.DescribeLoadBalancersArgs{
|
|
RegionId: common.Region(d.aliCloud.Region()),
|
|
LoadBalancerName: loadBalancerName,
|
|
}
|
|
loadBalancers, err := d.aliCloud.SlbClient().DescribeLoadBalancers(describeLoadBalancersArgs)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("err listing LoadBalancers")
|
|
}
|
|
|
|
if len(loadBalancers) > 1 {
|
|
return nil, fmt.Errorf("found multiple LoadBalancers with the same name: %v", loadBalancerName)
|
|
}
|
|
|
|
if len(loadBalancers) == 1 {
|
|
resourceTracker := &resources.Resource{
|
|
Name: loadBalancers[0].LoadBalancerName,
|
|
ID: loadBalancers[0].LoadBalancerId,
|
|
Type: typeLoadBalancer,
|
|
Deleter: DeleteLoadBalancer,
|
|
}
|
|
resourceTrackers = append(resourceTrackers, resourceTracker)
|
|
}
|
|
|
|
return resourceTrackers, nil
|
|
}
|
|
|
|
func DeleteLoadBalancer(cloud fi.Cloud, r *resources.Resource) error {
|
|
c := cloud.(aliup.ALICloud)
|
|
klog.V(2).Infof("Removing LoadBalancer with Id %s", r.ID)
|
|
|
|
err := c.SlbClient().DeleteLoadBalancer(r.ID)
|
|
if err != nil {
|
|
return fmt.Errorf("err deleting LoadBalancer:%v", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (d *clusterDiscoveryALI) ListSecurityGroup() ([]*resources.Resource, error) {
|
|
var resourceTrackers []*resources.Resource
|
|
// SecurityGroup's name can be renamed in alicloud.
|
|
// We recognize SecurityGroup with its name and clusterTags
|
|
tags := make(map[string]string)
|
|
d.aliCloud.AddClusterTags(tags)
|
|
|
|
securityGroupNames := []string{
|
|
"masters." + d.clusterName,
|
|
"bastions." + d.clusterName,
|
|
"nodes." + d.clusterName,
|
|
}
|
|
|
|
describeResourceByTagsArgs := &ecs.DescribeResourceByTagsArgs{
|
|
ResourceType: ecs.TagResourceType(alitasks.SecurityResource),
|
|
RegionId: common.Region(d.aliCloud.Region()),
|
|
Tag: tags,
|
|
}
|
|
|
|
resourceList, _, err := d.aliCloud.EcsClient().DescribeResourceByTags(describeResourceByTagsArgs)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("err listing securityGroup:%v", err)
|
|
}
|
|
|
|
blocked := []string{}
|
|
groupTrackers := []*resources.Resource{}
|
|
|
|
if len(resourceList) != 0 {
|
|
for _, resource := range resourceList {
|
|
find := false
|
|
|
|
describeSecurityGroupAttributeArgs := &ecs.DescribeSecurityGroupAttributeArgs{
|
|
SecurityGroupId: resource.ResourceId,
|
|
RegionId: resource.RegionId,
|
|
}
|
|
respGroup, err := d.aliCloud.EcsClient().DescribeSecurityGroupAttribute(describeSecurityGroupAttributeArgs)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("err listing securityGroup:%v", err)
|
|
}
|
|
|
|
for _, value := range securityGroupNames {
|
|
if respGroup.SecurityGroupName == value {
|
|
find = true
|
|
}
|
|
}
|
|
|
|
if find {
|
|
groupTracker := &resources.Resource{
|
|
Name: respGroup.SecurityGroupName,
|
|
ID: respGroup.SecurityGroupId,
|
|
Type: typeSecurityGroup,
|
|
Deleter: DeleteSecurityGroup,
|
|
}
|
|
groupTrackers = append(groupTrackers, groupTracker)
|
|
|
|
if len(respGroup.Permissions.Permission) != 0 {
|
|
for i, securityGroupRole := range respGroup.Permissions.Permission {
|
|
roleTracker := &resources.Resource{
|
|
Name: respGroup.SecurityGroupId,
|
|
ID: respGroup.SecurityGroupName + strconv.Itoa(i),
|
|
Type: typeSecurityGroupRole,
|
|
Deleter: DeleteSecurityGroupRole,
|
|
Obj: securityGroupRole,
|
|
}
|
|
resourceTrackers = append(resourceTrackers, roleTracker)
|
|
|
|
// Any SecurityGroupRole which depends on the current SecurityGroup should be deleted before delete the SecurityGroup.
|
|
// So before deleting any SecurityGroup, we should delete all SecurityGroupRoles of all SecurityGroups.
|
|
blocked = append(blocked, roleTracker.Type+":"+roleTracker.ID)
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
if len(groupTrackers) != 0 {
|
|
for _, groupTracker := range groupTrackers {
|
|
|
|
for scalingGroupName, scalingGroupId := range d.scalingGroup {
|
|
if strings.Contains(scalingGroupName, groupTracker.Name) {
|
|
groupTracker.Blocked = append(groupTracker.Blocked, typeScalingGroup+":"+scalingGroupId)
|
|
}
|
|
}
|
|
|
|
groupTracker.Blocked = append(groupTracker.Blocked, blocked...)
|
|
resourceTrackers = append(resourceTrackers, groupTracker)
|
|
}
|
|
}
|
|
return resourceTrackers, nil
|
|
}
|
|
|
|
func DeleteSecurityGroup(cloud fi.Cloud, r *resources.Resource) error {
|
|
c := cloud.(aliup.ALICloud)
|
|
region := common.Region(c.Region())
|
|
klog.V(2).Infof("Removing SecurityGroup with Id %s", r.ID)
|
|
|
|
err := c.EcsClient().DeleteSecurityGroup(region, r.ID)
|
|
if err != nil {
|
|
return fmt.Errorf("err deleting securityGroup:%v", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func DeleteSecurityGroupRole(cloud fi.Cloud, r *resources.Resource) error {
|
|
c := cloud.(aliup.ALICloud)
|
|
permission := r.Obj.(ecs.PermissionType)
|
|
|
|
klog.V(2).Infof("Removing SecurityGroupRole of SecurityGroup %s", r.Name)
|
|
|
|
if permission.Direction == "ingress" {
|
|
authorizeSecurityGroupArgs := ecs.AuthorizeSecurityGroupArgs{
|
|
SecurityGroupId: r.Name,
|
|
RegionId: common.Region(c.Region()),
|
|
IpProtocol: permission.IpProtocol,
|
|
PortRange: permission.PortRange,
|
|
SourceGroupId: permission.SourceGroupId,
|
|
SourceGroupOwnerAccount: permission.SourceGroupOwnerAccount,
|
|
SourceCidrIp: permission.SourceCidrIp,
|
|
Policy: permission.Policy,
|
|
Priority: permission.Priority,
|
|
NicType: permission.NicType,
|
|
}
|
|
|
|
revokeSecurityGroupArgs := &ecs.RevokeSecurityGroupArgs{
|
|
AuthorizeSecurityGroupArgs: authorizeSecurityGroupArgs,
|
|
}
|
|
|
|
err := c.EcsClient().RevokeSecurityGroup(revokeSecurityGroupArgs)
|
|
if err != nil {
|
|
return fmt.Errorf("err deleting securityGroup Role:%v", err)
|
|
}
|
|
}
|
|
|
|
if permission.Direction == "egress" {
|
|
authorizeSecurityGroupEgressArgs := ecs.AuthorizeSecurityGroupEgressArgs{
|
|
SecurityGroupId: r.Name,
|
|
RegionId: common.Region(c.Region()),
|
|
IpProtocol: permission.IpProtocol,
|
|
PortRange: permission.PortRange,
|
|
DestGroupId: permission.DestGroupId,
|
|
DestGroupOwnerAccount: permission.DestGroupOwnerAccount,
|
|
DestCidrIp: permission.DestCidrIp,
|
|
Policy: permission.Policy,
|
|
Priority: permission.Priority,
|
|
NicType: permission.NicType,
|
|
}
|
|
|
|
revokeSecurityGroupEgressArgs := &ecs.RevokeSecurityGroupEgressArgs{
|
|
AuthorizeSecurityGroupEgressArgs: authorizeSecurityGroupEgressArgs,
|
|
}
|
|
|
|
err := c.EcsClient().RevokeSecurityGroupEgress(revokeSecurityGroupEgressArgs)
|
|
if err != nil {
|
|
return fmt.Errorf("err deleting securityGroup Role:%v", err)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (d *clusterDiscoveryALI) ListRam() ([]*resources.Resource, error) {
|
|
var resourceTrackers []*resources.Resource
|
|
clusterName := strings.Replace(d.clusterName, ".", "-", -1)
|
|
names := []string{
|
|
"masters-" + clusterName,
|
|
"nodes-" + clusterName,
|
|
"bastions-" + clusterName,
|
|
}
|
|
|
|
response, err := d.aliCloud.RamClient().ListRoles()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("err listing RamRole:%v", err)
|
|
|
|
}
|
|
|
|
if len(response.Roles.Role) != 0 {
|
|
for _, role := range response.Roles.Role {
|
|
for _, roleName := range names {
|
|
if role.RoleName == roleName {
|
|
resourceTracker := &resources.Resource{
|
|
Name: role.RoleName,
|
|
ID: role.RoleId,
|
|
Type: typeRamRole,
|
|
Deleter: DeleteRoleRam,
|
|
}
|
|
resourceTrackers = append(resourceTrackers, resourceTracker)
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return resourceTrackers, nil
|
|
}
|
|
|
|
func DeleteRoleRam(cloud fi.Cloud, r *resources.Resource) error {
|
|
c := cloud.(aliup.ALICloud)
|
|
policies := []string{}
|
|
|
|
klog.V(2).Infof("Removing RamRole %s", r.Name)
|
|
|
|
roleQueryRequest := ram.RoleQueryRequest{
|
|
RoleName: r.Name,
|
|
}
|
|
response, err := c.RamClient().ListPoliciesForRole(roleQueryRequest)
|
|
if err != nil {
|
|
return fmt.Errorf("err listing Policies for role:%v", err)
|
|
}
|
|
if len(response.Policies.Policy) != 0 {
|
|
for _, policy := range response.Policies.Policy {
|
|
policies = append(policies, policy.PolicyName)
|
|
}
|
|
}
|
|
|
|
for _, policy := range policies {
|
|
klog.V(2).Infof("Removing RolePolicy %s of RamRole %s", policy, r.Name)
|
|
|
|
policyRequest := ram.PolicyRequest{
|
|
PolicyName: policy,
|
|
PolicyType: ram.Custom,
|
|
}
|
|
|
|
attachPolicyToRoleRequest := ram.AttachPolicyToRoleRequest{
|
|
PolicyRequest: policyRequest,
|
|
RoleName: r.Name,
|
|
}
|
|
_, err := c.RamClient().DetachPolicyFromRole(attachPolicyToRoleRequest)
|
|
if err != nil {
|
|
return fmt.Errorf("err detaching policy from role:%v", err)
|
|
}
|
|
|
|
_, err = c.RamClient().DeletePolicy(policyRequest)
|
|
if err != nil {
|
|
return fmt.Errorf("err deleting policy:%v", err)
|
|
}
|
|
}
|
|
|
|
_, err = c.RamClient().DeleteRole(roleQueryRequest)
|
|
if err != nil {
|
|
return fmt.Errorf("err deleting ram role:%v", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (d *clusterDiscoveryALI) ListSSHKey() ([]*resources.Resource, error) {
|
|
var resourceTrackers []*resources.Resource
|
|
name := "k8s.sshkey." + d.clusterName
|
|
|
|
resourceTracker := &resources.Resource{
|
|
Name: name,
|
|
ID: name,
|
|
Type: typeSSHKey,
|
|
Deleter: DeleteSSHKey,
|
|
}
|
|
|
|
resourceTrackers = append(resourceTrackers, resourceTracker)
|
|
return resourceTrackers, nil
|
|
}
|
|
|
|
func DeleteSSHKey(cloud fi.Cloud, r *resources.Resource) error {
|
|
c := cloud.(aliup.ALICloud)
|
|
region := common.Region(c.Region())
|
|
klog.V(2).Infof("Removing SSHKey %s", r.Name)
|
|
|
|
deleteKeyPairsArgs := &ecs.DeleteKeyPairsArgs{
|
|
RegionId: region,
|
|
}
|
|
keyPairs := []string{r.Name}
|
|
keyPairsJson, _ := json.Marshal(keyPairs)
|
|
deleteKeyPairsArgs.KeyPairNames = string(keyPairsJson)
|
|
|
|
err := c.EcsClient().DeleteKeyPairs(deleteKeyPairsArgs)
|
|
if err != nil {
|
|
return fmt.Errorf("err deleting sshkey pairs:%v", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (d *clusterDiscoveryALI) ListVPC() ([]*resources.Resource, error) {
|
|
var resourceTrackers []*resources.Resource
|
|
|
|
// Delete VPC with specified name. All of the Switches will be deleted.
|
|
// We think the VPC which owns the designated name is owned.
|
|
name := d.clusterName
|
|
vpcsToDelete := []string{}
|
|
vswitchsToDelete := []string{}
|
|
|
|
pageNumber := 1
|
|
pageSize := 50
|
|
for {
|
|
describeVpcsArgs := &ecs.DescribeVpcsArgs{
|
|
RegionId: common.Region(d.aliCloud.Region()),
|
|
Pagination: common.Pagination{
|
|
PageNumber: pageNumber,
|
|
PageSize: pageSize,
|
|
},
|
|
}
|
|
|
|
vpcs, _, err := d.aliCloud.EcsClient().DescribeVpcs(describeVpcsArgs)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("err listing VPC:%v", err)
|
|
}
|
|
|
|
if len(vpcs) != 0 {
|
|
for _, vpc := range vpcs {
|
|
if name == vpc.VpcName {
|
|
vpcsToDelete = append(vpcsToDelete, vpc.VpcId)
|
|
vswitchsToDelete = append(vswitchsToDelete, vpc.VSwitchIds.VSwitchId...)
|
|
}
|
|
}
|
|
}
|
|
if len(vpcs) < pageSize {
|
|
break
|
|
} else {
|
|
pageNumber++
|
|
}
|
|
}
|
|
|
|
if len(vpcsToDelete) > 1 {
|
|
klog.V(8).Infof("Found multiple vpcs with name %q", name)
|
|
} else if len(vpcsToDelete) == 1 {
|
|
vpcTracker := &resources.Resource{
|
|
Name: name,
|
|
ID: vpcsToDelete[0],
|
|
Type: typeVPC,
|
|
Deleter: DeleteVPC,
|
|
}
|
|
resourceTrackers = append(resourceTrackers, vpcTracker)
|
|
|
|
for _, vswitchId := range vswitchsToDelete {
|
|
|
|
resourceTracker := &resources.Resource{
|
|
Name: name,
|
|
ID: vswitchId,
|
|
Type: typeVswitch,
|
|
Deleter: DeleteVswitch,
|
|
}
|
|
resourceTracker.Blocks = append(resourceTracker.Blocks, typeVPC+":"+vpcTracker.ID)
|
|
|
|
//Waiting for all autoScalingGroups to be deleted.
|
|
for _, scalingGroupId := range d.scalingGroup {
|
|
resourceTracker.Blocked = append(resourceTracker.Blocked, typeScalingGroup+":"+scalingGroupId)
|
|
}
|
|
resourceTrackers = append(resourceTrackers, resourceTracker)
|
|
}
|
|
|
|
ListNatGateway(d, vpcsToDelete[0], &resourceTrackers)
|
|
}
|
|
|
|
return resourceTrackers, nil
|
|
}
|
|
|
|
func DeleteVswitch(cloud fi.Cloud, r *resources.Resource) error {
|
|
c := cloud.(aliup.ALICloud)
|
|
klog.V(2).Infof("Removing Vswitch with Id %s", r.ID)
|
|
|
|
err := c.EcsClient().DeleteVSwitch(r.ID)
|
|
if err != nil {
|
|
return fmt.Errorf("err deleting Vswitch:%v", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func DeleteVPC(cloud fi.Cloud, r *resources.Resource) error {
|
|
c := cloud.(aliup.ALICloud)
|
|
klog.V(2).Infof("Removing VPC with Id %s", r.ID)
|
|
|
|
err := c.EcsClient().DeleteVpc(r.ID)
|
|
if err != nil {
|
|
return fmt.Errorf("err deleting VPC:%v", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (d *clusterDiscoveryALI) ListVolume() ([]*resources.Resource, error) {
|
|
var resourceTrackers []*resources.Resource
|
|
// Volume has cluster tags
|
|
tags := make(map[string]string)
|
|
d.aliCloud.AddClusterTags(tags)
|
|
disksToDelete := []string{}
|
|
|
|
pageNumber := 1
|
|
pageSize := 50
|
|
for {
|
|
describeDisksArgs := &ecs.DescribeDisksArgs{
|
|
RegionId: common.Region(d.aliCloud.Region()),
|
|
Tag: tags,
|
|
DiskType: ecs.DiskTypeAllData,
|
|
Pagination: common.Pagination{
|
|
PageNumber: pageNumber,
|
|
PageSize: pageSize,
|
|
},
|
|
}
|
|
|
|
disks, _, err := d.aliCloud.EcsClient().DescribeDisks(describeDisksArgs)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("err listing disks:%v", err)
|
|
}
|
|
|
|
if len(disks) != 0 {
|
|
for _, disk := range disks {
|
|
disksToDelete = append(disksToDelete, disk.DiskId)
|
|
}
|
|
}
|
|
if len(disks) < pageSize {
|
|
break
|
|
} else {
|
|
pageNumber++
|
|
}
|
|
}
|
|
|
|
if len(disksToDelete) == 0 {
|
|
klog.V(8).Infof("Found no disks to delete")
|
|
} else {
|
|
for _, disk := range disksToDelete {
|
|
|
|
resourceTracker := &resources.Resource{
|
|
Name: disk,
|
|
ID: disk,
|
|
Type: typeVolume,
|
|
Deleter: DeleteVolume,
|
|
}
|
|
resourceTrackers = append(resourceTrackers, resourceTracker)
|
|
}
|
|
}
|
|
|
|
return resourceTrackers, nil
|
|
|
|
}
|
|
|
|
func DeleteVolume(cloud fi.Cloud, r *resources.Resource) error {
|
|
c := cloud.(aliup.ALICloud)
|
|
klog.V(2).Infof("Removing Disk with Id %s", r.ID)
|
|
|
|
err := c.EcsClient().DeleteDisk(r.ID)
|
|
if err != nil {
|
|
return fmt.Errorf("err deleting volume:%v", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func ListNatGateway(d *clusterDiscoveryALI, vpcID string, resourceTrackers *[]*resources.Resource) error {
|
|
|
|
// Delete NateGateway with specified name. All of the EIPs will be deleted.
|
|
// We think the NateGateway which owns the designated name is owned.
|
|
natGatewaysToDelete := []string{}
|
|
eipToDelete := []string{}
|
|
|
|
name := d.clusterName
|
|
pageNumber := 1
|
|
pageSize := 50
|
|
for {
|
|
describeNatGatewaysArgs := &ecs.DescribeNatGatewaysArgs{
|
|
RegionId: common.Region(d.aliCloud.Region()),
|
|
VpcId: vpcID,
|
|
Pagination: common.Pagination{
|
|
PageNumber: pageNumber,
|
|
PageSize: pageSize,
|
|
},
|
|
}
|
|
|
|
natGateways, _, err := d.aliCloud.VpcClient().DescribeNatGateways(describeNatGatewaysArgs)
|
|
if err != nil {
|
|
return fmt.Errorf("err listing NatGateway:%v", err)
|
|
}
|
|
|
|
if len(natGateways) != 0 {
|
|
for _, nateGateway := range natGateways {
|
|
natGatewaysToDelete = append(natGatewaysToDelete, nateGateway.NatGatewayId)
|
|
for _, ip := range nateGateway.IpLists.IpList {
|
|
eipToDelete = append(eipToDelete, ip.AllocationId)
|
|
}
|
|
}
|
|
}
|
|
if len(natGateways) < pageSize {
|
|
break
|
|
} else {
|
|
pageNumber++
|
|
}
|
|
}
|
|
|
|
if len(natGatewaysToDelete) > 1 {
|
|
klog.V(8).Infof("Found multiple natGateways with name %q", name)
|
|
} else if len(natGatewaysToDelete) == 1 {
|
|
natGatwayTracker := &resources.Resource{
|
|
Name: name,
|
|
ID: natGatewaysToDelete[0],
|
|
Type: typeNatGateway,
|
|
Deleter: DeleteNatGateway,
|
|
}
|
|
*resourceTrackers = append(*resourceTrackers, natGatwayTracker)
|
|
natGatwayTracker.Blocks = append(natGatwayTracker.Blocks, typeVPC+":"+vpcID)
|
|
for _, eip := range eipToDelete {
|
|
|
|
resourceTracker := &resources.Resource{
|
|
Name: name,
|
|
ID: eip,
|
|
Type: typeEIP,
|
|
Deleter: DeleteEIP,
|
|
}
|
|
resourceTracker.Blocked = append(resourceTracker.Blocked, typeNatGateway+":"+natGatwayTracker.ID)
|
|
*resourceTrackers = append(*resourceTrackers, resourceTracker)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func DeleteNatGateway(cloud fi.Cloud, r *resources.Resource) error {
|
|
c := cloud.(aliup.ALICloud)
|
|
|
|
describeNatGatewaysArgs := &ecs.DescribeNatGatewaysArgs{
|
|
RegionId: common.Region(c.Region()),
|
|
NatGatewayId: r.ID,
|
|
}
|
|
|
|
natGateways, _, err := c.VpcClient().DescribeNatGateways(describeNatGatewaysArgs)
|
|
if err != nil {
|
|
return fmt.Errorf("err listing NatGateway:%v", err)
|
|
}
|
|
|
|
if len(natGateways) > 1 {
|
|
klog.V(8).Infof("Found multiple natGateways with ID %q", r.ID)
|
|
} else if len(natGateways) == 1 {
|
|
for _, snatTableId := range natGateways[0].SnatTableIds.SnatTableId {
|
|
describeSnatTableEntriesArgs := &ecs.DescribeSnatTableEntriesArgs{
|
|
RegionId: common.Region(c.Region()),
|
|
SnatTableId: snatTableId,
|
|
}
|
|
snatTableEntries, _, err := c.VpcClient().DescribeSnatTableEntries(describeSnatTableEntriesArgs)
|
|
if err != nil {
|
|
return fmt.Errorf("err Listing snatTableEntries:%v", err)
|
|
}
|
|
for _, snatTableEntry := range snatTableEntries {
|
|
deleteSnatEntryArgs := &ecs.DeleteSnatEntryArgs{
|
|
RegionId: common.Region(c.Region()),
|
|
SnatTableId: snatTableId,
|
|
SnatEntryId: snatTableEntry.SnatEntryId,
|
|
}
|
|
err := c.VpcClient().DeleteSnatEntry(deleteSnatEntryArgs)
|
|
if err != nil {
|
|
return fmt.Errorf("err deleting SnatEntryArgs:%v", err)
|
|
}
|
|
}
|
|
}
|
|
for _, ip := range natGateways[0].IpLists.IpList {
|
|
err := c.VpcClient().UnassociateEipAddress(ip.AllocationId, r.ID)
|
|
if err != nil {
|
|
return fmt.Errorf("err unassociating EIP:%v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
klog.V(2).Infof("Removing NatGateway with Id %s", r.ID)
|
|
deleteNatGatewayArgs := &ecs.DeleteNatGatewayArgs{
|
|
RegionId: common.Region(c.Region()),
|
|
NatGatewayId: r.ID,
|
|
}
|
|
err = c.EcsClient().DeleteNatGateway(deleteNatGatewayArgs)
|
|
if err != nil {
|
|
return fmt.Errorf("err deleting NatGateway:%v", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func DeleteEIP(cloud fi.Cloud, r *resources.Resource) error {
|
|
c := cloud.(aliup.ALICloud)
|
|
klog.V(2).Infof("Removing EIP with Id %s", r.ID)
|
|
|
|
err := c.VpcClient().ReleaseEipAddress(r.ID)
|
|
if err != nil {
|
|
return fmt.Errorf("err deleting EIP:%v", err)
|
|
}
|
|
return nil
|
|
}
|