github.com/alibaba/sealer@v0.8.6-0.20220430115802-37a2bdaa8173/pkg/infra/aliyun/ali_provider.go (about)

     1  // Copyright © 2021 Alibaba Group Holding Ltd.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package aliyun
    16  
    17  import (
    18  	"strings"
    19  	"time"
    20  
    21  	"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
    22  	"github.com/aliyun/alibaba-cloud-sdk-go/services/vpc"
    23  
    24  	"github.com/alibaba/sealer/logger"
    25  	v1 "github.com/alibaba/sealer/types/api/v1"
    26  	"github.com/alibaba/sealer/utils"
    27  )
    28  
    29  type ActionName string
    30  
    31  const (
    32  	CreateVPC           ActionName = "CreateVPC"
    33  	CreateVSwitch       ActionName = "CreateVSwitch"
    34  	CreateSecurityGroup ActionName = "CreateSecurityGroup"
    35  	ReconcileInstance   ActionName = "ReconcileInstance"
    36  	BindEIP             ActionName = "BindEIP"
    37  	ReleaseEIP          ActionName = "ReleaseEIP"
    38  	ClearInstances      ActionName = "ClearInstances"
    39  	DeleteVSwitch       ActionName = "DeleteVSwitch"
    40  	DeleteSecurityGroup ActionName = "DeleteSecurityGroup"
    41  	DeleteVPC           ActionName = "DeleteVPC"
    42  	GetZoneID           ActionName = "GetZoneID"
    43  )
    44  
    45  type AliProvider struct {
    46  	Config    Config
    47  	EcsClient ecs.Client
    48  	VpcClient vpc.Client
    49  	Cluster   *v1.Cluster
    50  }
    51  
    52  type Config struct {
    53  	AccessKey    string
    54  	AccessSecret string
    55  	RegionID     string
    56  }
    57  
    58  type Alifunc func() error
    59  
    60  const (
    61  	Scheme                     = "https"
    62  	IPProtocol                 = "tcp"
    63  	APIServerPortRange         = "6443/6443"
    64  	SSHPortRange               = "22/22"
    65  	SourceCidrIP               = "0.0.0.0/0"
    66  	CidrBlock                  = "172.16.0.0/24"
    67  	Policy                     = "accept"
    68  	DestinationResource        = "InstanceType"
    69  	InstanceChargeType         = "PostPaid"
    70  	InternetChargeType         = "PayByTraffic"
    71  	ImageID                    = "centos_7_9_x64_20G_alibase_20210927.vhd"
    72  	AccessKey                  = "ACCESSKEYID"
    73  	AccessSecret               = "ACCESSKEYSECRET"
    74  	Product                    = "product"
    75  	Role                       = "role"
    76  	Master                     = "master"
    77  	Node                       = "node"
    78  	Stopped                    = "Stopped"
    79  	AvailableTypeStatus        = "WithStock"
    80  	Bandwidth                  = "100"
    81  	Digits                     = "0123456789"
    82  	Specials                   = "~=+%^*/()[]{}/!@#$?|"
    83  	Letter                     = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
    84  	PasswordLength             = 16
    85  	DataCategory               = "cloud_ssd"
    86  	AliDomain                  = "sea.aliyun.com/"
    87  	AliCloud                   = "ALI_CLOUD"
    88  	EipID                      = AliDomain + "EipID"
    89  	Master0ID                  = AliDomain + "Master0ID"
    90  	Master0InternalIP          = AliDomain + "Master0InternalIP"
    91  	VpcID                      = AliDomain + "VpcID"
    92  	VSwitchID                  = AliDomain + "VSwitchID"
    93  	SecurityGroupID            = AliDomain + "SecurityGroupID"
    94  	Eip                        = AliDomain + "ClusterEIP"
    95  	ZoneID                     = AliDomain + "ZoneID"
    96  	RegionID                   = "RegionID"
    97  	AliRegionID                = AliDomain + RegionID
    98  	AliMasterIDs               = AliDomain + "MasterIDs"
    99  	AliNodeIDs                 = AliDomain + "NodeIDs"
   100  	DefaultRegionID            = "cn-chengdu"
   101  	AliCloudEssd               = "cloud_essd"
   102  	TryTimes                   = 10
   103  	TrySleepTime               = time.Second
   104  	JustGetInstanceInfo        = ""
   105  	ShouldBeDeleteInstancesIDs = "ShouldBeDeleteInstancesIDs"
   106  )
   107  
   108  func (a *AliProvider) ReconcileResource(resourceKey string, action Alifunc) error {
   109  	if a.Cluster.Annotations[resourceKey] == "" {
   110  		err := action()
   111  		if err != nil {
   112  			return err
   113  		}
   114  		logger.Info("create resource success %s: %s", resourceKey, a.Cluster.Annotations[resourceKey])
   115  		return utils.SaveClusterInfoToFile(a.Cluster, a.Cluster.Name)
   116  	}
   117  	return nil
   118  }
   119  
   120  func (a *AliProvider) DeleteResource(resourceKey string, action Alifunc) {
   121  	if a.Cluster.Annotations[resourceKey] != "" {
   122  		err := action()
   123  		if err != nil {
   124  			logger.Error("delete resource %s failed err: %s", resourceKey, err)
   125  		} else {
   126  			logger.Info("delete resource Success %s", a.Cluster.Annotations[resourceKey])
   127  		}
   128  	}
   129  }
   130  
   131  var RecocileFuncMap = map[ActionName]func(provider *AliProvider) error{
   132  	CreateVPC: func(aliProvider *AliProvider) error {
   133  		return aliProvider.ReconcileResource(VpcID, aliProvider.CreateVPC)
   134  	},
   135  
   136  	CreateVSwitch: func(aliProvider *AliProvider) error {
   137  		return aliProvider.ReconcileResource(VSwitchID, aliProvider.CreateVSwitch)
   138  	},
   139  	CreateSecurityGroup: func(aliProvider *AliProvider) error {
   140  		return aliProvider.ReconcileResource(SecurityGroupID, aliProvider.CreateSecurityGroup)
   141  	},
   142  	ReconcileInstance: func(aliProvider *AliProvider) error {
   143  		err := aliProvider.ReconcileInstances(Master)
   144  		if err != nil {
   145  			return err
   146  		}
   147  
   148  		err = aliProvider.ReconcileInstances(Node)
   149  		if err != nil {
   150  			return err
   151  		}
   152  		return nil
   153  	},
   154  	GetZoneID: func(aliProvider *AliProvider) error {
   155  		return aliProvider.ReconcileResource(ZoneID, aliProvider.GetZoneID)
   156  	},
   157  	BindEIP: func(aliProvider *AliProvider) error {
   158  		return aliProvider.ReconcileResource(EipID, aliProvider.BindEipForMaster0)
   159  	},
   160  }
   161  
   162  var DeleteFuncMap = map[ActionName]func(provider *AliProvider){
   163  	ReleaseEIP: func(aliProvider *AliProvider) {
   164  		aliProvider.DeleteResource(EipID, aliProvider.ReleaseEipAddress)
   165  	},
   166  	ClearInstances: func(aliProvider *AliProvider) {
   167  		var instanceIDs []string
   168  		roles := []string{Master, Node}
   169  		for _, role := range roles {
   170  			instances, err := aliProvider.GetInstancesInfo(role, JustGetInstanceInfo)
   171  			if err != nil {
   172  				logger.Error("get %s instanceinfo failed %v", role, err)
   173  			}
   174  			for _, instance := range instances {
   175  				instanceIDs = append(instanceIDs, instance.InstanceID)
   176  			}
   177  		}
   178  		if len(instanceIDs) != 0 {
   179  			aliProvider.Cluster.Annotations[ShouldBeDeleteInstancesIDs] = strings.Join(instanceIDs, ",")
   180  		}
   181  		aliProvider.DeleteResource(ShouldBeDeleteInstancesIDs, aliProvider.DeleteInstances)
   182  	},
   183  	DeleteVSwitch: func(aliProvider *AliProvider) {
   184  		aliProvider.DeleteResource(VSwitchID, aliProvider.DeleteVSwitch)
   185  	},
   186  	DeleteSecurityGroup: func(aliProvider *AliProvider) {
   187  		aliProvider.DeleteResource(SecurityGroupID, aliProvider.DeleteSecurityGroup)
   188  	},
   189  	DeleteVPC: func(aliProvider *AliProvider) {
   190  		aliProvider.DeleteResource(VpcID, aliProvider.DeleteVPC)
   191  	},
   192  }
   193  
   194  func (a *AliProvider) NewClient() error {
   195  	ecsClient, err := ecs.NewClientWithAccessKey(a.Config.RegionID, a.Config.AccessKey, a.Config.AccessSecret)
   196  	if err != nil {
   197  		return err
   198  	}
   199  	vpcClient, err := vpc.NewClientWithAccessKey(a.Config.RegionID, a.Config.AccessKey, a.Config.AccessSecret)
   200  	if err != nil {
   201  		return err
   202  	}
   203  	a.EcsClient = *ecsClient
   204  	a.VpcClient = *vpcClient
   205  	return nil
   206  }
   207  
   208  func (a *AliProvider) ClearCluster() {
   209  	todolist := []ActionName{
   210  		ReleaseEIP,
   211  		ClearInstances,
   212  		DeleteVSwitch,
   213  		DeleteSecurityGroup,
   214  		DeleteVPC,
   215  	}
   216  	for _, name := range todolist {
   217  		DeleteFuncMap[name](a)
   218  	}
   219  }
   220  
   221  func (a *AliProvider) Reconcile() error {
   222  	if a.Cluster.Annotations == nil {
   223  		a.Cluster.Annotations = make(map[string]string)
   224  	}
   225  	if a.Cluster.DeletionTimestamp != nil {
   226  		logger.Info("DeletionTimestamp not nil Clear Cluster")
   227  		a.ClearCluster()
   228  		return nil
   229  	}
   230  	if a.Cluster.Spec.SSH.Passwd == "" {
   231  		// Create ssh password
   232  		a.CreatePassword()
   233  	}
   234  	todolist := []ActionName{
   235  		CreateVPC,
   236  		GetZoneID,
   237  		CreateVSwitch,
   238  		CreateSecurityGroup,
   239  		ReconcileInstance,
   240  		BindEIP,
   241  	}
   242  
   243  	for _, actionname := range todolist {
   244  		err := RecocileFuncMap[actionname](a)
   245  		if err != nil {
   246  			return err
   247  		}
   248  	}
   249  
   250  	return nil
   251  }
   252  
   253  func (a *AliProvider) Apply() error {
   254  	return a.Reconcile()
   255  }