github.com/sealerio/sealer@v0.11.1-0.20240507115618-f4f89c5853ae/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 "fmt" 19 "os" 20 "path/filepath" 21 "strings" 22 "time" 23 24 "github.com/sealerio/sealer/common" 25 "github.com/sealerio/sealer/utils/yaml" 26 27 "github.com/aliyun/alibaba-cloud-sdk-go/services/ecs" 28 "github.com/aliyun/alibaba-cloud-sdk-go/services/vpc" 29 "github.com/sirupsen/logrus" 30 31 v1 "github.com/sealerio/sealer/types/api/v1" 32 ) 33 34 type ActionName string 35 36 const ( 37 CreateVPC ActionName = "CreateVPC" 38 CreateVSwitch ActionName = "CreateVSwitch" 39 CreateSecurityGroup ActionName = "CreateSecurityGroup" 40 ReconcileInstance ActionName = "ReconcileInstance" 41 BindEIP ActionName = "BindEIP" 42 ReleaseEIP ActionName = "ReleaseEIP" 43 ClearInstances ActionName = "ClearInstances" 44 DeleteVSwitch ActionName = "DeleteVSwitch" 45 DeleteSecurityGroup ActionName = "DeleteSecurityGroup" 46 DeleteVPC ActionName = "DeleteVPC" 47 GetZoneID ActionName = "GetZoneID" 48 ) 49 50 type AliProvider struct { 51 Config Config 52 EcsClient ecs.Client 53 VpcClient vpc.Client 54 Cluster *v1.Cluster 55 } 56 57 type Config struct { 58 AccessKey string 59 AccessSecret string 60 RegionID string 61 } 62 63 type Alifunc func() error 64 65 const ( 66 Scheme = "https" 67 IPProtocol = "tcp" 68 APIServerPortRange = "6443/6443" 69 SSHPortRange = "22/22" 70 SourceCidrIP = "0.0.0.0/0" 71 CidrBlock = "172.16.0.0/24" 72 Policy = "accept" 73 DestinationResource = "InstanceType" 74 InstanceChargeType = "PostPaid" 75 InternetChargeType = "PayByTraffic" 76 ImageID = "centos_7_9_x64_20G_alibase_20210927.vhd" 77 AccessKey = "ACCESSKEYID" 78 AccessSecret = "ACCESSKEYSECRET" 79 Product = "product" 80 Role = "role" 81 Master = "master" 82 Node = "node" 83 Stopped = "Stopped" 84 AvailableTypeStatus = "WithStock" 85 Bandwidth = "100" 86 Digits = "0123456789" 87 Specials = "~=+%^*/()[]{}/!@#$?|" 88 Letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" 89 PasswordLength = 16 90 DataCategory = "cloud_ssd" 91 AliDomain = "sea.aliyun.com/" 92 AliCloud = "ALI_CLOUD" 93 EipID = AliDomain + "EipID" 94 Master0ID = AliDomain + "Master0ID" 95 Master0InternalIP = AliDomain + "Master0InternalIP" 96 VpcID = AliDomain + "VpcID" 97 VSwitchID = AliDomain + "VSwitchID" 98 SecurityGroupID = AliDomain + "SecurityGroupID" 99 Eip = AliDomain + "ClusterEIP" 100 ZoneID = AliDomain + "ZoneID" 101 RegionID = "RegionID" 102 AliRegionID = AliDomain + RegionID 103 AliMasterIDs = AliDomain + "MasterIDs" 104 AliNodeIDs = AliDomain + "NodeIDs" 105 DefaultRegionID = "cn-chengdu" 106 AliCloudEssd = "cloud_essd" 107 TryTimes = 10 108 TrySleepTime = time.Second 109 JustGetInstanceInfo = "" 110 ShouldBeDeleteInstancesIDs = "ShouldBeDeleteInstancesIDs" 111 ) 112 113 func (a *AliProvider) ReconcileResource(resourceKey string, action Alifunc) error { 114 if a.Cluster.Annotations[resourceKey] == "" { 115 err := action() 116 if err != nil { 117 return err 118 } 119 logrus.Infof("create resource success %s: %s", resourceKey, a.Cluster.Annotations[resourceKey]) 120 return a.SaveToDisk() 121 } 122 return nil 123 } 124 125 func (a *AliProvider) SaveToDisk() error { 126 fileName := common.GetDefaultClusterfile() 127 err := os.MkdirAll(filepath.Dir(fileName), os.ModePerm) 128 if err != nil { 129 return fmt.Errorf("mkdir failed %s %v", fileName, err) 130 } 131 132 return yaml.MarshalToFile(fileName, a.Cluster) 133 } 134 135 func (a *AliProvider) DeleteResource(resourceKey string, action Alifunc) { 136 if a.Cluster.Annotations[resourceKey] != "" { 137 err := action() 138 if err != nil { 139 logrus.Errorf("delete resource %s failed err: %s", resourceKey, err) 140 } else { 141 logrus.Infof("delete resource Success %s", a.Cluster.Annotations[resourceKey]) 142 } 143 } 144 } 145 146 var RecocileFuncMap = map[ActionName]func(provider *AliProvider) error{ 147 CreateVPC: func(aliProvider *AliProvider) error { 148 return aliProvider.ReconcileResource(VpcID, aliProvider.CreateVPC) 149 }, 150 151 CreateVSwitch: func(aliProvider *AliProvider) error { 152 return aliProvider.ReconcileResource(VSwitchID, aliProvider.CreateVSwitch) 153 }, 154 CreateSecurityGroup: func(aliProvider *AliProvider) error { 155 return aliProvider.ReconcileResource(SecurityGroupID, aliProvider.CreateSecurityGroup) 156 }, 157 ReconcileInstance: func(aliProvider *AliProvider) error { 158 err := aliProvider.ReconcileInstances(Master) 159 if err != nil { 160 return err 161 } 162 163 err = aliProvider.ReconcileInstances(Node) 164 if err != nil { 165 return err 166 } 167 return nil 168 }, 169 GetZoneID: func(aliProvider *AliProvider) error { 170 return aliProvider.ReconcileResource(ZoneID, aliProvider.GetZoneID) 171 }, 172 BindEIP: func(aliProvider *AliProvider) error { 173 return aliProvider.ReconcileResource(EipID, aliProvider.BindEipForMaster0) 174 }, 175 } 176 177 var DeleteFuncMap = map[ActionName]func(provider *AliProvider){ 178 ReleaseEIP: func(aliProvider *AliProvider) { 179 aliProvider.DeleteResource(EipID, aliProvider.ReleaseEipAddress) 180 }, 181 ClearInstances: func(aliProvider *AliProvider) { 182 var instanceIDs []string 183 roles := []string{Master, Node} 184 for _, role := range roles { 185 instances, err := aliProvider.GetInstancesInfo(role, JustGetInstanceInfo) 186 if err != nil { 187 logrus.Errorf("get %s instanceinfo failed %v", role, err) 188 } 189 for _, instance := range instances { 190 instanceIDs = append(instanceIDs, instance.InstanceID) 191 } 192 } 193 if len(instanceIDs) != 0 { 194 aliProvider.Cluster.Annotations[ShouldBeDeleteInstancesIDs] = strings.Join(instanceIDs, ",") 195 } 196 aliProvider.DeleteResource(ShouldBeDeleteInstancesIDs, aliProvider.DeleteInstances) 197 }, 198 DeleteVSwitch: func(aliProvider *AliProvider) { 199 aliProvider.DeleteResource(VSwitchID, aliProvider.DeleteVSwitch) 200 }, 201 DeleteSecurityGroup: func(aliProvider *AliProvider) { 202 aliProvider.DeleteResource(SecurityGroupID, aliProvider.DeleteSecurityGroup) 203 }, 204 DeleteVPC: func(aliProvider *AliProvider) { 205 aliProvider.DeleteResource(VpcID, aliProvider.DeleteVPC) 206 }, 207 } 208 209 func (a *AliProvider) NewClient() error { 210 ecsClient, err := ecs.NewClientWithAccessKey(a.Config.RegionID, a.Config.AccessKey, a.Config.AccessSecret) 211 if err != nil { 212 return err 213 } 214 vpcClient, err := vpc.NewClientWithAccessKey(a.Config.RegionID, a.Config.AccessKey, a.Config.AccessSecret) 215 if err != nil { 216 return err 217 } 218 a.EcsClient = *ecsClient 219 a.VpcClient = *vpcClient 220 return nil 221 } 222 223 func (a *AliProvider) ClearCluster() { 224 todolist := []ActionName{ 225 ReleaseEIP, 226 ClearInstances, 227 DeleteVSwitch, 228 DeleteSecurityGroup, 229 DeleteVPC, 230 } 231 for _, name := range todolist { 232 DeleteFuncMap[name](a) 233 } 234 } 235 236 func (a *AliProvider) Reconcile() error { 237 if a.Cluster.Annotations == nil { 238 a.Cluster.Annotations = make(map[string]string) 239 } 240 if a.Cluster.DeletionTimestamp != nil { 241 logrus.Info("DeletionTimestamp not nil Clear Cluster") 242 a.ClearCluster() 243 return nil 244 } 245 if a.Cluster.Spec.SSH.Passwd == "" { 246 // Create ssh password 247 a.CreatePassword() 248 } 249 todolist := []ActionName{ 250 CreateVPC, 251 GetZoneID, 252 CreateVSwitch, 253 CreateSecurityGroup, 254 ReconcileInstance, 255 BindEIP, 256 } 257 258 for _, actionname := range todolist { 259 err := RecocileFuncMap[actionname](a) 260 if err != nil { 261 return err 262 } 263 } 264 265 return nil 266 } 267 268 func (a *AliProvider) Apply() error { 269 return a.Reconcile() 270 }