From f5acabd6cd11c4008ee6f14d12d6385976845e93 Mon Sep 17 00:00:00 2001 From: LilyFaFa <21621231@zju.edu.cn> Date: Mon, 18 Jun 2018 10:18:14 +0800 Subject: [PATCH] implement scalingGroup tasks for AliCloud --- Gopkg.lock | 3 +- upup/pkg/fi/cloudup/alitasks/BUILD.bazel | 5 + .../cloudup/alitasks/launchconfiguration.go | 272 ++++++++++++++ .../alitasks/launchconfiguration_fitask.go | 75 ++++ upup/pkg/fi/cloudup/alitasks/scalinggroup.go | 208 +++++++++++ .../cloudup/alitasks/scalinggroup_fitask.go | 75 ++++ upup/pkg/fi/cloudup/aliup/BUILD.bazel | 1 + upup/pkg/fi/cloudup/aliup/ali_cloud.go | 8 + .../denverdino/aliyungo/ess/BUILD.bazel | 19 + .../denverdino/aliyungo/ess/client.go | 48 +++ .../denverdino/aliyungo/ess/configuration.go | 168 +++++++++ .../denverdino/aliyungo/ess/group.go | 339 ++++++++++++++++++ .../denverdino/aliyungo/ess/rule.go | 152 ++++++++ .../denverdino/aliyungo/ess/schedule.go | 140 ++++++++ 14 files changed, 1512 insertions(+), 1 deletion(-) create mode 100644 upup/pkg/fi/cloudup/alitasks/launchconfiguration.go create mode 100644 upup/pkg/fi/cloudup/alitasks/launchconfiguration_fitask.go create mode 100644 upup/pkg/fi/cloudup/alitasks/scalinggroup.go create mode 100644 upup/pkg/fi/cloudup/alitasks/scalinggroup_fitask.go create mode 100644 vendor/github.com/denverdino/aliyungo/ess/BUILD.bazel create mode 100644 vendor/github.com/denverdino/aliyungo/ess/client.go create mode 100644 vendor/github.com/denverdino/aliyungo/ess/configuration.go create mode 100644 vendor/github.com/denverdino/aliyungo/ess/group.go create mode 100644 vendor/github.com/denverdino/aliyungo/ess/rule.go create mode 100644 vendor/github.com/denverdino/aliyungo/ess/schedule.go diff --git a/Gopkg.lock b/Gopkg.lock index e6da649280..8db91ee40f 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -227,6 +227,7 @@ packages = [ "common", "ecs", + "ess", "oss", "ram", "slb", @@ -1712,6 +1713,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "466d4f729f9b42c133774b443359841aa56e918db97a9adf33e609df9be4cee9" + inputs-digest = "1debbbe03ce960a107f0c1d9a965dd32e6e3bb6cc75b07d3cd52cb5527ead016" solver-name = "gps-cdcl" solver-version = 1 diff --git a/upup/pkg/fi/cloudup/alitasks/BUILD.bazel b/upup/pkg/fi/cloudup/alitasks/BUILD.bazel index c50568371b..12bedd92d2 100644 --- a/upup/pkg/fi/cloudup/alitasks/BUILD.bazel +++ b/upup/pkg/fi/cloudup/alitasks/BUILD.bazel @@ -5,6 +5,8 @@ go_library( srcs = [ "disk.go", "disk_fitask.go", + "launchconfiguration.go", + "launchconfiguration_fitask.go", "loadbalancer.go", "loadbalancer_fitask.go", "loadbalancerlistener.go", @@ -15,6 +17,8 @@ go_library( "rampolicy_fitask.go", "ramrole.go", "ramrole_fitask.go", + "scalinggroup.go", + "scalinggroup_fitask.go", "securitygroup.go", "securitygroup_fitask.go", "securitygrouprule.go", @@ -34,6 +38,7 @@ go_library( "//upup/pkg/fi/cloudup/terraform:go_default_library", "//vendor/github.com/denverdino/aliyungo/common:go_default_library", "//vendor/github.com/denverdino/aliyungo/ecs:go_default_library", + "//vendor/github.com/denverdino/aliyungo/ess:go_default_library", "//vendor/github.com/denverdino/aliyungo/ram:go_default_library", "//vendor/github.com/denverdino/aliyungo/slb:go_default_library", "//vendor/github.com/golang/glog:go_default_library", diff --git a/upup/pkg/fi/cloudup/alitasks/launchconfiguration.go b/upup/pkg/fi/cloudup/alitasks/launchconfiguration.go new file mode 100644 index 0000000000..6ac792a374 --- /dev/null +++ b/upup/pkg/fi/cloudup/alitasks/launchconfiguration.go @@ -0,0 +1,272 @@ +/* +Copyright 2018 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 alitasks + +import ( + "encoding/base64" + "encoding/json" + "fmt" + "strconv" + + "github.com/denverdino/aliyungo/common" + "github.com/denverdino/aliyungo/ess" + "github.com/golang/glog" + + "k8s.io/kops/upup/pkg/fi" + "k8s.io/kops/upup/pkg/fi/cloudup/aliup" + "k8s.io/kops/upup/pkg/fi/cloudup/terraform" +) + +//go:generate fitask -type=LaunchConfiguration + +type LaunchConfiguration struct { + Lifecycle *fi.Lifecycle + Name *string + ConfigurationId *string + + ImageId *string + InstanceType *string + SystemDiskSize *int + SystemDiskCategory *string + + RAMRole *RAMRole + ScalingGroup *ScalingGroup + SSHKey *SSHKey + UserData *fi.ResourceHolder + SecurityGroup *SecurityGroup + + Tags map[string]string +} + +var _ fi.CompareWithID = &LaunchConfiguration{} + +func (l *LaunchConfiguration) CompareWithID() *string { + return l.ConfigurationId +} + +func (l *LaunchConfiguration) Find(c *fi.Context) (*LaunchConfiguration, error) { + + if l.ScalingGroup == nil || l.ScalingGroup.ScalingGroupId == nil { + glog.V(4).Infof("ScalingGroup / ScalingGroupId not found for %s, skipping Find", fi.StringValue(l.Name)) + return nil, nil + } + + cloud := c.Cloud.(aliup.ALICloud) + + describeScalingConfigurationsArgs := &ess.DescribeScalingConfigurationsArgs{ + RegionId: common.Region(cloud.Region()), + ScalingConfigurationName: common.FlattenArray{fi.StringValue(l.Name)}, + ScalingGroupId: fi.StringValue(l.ScalingGroup.ScalingGroupId), + } + + if l.ScalingGroup != nil && l.ScalingGroup.ScalingGroupId != nil { + describeScalingConfigurationsArgs.ScalingGroupId = fi.StringValue(l.ScalingGroup.ScalingGroupId) + } + + configList, _, err := cloud.EssClient().DescribeScalingConfigurations(describeScalingConfigurationsArgs) + if err != nil { + return nil, fmt.Errorf("error finding ScalingConfigurations: %v", err) + } + // Don't exist ScalingConfigurations with specified Name. + if len(configList) == 0 { + return nil, nil + } + if len(configList) > 1 { + glog.V(4).Info("The number of specified ScalingConfigurations with the same name and ScalingGroupId exceeds 1, diskName:%q", *l.Name) + } + + glog.V(2).Infof("found matching LaunchConfiguration: %q", *l.Name) + + actual := &LaunchConfiguration{} + actual.ImageId = fi.String(configList[0].ImageId) + actual.InstanceType = fi.String(configList[0].InstanceType) + actual.SystemDiskCategory = fi.String(string(configList[0].SystemDiskCategory)) + actual.ConfigurationId = fi.String(configList[0].ScalingConfigurationId) + actual.Name = fi.String(configList[0].ScalingConfigurationName) + + if configList[0].KeyPairName != "" { + actual.SSHKey = &SSHKey{ + Name: fi.String(configList[0].KeyPairName), + } + } + + if configList[0].RamRoleName != "" { + actual.RAMRole = &RAMRole{ + Name: fi.String(configList[0].RamRoleName), + } + } + + if configList[0].UserData != "" { + userData, err := base64.StdEncoding.DecodeString(configList[0].UserData) + if err != nil { + return nil, fmt.Errorf("error decoding UserData: %v", err) + } + actual.UserData = fi.WrapResource(fi.NewStringResource(string(userData))) + } + + actual.ScalingGroup = &ScalingGroup{ + ScalingGroupId: fi.String(configList[0].ScalingGroupId), + } + actual.SecurityGroup = &SecurityGroup{ + SecurityGroupId: fi.String(configList[0].SecurityGroupId), + } + + if len(configList[0].Tags.Tag) != 0 { + for _, tag := range configList[0].Tags.Tag { + actual.Tags[tag.Key] = tag.Value + } + } + + // Ignore "system" fields + actual.Lifecycle = l.Lifecycle + return actual, nil +} + +func (l *LaunchConfiguration) Run(c *fi.Context) error { + c.Cloud.(aliup.ALICloud).AddClusterTags(l.Tags) + return fi.DefaultDeltaRunMethod(l, c) +} + +func (_ *LaunchConfiguration) CheckChanges(a, e, changes *LaunchConfiguration) error { + //Configuration can not be modified, we need to create a new one + + if e.Name == nil { + return fi.RequiredField("Name") + } + + if e.ImageId == nil { + return fi.RequiredField("ImageId") + } + if e.InstanceType == nil { + return fi.RequiredField("InstanceType") + } + + return nil +} + +func (_ *LaunchConfiguration) RenderALI(t *aliup.ALIAPITarget, a, e, changes *LaunchConfiguration) error { + + glog.V(2).Infof("Creating LaunchConfiguration for ScalingGroup:%q", fi.StringValue(e.ScalingGroup.ScalingGroupId)) + + createScalingConfiguration := &ess.CreateScalingConfigurationArgs{ + ScalingGroupId: fi.StringValue(e.ScalingGroup.ScalingGroupId), + ImageId: fi.StringValue(e.ImageId), + InstanceType: fi.StringValue(e.InstanceType), + SecurityGroupId: fi.StringValue(e.SecurityGroup.SecurityGroupId), + SystemDisk_Size: common.UnderlineString(strconv.Itoa(fi.IntValue(e.SystemDiskSize))), + SystemDisk_Category: common.UnderlineString(fi.StringValue(e.SystemDiskCategory)), + } + + if e.RAMRole != nil && e.RAMRole.Name != nil { + createScalingConfiguration.RamRoleName = fi.StringValue(e.RAMRole.Name) + } + + if e.UserData != nil { + userData, err := e.UserData.AsString() + if err != nil { + return fmt.Errorf("error rendering ScalingLaunchConfiguration UserData: %v", err) + } + createScalingConfiguration.UserData = userData + } + + if e.SSHKey != nil && e.SSHKey.Name != nil { + createScalingConfiguration.KeyPairName = fi.StringValue(e.SSHKey.Name) + } + + if e.Tags != nil { + tagItem, err := json.Marshal(e.Tags) + if err != nil { + return fmt.Errorf("error rendering ScalingLaunchConfiguration Tags: %v", err) + } + createScalingConfiguration.Tags = string(tagItem) + } + + createScalingConfigurationResponse, err := t.Cloud.EssClient().CreateScalingConfiguration(createScalingConfiguration) + if err != nil { + return fmt.Errorf("error creating scalingConfiguration: %v", err) + } + e.ConfigurationId = fi.String(createScalingConfigurationResponse.ScalingConfigurationId) + + // Disable ScalingGroup, used to bind scalingConfig, we should excute EnableScalingGroup in the task LaunchConfiguration + // If the ScalingGroup is active, we can not excute EnableScalingGroup. + if e.ScalingGroup.Active != nil && fi.BoolValue(e.ScalingGroup.Active) { + + glog.V(2).Infof("Disabling LoadBalancer with id:%q", fi.StringValue(e.ScalingGroup.ScalingGroupId)) + + disableScalingGroupArgs := &ess.DisableScalingGroupArgs{ + ScalingGroupId: fi.StringValue(e.ScalingGroup.ScalingGroupId), + } + _, err := t.Cloud.EssClient().DisableScalingGroup(disableScalingGroupArgs) + if err != nil { + return fmt.Errorf("error disabling scalingGroup: %v", err) + } + } + + //Enable this configuration + enableScalingGroupArgs := &ess.EnableScalingGroupArgs{ + ScalingGroupId: fi.StringValue(e.ScalingGroup.ScalingGroupId), + ActiveScalingConfigurationId: fi.StringValue(e.ConfigurationId), + } + + glog.V(2).Infof("Enabling new LaunchConfiguration of LoadBalancer with id:%q", fi.StringValue(e.ScalingGroup.ScalingGroupId)) + + _, err = t.Cloud.EssClient().EnableScalingGroup(enableScalingGroupArgs) + if err != nil { + return fmt.Errorf("error enabling scalingGroup: %v", err) + } + + return nil +} + +type terraformLaunchConfiguration struct { + ImageID *string `json:"image_id ,omitempty"` + InstanceType *string `json:"instance_type,omitempty"` + SystemDiskCategory *string `json:"system_disk_category,omitempty"` + UserData *string `json:"user_data,omitempty"` + + RAMRole *terraform.Literal `json:"role_name,omitempty"` + ScalingGroup *terraform.Literal `json:"scaling_group_id,omitempty"` + SSHKey *terraform.Literal `json:"key_name,omitempty"` + SecurityGroup *terraform.Literal `json:"security_group_id,omitempty"` +} + +func (_ *LaunchConfiguration) RenderTerraform(t *terraform.TerraformTarget, a, e, changes *LaunchConfiguration) error { + data, err := e.UserData.AsBytes() + if err != nil { + return fmt.Errorf("error rendering ScalingLaunchConfiguration UserData: %v", err) + } + + userData := base64.StdEncoding.EncodeToString(data) + + tf := &terraformLaunchConfiguration{ + ImageID: e.ImageId, + InstanceType: e.InstanceType, + SystemDiskCategory: e.SystemDiskCategory, + UserData: &userData, + + RAMRole: e.RAMRole.TerraformLink(), + ScalingGroup: e.ScalingGroup.TerraformLink(), + SSHKey: e.SSHKey.TerraformLink(), + SecurityGroup: e.SecurityGroup.TerraformLink(), + } + + return t.RenderResource("alicloud_ess_scaling_configuration", *e.Name, tf) +} + +func (l *LaunchConfiguration) TerraformLink() *terraform.Literal { + return terraform.LiteralProperty("alicloud_ess_scaling_configuration", *l.Name, "id") +} diff --git a/upup/pkg/fi/cloudup/alitasks/launchconfiguration_fitask.go b/upup/pkg/fi/cloudup/alitasks/launchconfiguration_fitask.go new file mode 100644 index 0000000000..22c1b328d7 --- /dev/null +++ b/upup/pkg/fi/cloudup/alitasks/launchconfiguration_fitask.go @@ -0,0 +1,75 @@ +/* +Copyright 2018 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. +*/ + +// Code generated by ""fitask" -type=LaunchConfiguration"; DO NOT EDIT + +package alitasks + +import ( + "encoding/json" + + "k8s.io/kops/upup/pkg/fi" +) + +// LaunchConfiguration + +// JSON marshalling boilerplate +type realLaunchConfiguration LaunchConfiguration + +// UnmarshalJSON implements conversion to JSON, supporitng an alternate specification of the object as a string +func (o *LaunchConfiguration) UnmarshalJSON(data []byte) error { + var jsonName string + if err := json.Unmarshal(data, &jsonName); err == nil { + o.Name = &jsonName + return nil + } + + var r realLaunchConfiguration + if err := json.Unmarshal(data, &r); err != nil { + return err + } + *o = LaunchConfiguration(r) + return nil +} + +var _ fi.HasLifecycle = &LaunchConfiguration{} + +// GetLifecycle returns the Lifecycle of the object, implementing fi.HasLifecycle +func (o *LaunchConfiguration) GetLifecycle() *fi.Lifecycle { + return o.Lifecycle +} + +// SetLifecycle sets the Lifecycle of the object, implementing fi.SetLifecycle +func (o *LaunchConfiguration) SetLifecycle(lifecycle fi.Lifecycle) { + o.Lifecycle = &lifecycle +} + +var _ fi.HasName = &LaunchConfiguration{} + +// GetName returns the Name of the object, implementing fi.HasName +func (o *LaunchConfiguration) GetName() *string { + return o.Name +} + +// SetName sets the Name of the object, implementing fi.SetName +func (o *LaunchConfiguration) SetName(name string) { + o.Name = &name +} + +// String is the stringer function for the task, producing readable output using fi.TaskAsString +func (o *LaunchConfiguration) String() string { + return fi.TaskAsString(o) +} diff --git a/upup/pkg/fi/cloudup/alitasks/scalinggroup.go b/upup/pkg/fi/cloudup/alitasks/scalinggroup.go new file mode 100644 index 0000000000..5641bbb9af --- /dev/null +++ b/upup/pkg/fi/cloudup/alitasks/scalinggroup.go @@ -0,0 +1,208 @@ +/* +Copyright 2018 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 alitasks + +import ( + "encoding/json" + "errors" + "fmt" + + "github.com/denverdino/aliyungo/common" + "github.com/denverdino/aliyungo/ess" + "github.com/golang/glog" + + "k8s.io/kops/upup/pkg/fi" + "k8s.io/kops/upup/pkg/fi/cloudup/aliup" + "k8s.io/kops/upup/pkg/fi/cloudup/terraform" +) + +//go:generate fitask -type=ScalingGroup + +type ScalingGroup struct { + Name *string + Lifecycle *fi.Lifecycle + ScalingGroupId *string + LoadBalancer *LoadBalancer + VSwitchs []*VSwitch + MinSize *int + MaxSize *int + Active *bool +} + +var _ fi.CompareWithID = &ScalingGroup{} + +func (s *ScalingGroup) CompareWithID() *string { + return s.ScalingGroupId +} + +func (s *ScalingGroup) Find(c *fi.Context) (*ScalingGroup, error) { + cloud := c.Cloud.(aliup.ALICloud) + + describeScalingGroupsArgs := &ess.DescribeScalingGroupsArgs{ + RegionId: common.Region(cloud.Region()), + ScalingGroupName: common.FlattenArray{fi.StringValue(s.Name)}, + } + + groupList, _, err := cloud.EssClient().DescribeScalingGroups(describeScalingGroupsArgs) + if err != nil { + return nil, fmt.Errorf("error finding scalingGroup: %v", err) + } + + // Don't exist scalingGroup with specified ClusterTags or Name. + if len(groupList) == 0 { + return nil, nil + } + + if len(groupList) > 1 { + glog.V(4).Info("The number of specified scalingGroup with the same name and ClusterTags exceeds 1, diskName:%q", *s.Name) + } + + glog.V(2).Infof("found matching ScalingGroup with Name: %q", *s.Name) + + actual := &ScalingGroup{} + actual.Name = fi.String(groupList[0].ScalingGroupName) + actual.MinSize = fi.Int(groupList[0].MinSize) + actual.MaxSize = fi.Int(groupList[0].MaxSize) + actual.ScalingGroupId = fi.String(groupList[0].ScalingGroupId) + actual.Active = fi.Bool(groupList[0].LifecycleState == ess.Active) + + actual.LoadBalancer = &LoadBalancer{ + LoadbalancerId: fi.String(groupList[0].LoadBalancerId), + } + + if len(groupList[0].VSwitchIds.VSwitchId) != 0 { + for _, vswitch := range groupList[0].VSwitchIds.VSwitchId { + v := &VSwitch{ + VSwitchId: fi.String(vswitch), + } + actual.VSwitchs = append(actual.VSwitchs, v) + } + } + + // Ignore "system" fields + s.ScalingGroupId = actual.ScalingGroupId + s.Active = actual.Active + actual.Lifecycle = s.Lifecycle + return actual, nil + +} + +func (a *ScalingGroup) Run(c *fi.Context) error { + return fi.DefaultDeltaRunMethod(a, c) +} + +func (_ *ScalingGroup) CheckChanges(a, e, changes *ScalingGroup) error { + if a == nil { + if e.MaxSize == nil { + return fi.RequiredField("MaxSize") + } + if e.MinSize == nil { + return fi.RequiredField("MinSize") + } + if e.Name == nil { + return fi.RequiredField("Name") + } + } + return nil +} + +func (_ *ScalingGroup) RenderALI(t *aliup.ALIAPITarget, a, e, changes *ScalingGroup) error { + vswitchs := common.FlattenArray{} + for _, vswitch := range e.VSwitchs { + if vswitch.VSwitchId == nil { + return errors.New("error updating scalingGroup, lack of VSwitchId") + } + vswitchs = append(vswitchs, fi.StringValue(vswitch.VSwitchId)) + } + + if a == nil { + glog.V(2).Infof("Creating ScalingGroup with Name:%q", fi.StringValue(e.Name)) + + createScalingGroupArgs := &ess.CreateScalingGroupArgs{ + ScalingGroupName: fi.StringValue(e.Name), + RegionId: common.Region(t.Cloud.Region()), + MinSize: e.MinSize, + MaxSize: e.MaxSize, + VSwitchIds: vswitchs, + } + + if e.LoadBalancer != nil && e.LoadBalancer.LoadbalancerId != nil { + loadBalancerIds := []string{fi.StringValue(e.LoadBalancer.LoadbalancerId)} + loadBalancerId, _ := json.Marshal(loadBalancerIds) + createScalingGroupArgs.LoadBalancerIds = string(loadBalancerId) + } + + createScalingGroupResponse, err := t.Cloud.EssClient().CreateScalingGroup(createScalingGroupArgs) + if err != nil { + return fmt.Errorf("error creating autoscalingGroup: %v", err) + } + + e.ScalingGroupId = fi.String(createScalingGroupResponse.ScalingGroupId) + e.Active = fi.Bool(false) + + } else { + //only support to update size + if changes.MinSize != nil || changes.MaxSize != nil { + glog.V(2).Infof("Modifing AutoscalingGroup with Name:%q", fi.StringValue(e.Name)) + + modifyScalingGroupArgs := &ess.ModifyScalingGroupArgs{ + ScalingGroupId: fi.StringValue(a.ScalingGroupId), + MinSize: e.MinSize, + MaxSize: e.MaxSize, + } + _, err := t.Cloud.EssClient().ModifyScalingGroup(modifyScalingGroupArgs) + if err != nil { + return fmt.Errorf("error modifing autoscalingGroup: %v", err) + } + } + } + + return nil +} + +type terraformScalingGroup struct { + Name *string `json:"scaling_group_name,omitempty"` + MaxSize *int `json:"max_size,omitempty"` + MinSize *int `json:"min_size,omitempty"` + + VSwitchs []*terraform.Literal `json:"vswitch_ids,omitempty"` + LoadBalancer []*terraform.Literal `json:"loadbalancer_ids,omitempty"` +} + +func (_ *ScalingGroup) RenderTerraform(t *terraform.TerraformTarget, a, e, changes *ScalingGroup) error { + tf := &terraformScalingGroup{ + Name: e.Name, + MinSize: e.MinSize, + MaxSize: e.MaxSize, + } + + if len(e.VSwitchs) != 0 { + for _, s := range e.VSwitchs { + tf.VSwitchs = append(tf.VSwitchs, s.TerraformLink()) + } + } + + if e.LoadBalancer != nil { + tf.LoadBalancer = append(tf.LoadBalancer, e.LoadBalancer.TerraformLink()) + } + + return t.RenderResource("alicloud_ess_scaling_group", *e.Name, tf) +} + +func (a *ScalingGroup) TerraformLink() *terraform.Literal { + return terraform.LiteralProperty("alicloud_ess_scaling_group", *a.Name, "id") +} diff --git a/upup/pkg/fi/cloudup/alitasks/scalinggroup_fitask.go b/upup/pkg/fi/cloudup/alitasks/scalinggroup_fitask.go new file mode 100644 index 0000000000..231c795748 --- /dev/null +++ b/upup/pkg/fi/cloudup/alitasks/scalinggroup_fitask.go @@ -0,0 +1,75 @@ +/* +Copyright 2018 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. +*/ + +// Code generated by ""fitask" -type=ScalingGroup"; DO NOT EDIT + +package alitasks + +import ( + "encoding/json" + + "k8s.io/kops/upup/pkg/fi" +) + +// ScalingGroup + +// JSON marshalling boilerplate +type realScalingGroup ScalingGroup + +// UnmarshalJSON implements conversion to JSON, supporitng an alternate specification of the object as a string +func (o *ScalingGroup) UnmarshalJSON(data []byte) error { + var jsonName string + if err := json.Unmarshal(data, &jsonName); err == nil { + o.Name = &jsonName + return nil + } + + var r realScalingGroup + if err := json.Unmarshal(data, &r); err != nil { + return err + } + *o = ScalingGroup(r) + return nil +} + +var _ fi.HasLifecycle = &ScalingGroup{} + +// GetLifecycle returns the Lifecycle of the object, implementing fi.HasLifecycle +func (o *ScalingGroup) GetLifecycle() *fi.Lifecycle { + return o.Lifecycle +} + +// SetLifecycle sets the Lifecycle of the object, implementing fi.SetLifecycle +func (o *ScalingGroup) SetLifecycle(lifecycle fi.Lifecycle) { + o.Lifecycle = &lifecycle +} + +var _ fi.HasName = &ScalingGroup{} + +// GetName returns the Name of the object, implementing fi.HasName +func (o *ScalingGroup) GetName() *string { + return o.Name +} + +// SetName sets the Name of the object, implementing fi.SetName +func (o *ScalingGroup) SetName(name string) { + o.Name = &name +} + +// String is the stringer function for the task, producing readable output using fi.TaskAsString +func (o *ScalingGroup) String() string { + return fi.TaskAsString(o) +} diff --git a/upup/pkg/fi/cloudup/aliup/BUILD.bazel b/upup/pkg/fi/cloudup/aliup/BUILD.bazel index f5de4b244e..ebab03f294 100644 --- a/upup/pkg/fi/cloudup/aliup/BUILD.bazel +++ b/upup/pkg/fi/cloudup/aliup/BUILD.bazel @@ -17,6 +17,7 @@ go_library( "//upup/pkg/fi:go_default_library", "//vendor/github.com/denverdino/aliyungo/common:go_default_library", "//vendor/github.com/denverdino/aliyungo/ecs:go_default_library", + "//vendor/github.com/denverdino/aliyungo/ess:go_default_library", "//vendor/github.com/denverdino/aliyungo/ram:go_default_library", "//vendor/github.com/denverdino/aliyungo/slb:go_default_library", "//vendor/github.com/golang/glog:go_default_library", diff --git a/upup/pkg/fi/cloudup/aliup/ali_cloud.go b/upup/pkg/fi/cloudup/aliup/ali_cloud.go index 79aed5a670..b1e3f0a56a 100644 --- a/upup/pkg/fi/cloudup/aliup/ali_cloud.go +++ b/upup/pkg/fi/cloudup/aliup/ali_cloud.go @@ -25,6 +25,7 @@ import ( "github.com/denverdino/aliyungo/common" "github.com/denverdino/aliyungo/ecs" + "github.com/denverdino/aliyungo/ess" "github.com/denverdino/aliyungo/ram" "github.com/denverdino/aliyungo/slb" @@ -47,6 +48,7 @@ type ALICloud interface { EcsClient() *ecs.Client SlbClient() *slb.Client RamClient() *ram.RamClient + EssClient() *ess.Client Region() string AddClusterTags(tags map[string]string) @@ -60,6 +62,7 @@ type aliCloudImplementation struct { ecsClient *ecs.Client slbClient *slb.Client ramClient *ram.RamClient + essClient *ess.Client region string tags map[string]string @@ -87,6 +90,7 @@ func NewALICloud(region string, tags map[string]string) (ALICloud, error) { c.slbClient = slb.NewClient(accessKeyId, accessKeySecret) ramclient := ram.NewClient(accessKeyId, accessKeySecret) c.ramClient = ramclient.(*ram.RamClient) + c.essClient = ess.NewClient(accessKeyId, accessKeySecret) c.tags = tags @@ -105,6 +109,10 @@ func (c *aliCloudImplementation) RamClient() *ram.RamClient { return c.ramClient } +func (c *aliCloudImplementation) EssClient() *ess.Client { + return c.essClient +} + func (c *aliCloudImplementation) Region() string { return c.region } diff --git a/vendor/github.com/denverdino/aliyungo/ess/BUILD.bazel b/vendor/github.com/denverdino/aliyungo/ess/BUILD.bazel new file mode 100644 index 0000000000..9e21d45101 --- /dev/null +++ b/vendor/github.com/denverdino/aliyungo/ess/BUILD.bazel @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = [ + "client.go", + "configuration.go", + "group.go", + "rule.go", + "schedule.go", + ], + importmap = "vendor/github.com/denverdino/aliyungo/ess", + importpath = "github.com/denverdino/aliyungo/ess", + visibility = ["//visibility:public"], + deps = [ + "//vendor/github.com/denverdino/aliyungo/common:go_default_library", + "//vendor/github.com/denverdino/aliyungo/ecs:go_default_library", + ], +) diff --git a/vendor/github.com/denverdino/aliyungo/ess/client.go b/vendor/github.com/denverdino/aliyungo/ess/client.go new file mode 100644 index 0000000000..a2d4865465 --- /dev/null +++ b/vendor/github.com/denverdino/aliyungo/ess/client.go @@ -0,0 +1,48 @@ +package ess + +import ( + "github.com/denverdino/aliyungo/common" + + "os" +) + +type Client struct { + common.Client +} + +const ( + // ESSDefaultEndpoint is the default API endpoint of ESS services + ESSDefaultEndpoint = "https://ess.aliyuncs.com" + ESSAPIVersion = "2014-08-28" + ESSServiceCode = "ess" +) + +// NewClient creates a new instance of RDS client +func NewClient(accessKeyId, accessKeySecret string) *Client { + endpoint := os.Getenv("ESS_ENDPOINT") + if endpoint == "" { + endpoint = ESSDefaultEndpoint + } + return NewClientWithEndpoint(endpoint, accessKeyId, accessKeySecret) +} + +func NewClientWithEndpoint(endpoint string, accessKeyId, accessKeySecret string) *Client { + client := &Client{} + client.Init(endpoint, ESSAPIVersion, accessKeyId, accessKeySecret) + return client +} + +func NewESSClient(accessKeyId, accessKeySecret string, regionID common.Region) *Client { + endpoint := os.Getenv("ESS_ENDPOINT") + if endpoint == "" { + endpoint = ESSDefaultEndpoint + } + + return NewClientWithRegion(endpoint, accessKeyId, accessKeySecret, regionID) +} + +func NewClientWithRegion(endpoint string, accessKeyId, accessKeySecret string, regionID common.Region) *Client { + client := &Client{} + client.NewInit(endpoint, ESSAPIVersion, accessKeyId, accessKeySecret, ESSServiceCode, regionID) + return client +} diff --git a/vendor/github.com/denverdino/aliyungo/ess/configuration.go b/vendor/github.com/denverdino/aliyungo/ess/configuration.go new file mode 100644 index 0000000000..6121701ff1 --- /dev/null +++ b/vendor/github.com/denverdino/aliyungo/ess/configuration.go @@ -0,0 +1,168 @@ +package ess + +import ( + "encoding/base64" + "github.com/denverdino/aliyungo/common" + "github.com/denverdino/aliyungo/ecs" +) + +type CreateScalingConfigurationArgs struct { + ScalingGroupId string + ImageId string + InstanceType string + IoOptimized ecs.IoOptimized + SecurityGroupId string + ScalingConfigurationName string + InternetChargeType common.InternetChargeType + InternetMaxBandwidthIn int + InternetMaxBandwidthOut *int + SystemDisk_Category common.UnderlineString + SystemDisk_Size common.UnderlineString + DataDisk []DataDiskType + UserData string + KeyPairName string + RamRoleName string + Tags string + InstanceName string +} + +type DataDiskType struct { + Category string + SnapshotId string + Device string + Size int +} + +type CreateScalingConfigurationResponse struct { + ScalingConfigurationId string + common.Response +} + +// CreateScalingConfiguration create scaling configuration +// +// You can read doc at https://help.aliyun.com/document_detail/25944.html?spm=5176.doc25942.6.625.KcE5ir +func (client *Client) CreateScalingConfiguration(args *CreateScalingConfigurationArgs) (resp *CreateScalingConfigurationResponse, err error) { + if args.UserData != "" { + // Encode to base64 string + args.UserData = base64.StdEncoding.EncodeToString([]byte(args.UserData)) + } + response := CreateScalingConfigurationResponse{} + err = client.InvokeByFlattenMethod("CreateScalingConfiguration", args, &response) + + if err != nil { + return nil, err + } + return &response, nil +} + +type DescribeScalingConfigurationsArgs struct { + RegionId common.Region + ScalingGroupId string + ScalingConfigurationId common.FlattenArray + ScalingConfigurationName common.FlattenArray + common.Pagination +} + +type DescribeScalingConfigurationsResponse struct { + common.Response + common.PaginationResult + ScalingConfigurations struct { + ScalingConfiguration []ScalingConfigurationItemType + } +} +type TagItemType struct { + Key string + Value string +} + +type ScalingConfigurationItemType struct { + ScalingConfigurationId string + ScalingConfigurationName string + ScalingGroupId string + ImageId string + InstanceType string + InstanceName string + IoOptimized string + SecurityGroupId string + InternetChargeType string + LifecycleState LifecycleState + CreationTime string + InternetMaxBandwidthIn int + InternetMaxBandwidthOut int + SystemDiskCategory string + DataDisks struct { + DataDisk []DataDiskItemType + } + KeyPairName string + RamRoleName string + UserData string + Tags struct { + Tag []TagItemType + } +} + +type DataDiskItemType struct { + Size int + Category string + SnapshotId string + Device string +} + +// DescribeScalingConfigurations describes scaling configuration +// +// You can read doc at https://help.aliyun.com/document_detail/25945.html?spm=5176.doc25944.6.626.knG0zz +func (client *Client) DescribeScalingConfigurations(args *DescribeScalingConfigurationsArgs) (configs []ScalingConfigurationItemType, pagination *common.PaginationResult, err error) { + args.Validate() + response := DescribeScalingConfigurationsResponse{} + + err = client.InvokeByFlattenMethod("DescribeScalingConfigurations", args, &response) + + if err == nil { + return response.ScalingConfigurations.ScalingConfiguration, &response.PaginationResult, nil + } + + return nil, nil, err +} + +type DeleteScalingConfigurationArgs struct { + ScalingConfigurationId string + ScalingGroupId string + ImageId string +} + +type DeleteScalingConfigurationResponse struct { + common.Response +} + +// DeleteScalingConfiguration delete scaling configuration +// +// You can read doc at https://help.aliyun.com/document_detail/25946.html?spm=5176.doc25944.6.627.MjkuuL +func (client *Client) DeleteScalingConfiguration(args *DeleteScalingConfigurationArgs) (resp *DeleteScalingConfigurationResponse, err error) { + response := DeleteScalingConfigurationResponse{} + err = client.InvokeByFlattenMethod("DeleteScalingConfiguration", args, &response) + + if err != nil { + return nil, err + } + return &response, nil +} + +type DeactivateScalingConfigurationArgs struct { + ScalingConfigurationId string +} + +type DeactivateScalingConfigurationResponse struct { + common.Response +} + +// DeactivateScalingConfiguration deactivate scaling configuration +// +func (client *Client) DeactivateScalingConfiguration(args *DeactivateScalingConfigurationArgs) (resp *DeactivateScalingConfigurationResponse, err error) { + response := DeactivateScalingConfigurationResponse{} + err = client.InvokeByFlattenMethod("DeactivateScalingConfiguration", args, &response) + + if err != nil { + return nil, err + } + return &response, nil +} diff --git a/vendor/github.com/denverdino/aliyungo/ess/group.go b/vendor/github.com/denverdino/aliyungo/ess/group.go new file mode 100644 index 0000000000..936b73a858 --- /dev/null +++ b/vendor/github.com/denverdino/aliyungo/ess/group.go @@ -0,0 +1,339 @@ +package ess + +import ( + "github.com/denverdino/aliyungo/common" + "time" +) + +type LifecycleState string + +const ( + Active = LifecycleState("Active") + Inacitve = LifecycleState("Inactive") + Deleting = LifecycleState("Deleting") + InService = LifecycleState("InService") + Pending = LifecycleState("Pending") + Removing = LifecycleState("Removing") +) + +type CreateScalingGroupArgs struct { + RegionId common.Region + ScalingGroupName string + LoadBalancerIds string + VpcId string + VSwitchId string + VSwitchIds common.FlattenArray + // NOTE: Set MinSize, MaxSize and DefaultCooldown type to int pointer to distinguish zero value from unset value. + MinSize *int + MaxSize *int + DefaultCooldown *int + RemovalPolicy common.FlattenArray + DBInstanceIds string +} + +type CreateScalingGroupResponse struct { + common.Response + ScalingGroupId string +} + +// CreateScalingGroup create scaling group +// +// You can read doc at https://help.aliyun.com/document_detail/25936.html?spm=5176.doc25940.6.617.vm6LXF +func (client *Client) CreateScalingGroup(args *CreateScalingGroupArgs) (resp *CreateScalingGroupResponse, err error) { + response := CreateScalingGroupResponse{} + err = client.InvokeByFlattenMethod("CreateScalingGroup", args, &response) + + if err != nil { + return nil, err + } + return &response, nil +} + +type ModifyScalingGroupArgs struct { + ScalingGroupId string + ScalingGroupName string + ActiveScalingConfigurationId string + // NOTE: Set MinSize/MaxSize type to int pointer to distinguish zero value from unset value. + MinSize *int + MaxSize *int + DefaultCooldown *int + RemovalPolicy common.FlattenArray +} + +type ModifyScalingGroupResponse struct { + common.Response +} + +// ModifyScalingGroup modify scaling group +// +// You can read doc at https://help.aliyun.com/document_detail/25937.html?spm=5176.doc25936.6.618.iwDcXT +func (client *Client) ModifyScalingGroup(args *ModifyScalingGroupArgs) (resp *ModifyScalingGroupResponse, err error) { + response := ModifyScalingGroupResponse{} + err = client.InvokeByFlattenMethod("ModifyScalingGroup", args, &response) + + if err != nil { + return nil, err + } + return &response, nil +} + +type DescribeScalingGroupsArgs struct { + RegionId common.Region + ScalingGroupId common.FlattenArray + ScalingGroupName common.FlattenArray + common.Pagination +} + +type DescribeInstancesResponse struct { + common.Response + common.PaginationResult + ScalingGroups struct { + ScalingGroup []ScalingGroupItemType + } +} + +type ScalingGroupItemType struct { + ScalingGroupId string + ScalingGroupName string + ActiveScalingConfigurationId string + RegionId string + LoadBalancerId string + VSwitchId string + VSwitchIds VSwitchIdsSetType + CreationTime string + LifecycleState LifecycleState + MinSize int + MaxSize int + DefaultCooldown int + TotalCapacity int + ActiveCapacity int + PendingCapacity int + RemovingCapacity int + RemovalPolicies RemovalPolicySetType + DBInstanceIds DBInstanceIdSetType + LoadBalancerIds LoadBalancerIdSetType +} + +type VSwitchIdsSetType struct { + VSwitchId []string +} + +type RemovalPolicySetType struct { + RemovalPolicy []string +} + +type DBInstanceIdSetType struct { + DBInstanceId []string +} +type LoadBalancerIdSetType struct { + LoadBalancerId []string +} + +// DescribeScalingGroups describes scaling groups +// +// You can read doc at https://help.aliyun.com/document_detail/25938.html?spm=5176.doc25937.6.619.sUUOT7 +func (client *Client) DescribeScalingGroups(args *DescribeScalingGroupsArgs) (groups []ScalingGroupItemType, pagination *common.PaginationResult, err error) { + args.Validate() + response := DescribeInstancesResponse{} + + err = client.InvokeByFlattenMethod("DescribeScalingGroups", args, &response) + + if err == nil { + return response.ScalingGroups.ScalingGroup, &response.PaginationResult, nil + } + + return nil, nil, err +} + +type DescribeScalingInstancesArgs struct { + RegionId common.Region + ScalingGroupId string + ScalingConfigurationId string + HealthStatus string + CreationType string + LifecycleState LifecycleState + InstanceId common.FlattenArray + common.Pagination +} + +type DescribeScalingInstancesResponse struct { + common.Response + common.PaginationResult + ScalingInstances struct { + ScalingInstance []ScalingInstanceItemType + } +} + +type ScalingInstanceItemType struct { + InstanceId string + ScalingGroupId string + ScalingConfigurationId string + HealthStatus string + CreationTime string + CreationType string + LifecycleState LifecycleState +} + +// DescribeScalingInstances describes scaling instances +// +// You can read doc at https://help.aliyun.com/document_detail/25942.html?spm=5176.doc25941.6.623.2xA0Uj +func (client *Client) DescribeScalingInstances(args *DescribeScalingInstancesArgs) (instances []ScalingInstanceItemType, pagination *common.PaginationResult, err error) { + args.Validate() + response := DescribeScalingInstancesResponse{} + + err = client.InvokeByFlattenMethod("DescribeScalingInstances", args, &response) + + if err == nil { + return response.ScalingInstances.ScalingInstance, &response.PaginationResult, nil + } + + return nil, nil, err +} + +type EnableScalingGroupArgs struct { + ScalingGroupId string + ActiveScalingConfigurationId string + InstanceId common.FlattenArray +} + +type EnableScalingGroupResponse struct { + common.Response +} + +// EnableScalingGroup enable scaling group +// +// You can read doc at https://help.aliyun.com/document_detail/25939.html?spm=5176.doc25938.6.620.JiJhkx +func (client *Client) EnableScalingGroup(args *EnableScalingGroupArgs) (resp *EnableScalingGroupResponse, err error) { + response := EnableScalingGroupResponse{} + err = client.InvokeByFlattenMethod("EnableScalingGroup", args, &response) + + if err != nil { + return nil, err + } + return &response, nil +} + +type DisableScalingGroupArgs struct { + ScalingGroupId string +} + +type DisableScalingGroupResponse struct { + common.Response +} + +// DisableScalingGroup disable scaling group +// +// You can read doc at https://help.aliyun.com/document_detail/25940.html?spm=5176.doc25939.6.621.M8GuuY +func (client *Client) DisableScalingGroup(args *DisableScalingGroupArgs) (resp *DisableScalingGroupResponse, err error) { + response := DisableScalingGroupResponse{} + err = client.InvokeByFlattenMethod("DisableScalingGroup", args, &response) + + if err != nil { + return nil, err + } + return &response, nil +} + +type DeleteScalingGroupArgs struct { + ScalingGroupId string + ForceDelete bool +} + +type DeleteScalingGroupResponse struct { + common.Response +} + +// DeleteScalingGroup delete scaling group +// +// You can read doc at https://help.aliyun.com/document_detail/25941.html?spm=5176.doc25940.6.622.mRBCuw +func (client *Client) DeleteScalingGroup(args *DeleteScalingGroupArgs) (resp *DeleteScalingGroupResponse, err error) { + response := DeleteScalingGroupResponse{} + err = client.InvokeByFlattenMethod("DeleteScalingGroup", args, &response) + + if err != nil { + return nil, err + } + return &response, nil +} + +type AttachInstancesArgs struct { + ScalingGroupId string + InstanceId common.FlattenArray +} + +type AttachInstancesResponse struct { + common.Response + ScalingActivityId string +} + +type RemoveInstancesArgs struct { + ScalingGroupId string + InstanceId common.FlattenArray +} + +type RemoveInstancesResponse struct { + common.Response + ScalingActivityId string +} + +// AttachInstances attach instances to scaling group +// +// You can read doc at https://help.aliyun.com/document_detail/25954.html?spm=5176.product25855.6.633.y5gmzX +func (client *Client) AttachInstances(args *AttachInstancesArgs) (resp *AttachInstancesResponse, err error) { + response := AttachInstancesResponse{} + err = client.InvokeByFlattenMethod("AttachInstances", args, &response) + + if err != nil { + return nil, err + } + return &response, nil +} + +// RemoveInstances detach instances from scaling group +// +// You can read doc at https://help.aliyun.com/document_detail/25955.html?spm=5176.doc25954.6.634.GtpzuJ +func (client *Client) RemoveInstances(args *RemoveInstancesArgs) (resp *RemoveInstancesResponse, err error) { + response := RemoveInstancesResponse{} + err = client.InvokeByFlattenMethod("RemoveInstances", args, &response) + + if err != nil { + return nil, err + } + return &response, nil +} + +// Default timeout value for WaitForInstance method +const DefaultWaitTimeout = 120 +const DefaultWaitForInterval = 5 + +// WaitForScalingGroup waits for group to given status +func (client *Client) WaitForScalingGroup(regionId common.Region, groupId string, status LifecycleState, timeout int) error { + if timeout <= 0 { + timeout = DefaultWaitTimeout + } + for { + sgs, _, err := client.DescribeScalingGroups(&DescribeScalingGroupsArgs{ + RegionId: regionId, + ScalingGroupId: []string{groupId}, + }) + if err != nil { + return err + } + + if timeout <= 0 { + return common.GetClientErrorFromString("Timeout") + } + + timeout = timeout - DefaultWaitForInterval + time.Sleep(DefaultWaitForInterval * time.Second) + + if len(sgs) < 1 { + return common.GetClientErrorFromString("Not found") + } + if sgs[0].LifecycleState == status { + break + } + + } + return nil +} diff --git a/vendor/github.com/denverdino/aliyungo/ess/rule.go b/vendor/github.com/denverdino/aliyungo/ess/rule.go new file mode 100644 index 0000000000..399ec1ae7c --- /dev/null +++ b/vendor/github.com/denverdino/aliyungo/ess/rule.go @@ -0,0 +1,152 @@ +package ess + +import "github.com/denverdino/aliyungo/common" + +type AdjustmentType string + +const ( + QuantityChangeInCapacity = AdjustmentType("QuantityChangeInCapacity") + PercentChangeInCapacity = AdjustmentType("PercentChangeInCapacity") + TotalCapacity = AdjustmentType("TotalCapacity") +) + +type CreateScalingRuleArgs struct { + RegionId common.Region + ScalingGroupId string + AdjustmentType AdjustmentType + AdjustmentValue int + Cooldown int + ScalingRuleName string +} + +type CreateScalingRuleResponse struct { + common.Response + ScalingRuleId string + ScalingRuleAri string +} + +// CreateScalingRule create scaling rule +// +// You can read doc at https://help.aliyun.com/document_detail/25948.html?spm=5176.doc25944.6.629.FLkNnj +func (client *Client) CreateScalingRule(args *CreateScalingRuleArgs) (resp *CreateScalingRuleResponse, err error) { + response := CreateScalingRuleResponse{} + err = client.Invoke("CreateScalingRule", args, &response) + + if err != nil { + return nil, err + } + return &response, nil +} + +type ModifyScalingRuleArgs struct { + RegionId common.Region + ScalingRuleId string + AdjustmentType AdjustmentType + AdjustmentValue int + Cooldown int + ScalingRuleName string +} + +type ModifyScalingRuleResponse struct { + common.Response +} + +// ModifyScalingRule modify scaling rule +// +// You can read doc at https://help.aliyun.com/document_detail/25949.html?spm=5176.doc25948.6.630.HGN1va +func (client *Client) ModifyScalingRule(args *ModifyScalingRuleArgs) (resp *ModifyScalingRuleResponse, err error) { + response := ModifyScalingRuleResponse{} + err = client.Invoke("ModifyScalingRule", args, &response) + + if err != nil { + return nil, err + } + return &response, nil +} + +type DescribeScalingRulesArgs struct { + common.Pagination + RegionId common.Region + ScalingGroupId string + ScalingRuleId common.FlattenArray + ScalingRuleName common.FlattenArray + ScalingRuleAri common.FlattenArray +} + +type DescribeScalingRulesResponse struct { + common.Response + common.PaginationResult + ScalingRules struct { + ScalingRule []ScalingRuleItemType + } +} + +type ScalingRuleItemType struct { + ScalingRuleId string + ScalingGroupId string + ScalingRuleName string + AdjustmentType string + ScalingRuleAri string + Cooldown int + AdjustmentValue int +} + +// DescribeScalingRules describes scaling rules +// +// You can read doc at https://help.aliyun.com/document_detail/25950.html?spm=5176.doc25949.6.631.RwPguo +func (client *Client) DescribeScalingRules(args *DescribeScalingRulesArgs) (configs []ScalingRuleItemType, pagination *common.PaginationResult, err error) { + args.Validate() + response := DescribeScalingRulesResponse{} + + err = client.InvokeByFlattenMethod("DescribeScalingRules", args, &response) + + if err == nil { + return response.ScalingRules.ScalingRule, &response.PaginationResult, nil + } + + return nil, nil, err +} + +type DeleteScalingRuleArgs struct { + RegionId common.Region + ScalingRuleId string +} + +type DeleteScalingRuleResponse struct { + common.Response +} + +// DeleteScalingRule delete scaling rule +// +// You can read doc at https://help.aliyun.com/document_detail/25951.html?spm=5176.doc25950.6.632.HbPLMZ +func (client *Client) DeleteScalingRule(args *DeleteScalingRuleArgs) (resp *DeleteScalingRuleResponse, err error) { + response := DeleteScalingRuleResponse{} + err = client.InvokeByFlattenMethod("DeleteScalingRule", args, &response) + + if err != nil { + return nil, err + } + return &response, nil +} + +type ExecuteScalingRuleArgs struct { + ScalingRuleAri string + ClientToken string +} + +type ExecuteScalingRuleResponse struct { + common.Response + ScalingActivityId string +} + +// ExecuteScalingRule execute scaling rule +// +// You can read doc at https://help.aliyun.com/document_detail/25953.html?spm=5176.doc25961.6.632.7sXDx6 +func (client *Client) ExecuteScalingRule(args *ExecuteScalingRuleArgs) (*ExecuteScalingRuleResponse, error) { + resp := ExecuteScalingRuleResponse{} + err := client.InvokeByFlattenMethod("ExecuteScalingRule", args, &resp) + if err != nil { + return nil, err + } + return &resp, nil +} diff --git a/vendor/github.com/denverdino/aliyungo/ess/schedule.go b/vendor/github.com/denverdino/aliyungo/ess/schedule.go new file mode 100644 index 0000000000..9da5a86e05 --- /dev/null +++ b/vendor/github.com/denverdino/aliyungo/ess/schedule.go @@ -0,0 +1,140 @@ +package ess + +import "github.com/denverdino/aliyungo/common" + +type RecurrenceType string + +const ( + Daily = RecurrenceType("Daily") + Weekly = RecurrenceType("Weekly") + Monthly = RecurrenceType("Monthly") +) + +type CreateScheduledTaskArgs struct { + RegionId common.Region + ScheduledAction string + LaunchTime string + ScheduledTaskName string + Description string + LaunchExpirationTime int + RecurrenceType RecurrenceType + RecurrenceValue string + RecurrenceEndTime string + TaskEnabled bool +} + +type CreateScheduledTaskResponse struct { + common.Response + ScheduledTaskId string +} + +// CreateScheduledTask create schedule task +// +// You can read doc at https://help.aliyun.com/document_detail/25957.html?spm=5176.doc25950.6.638.FfQ0BR +func (client *Client) CreateScheduledTask(args *CreateScheduledTaskArgs) (resp *CreateScheduledTaskResponse, err error) { + response := CreateScheduledTaskResponse{} + err = client.Invoke("CreateScheduledTask", args, &response) + + if err != nil { + return nil, err + } + return &response, nil +} + +type ModifyScheduledTaskArgs struct { + RegionId common.Region + ScheduledTaskId string + ScheduledAction string + LaunchTime string + ScheduledTaskName string + Description string + LaunchExpirationTime int + RecurrenceType RecurrenceType + RecurrenceValue string + RecurrenceEndTime string + TaskEnabled bool +} + +type ModifyScheduledTaskResponse struct { + common.Response +} + +// ModifyScheduledTask modify schedule task +// +// You can read doc at https://help.aliyun.com/document_detail/25958.html?spm=5176.doc25957.6.639.rgxQ1c +func (client *Client) ModifyScheduledTask(args *ModifyScheduledTaskArgs) (resp *ModifyScheduledTaskResponse, err error) { + response := ModifyScheduledTaskResponse{} + err = client.Invoke("ModifyScheduledTask", args, &response) + + if err != nil { + return nil, err + } + return &response, nil +} + +type DescribeScheduledTasksArgs struct { + RegionId common.Region + ScheduledTaskId common.FlattenArray + ScheduledTaskName common.FlattenArray + ScheduledAction common.FlattenArray + common.Pagination +} + +type DescribeScheduledTasksResponse struct { + common.Response + common.PaginationResult + ScheduledTasks struct { + ScheduledTask []ScheduledTaskItemType + } +} + +type ScheduledTaskItemType struct { + ScheduledTaskId string + ScheduledTaskName string + Description string + ScheduledAction string + LaunchTime string + RecurrenceType string + RecurrenceValue string + RecurrenceEndTime string + LaunchExpirationTime int + TaskEnabled bool +} + +// DescribeScheduledTasks describes scaling tasks +// +// You can read doc at https://help.aliyun.com/document_detail/25959.html?spm=5176.doc25958.6.640.cLccdR +func (client *Client) DescribeScheduledTasks(args *DescribeScheduledTasksArgs) (tasks []ScheduledTaskItemType, pagination *common.PaginationResult, err error) { + args.Validate() + response := DescribeScheduledTasksResponse{} + + err = client.InvokeByFlattenMethod("DescribeScheduledTasks", args, &response) + + if err == nil { + return response.ScheduledTasks.ScheduledTask, &response.PaginationResult, nil + } + + return nil, nil, err +} + +type DeleteScheduledTaskArgs struct { + RegionId common.Region + ScheduledTaskId string +} + +type DeleteScheduledTaskResponse struct { + common.Response +} + +// DeleteScheduledTask delete schedule task +// +// You can read doc at https://help.aliyun.com/document_detail/25960.html?spm=5176.doc25959.6.641.aGdNuW +func (client *Client) DeleteScheduledTask(args *DeleteScheduledTaskArgs) (resp *DeleteScheduledTaskResponse, err error) { + response := DeleteScheduledTaskResponse{} + err = client.Invoke("DeleteScheduledTask", args, &response) + + if err != nil { + return nil, err + } + return &response, nil +}