260 lines
6.6 KiB
Go
260 lines
6.6 KiB
Go
package alicloud
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"github.com/denverdino/aliyungo/common"
|
|
"github.com/denverdino/aliyungo/ecs"
|
|
"strings"
|
|
)
|
|
|
|
func (client *AliyunClient) DescribeImage(imageId string) (*ecs.ImageType, error) {
|
|
|
|
pagination := common.Pagination{
|
|
PageNumber: 1,
|
|
}
|
|
args := ecs.DescribeImagesArgs{
|
|
Pagination: pagination,
|
|
RegionId: client.Region,
|
|
Status: ecs.ImageStatusAvailable,
|
|
}
|
|
|
|
var allImages []ecs.ImageType
|
|
|
|
for {
|
|
images, _, err := client.ecsconn.DescribeImages(&args)
|
|
if err != nil {
|
|
break
|
|
}
|
|
|
|
if len(images) == 0 {
|
|
break
|
|
}
|
|
|
|
allImages = append(allImages, images...)
|
|
|
|
args.Pagination.PageNumber++
|
|
}
|
|
|
|
if len(allImages) == 0 {
|
|
return nil, common.GetClientErrorFromString("Not found")
|
|
}
|
|
|
|
var image *ecs.ImageType
|
|
imageIds := []string{}
|
|
for _, im := range allImages {
|
|
if im.ImageId == imageId {
|
|
image = &im
|
|
}
|
|
imageIds = append(imageIds, im.ImageId)
|
|
}
|
|
|
|
if image == nil {
|
|
return nil, fmt.Errorf("image_id %s not exists in range %s, all images are %s", imageId, client.Region, imageIds)
|
|
}
|
|
|
|
return image, nil
|
|
}
|
|
|
|
// DescribeZone validate zoneId is valid in region
|
|
func (client *AliyunClient) DescribeZone(zoneID string) (*ecs.ZoneType, error) {
|
|
zones, err := client.ecsconn.DescribeZones(client.Region)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error to list zones not found")
|
|
}
|
|
|
|
var zone *ecs.ZoneType
|
|
zoneIds := []string{}
|
|
for _, z := range zones {
|
|
if z.ZoneId == zoneID {
|
|
zone = &ecs.ZoneType{
|
|
ZoneId: z.ZoneId,
|
|
LocalName: z.LocalName,
|
|
AvailableResourceCreation: z.AvailableResourceCreation,
|
|
AvailableDiskCategories: z.AvailableDiskCategories,
|
|
}
|
|
}
|
|
zoneIds = append(zoneIds, z.ZoneId)
|
|
}
|
|
|
|
if zone == nil {
|
|
return nil, fmt.Errorf("availability_zone not exists in range %s, all zones are %s", client.Region, zoneIds)
|
|
}
|
|
|
|
return zone, nil
|
|
}
|
|
|
|
// return multiIZ list of current region
|
|
func (client *AliyunClient) DescribeMultiIZByRegion() (izs []string, err error) {
|
|
resp, err := client.rdsconn.DescribeRegions()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error to list regions not found")
|
|
}
|
|
regions := resp.Regions.RDSRegion
|
|
|
|
zoneIds := []string{}
|
|
for _, r := range regions {
|
|
if r.RegionId == string(client.Region) && strings.Contains(r.ZoneId, MULTI_IZ_SYMBOL) {
|
|
zoneIds = append(zoneIds, r.ZoneId)
|
|
}
|
|
}
|
|
|
|
return zoneIds, nil
|
|
}
|
|
|
|
func (client *AliyunClient) QueryInstancesByIds(ids []string) (instances []ecs.InstanceAttributesType, err error) {
|
|
idsStr, jerr := json.Marshal(ids)
|
|
if jerr != nil {
|
|
return nil, jerr
|
|
}
|
|
|
|
args := ecs.DescribeInstancesArgs{
|
|
RegionId: client.Region,
|
|
InstanceIds: string(idsStr),
|
|
}
|
|
|
|
instances, _, errs := client.ecsconn.DescribeInstances(&args)
|
|
|
|
if errs != nil {
|
|
return nil, errs
|
|
}
|
|
|
|
return instances, nil
|
|
}
|
|
|
|
func (client *AliyunClient) QueryInstancesById(id string) (instance *ecs.InstanceAttributesType, err error) {
|
|
ids := []string{id}
|
|
|
|
instances, errs := client.QueryInstancesByIds(ids)
|
|
if errs != nil {
|
|
return nil, errs
|
|
}
|
|
|
|
if len(instances) == 0 {
|
|
return nil, common.GetClientErrorFromString(InstanceNotfound)
|
|
}
|
|
|
|
return &instances[0], nil
|
|
}
|
|
|
|
func (client *AliyunClient) QueryInstanceSystemDisk(id string) (disk *ecs.DiskItemType, err error) {
|
|
args := ecs.DescribeDisksArgs{
|
|
RegionId: client.Region,
|
|
InstanceId: string(id),
|
|
DiskType: ecs.DiskTypeAllSystem,
|
|
}
|
|
disks, _, err := client.ecsconn.DescribeDisks(&args)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(disks) == 0 {
|
|
return nil, common.GetClientErrorFromString(SystemDiskNotFound)
|
|
}
|
|
|
|
return &disks[0], nil
|
|
}
|
|
|
|
// ResourceAvailable check resource available for zone
|
|
func (client *AliyunClient) ResourceAvailable(zone *ecs.ZoneType, resourceType ecs.ResourceType) error {
|
|
available := false
|
|
for _, res := range zone.AvailableResourceCreation.ResourceTypes {
|
|
if res == resourceType {
|
|
available = true
|
|
}
|
|
}
|
|
if !available {
|
|
return fmt.Errorf("%s is not available in %s zone of %s region", resourceType, zone.ZoneId, client.Region)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (client *AliyunClient) DiskAvailable(zone *ecs.ZoneType, diskCategory ecs.DiskCategory) error {
|
|
available := false
|
|
for _, dist := range zone.AvailableDiskCategories.DiskCategories {
|
|
if dist == diskCategory {
|
|
available = true
|
|
}
|
|
}
|
|
if !available {
|
|
return fmt.Errorf("%s is not available in %s zone of %s region", diskCategory, zone.ZoneId, client.Region)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// todo: support syc
|
|
func (client *AliyunClient) JoinSecurityGroups(instanceId string, securityGroupIds []string) error {
|
|
for _, sid := range securityGroupIds {
|
|
err := client.ecsconn.JoinSecurityGroup(instanceId, sid)
|
|
if err != nil {
|
|
e, _ := err.(*common.Error)
|
|
if e.ErrorResponse.Code != InvalidInstanceIdAlreadyExists {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (client *AliyunClient) LeaveSecurityGroups(instanceId string, securityGroupIds []string) error {
|
|
for _, sid := range securityGroupIds {
|
|
err := client.ecsconn.LeaveSecurityGroup(instanceId, sid)
|
|
if err != nil {
|
|
e, _ := err.(*common.Error)
|
|
if e.ErrorResponse.Code != InvalidSecurityGroupIdNotFound {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (client *AliyunClient) DescribeSecurity(securityGroupId string) (*ecs.DescribeSecurityGroupAttributeResponse, error) {
|
|
|
|
args := &ecs.DescribeSecurityGroupAttributeArgs{
|
|
RegionId: client.Region,
|
|
SecurityGroupId: securityGroupId,
|
|
}
|
|
|
|
return client.ecsconn.DescribeSecurityGroupAttribute(args)
|
|
}
|
|
|
|
func (client *AliyunClient) DescribeSecurityByAttr(securityGroupId, direction, nicType string) (*ecs.DescribeSecurityGroupAttributeResponse, error) {
|
|
|
|
args := &ecs.DescribeSecurityGroupAttributeArgs{
|
|
RegionId: client.Region,
|
|
SecurityGroupId: securityGroupId,
|
|
Direction: direction,
|
|
NicType: ecs.NicType(nicType),
|
|
}
|
|
|
|
return client.ecsconn.DescribeSecurityGroupAttribute(args)
|
|
}
|
|
|
|
func (client *AliyunClient) DescribeSecurityGroupRule(securityGroupId, direction, nicType, ipProtocol, portRange string) (*ecs.PermissionType, error) {
|
|
sg, err := client.DescribeSecurityByAttr(securityGroupId, direction, nicType)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for _, p := range sg.Permissions.Permission {
|
|
if strings.ToLower(string(p.IpProtocol)) == ipProtocol && p.PortRange == portRange {
|
|
return &p, nil
|
|
}
|
|
}
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
func (client *AliyunClient) RevokeSecurityGroup(args *ecs.RevokeSecurityGroupArgs) error {
|
|
//when the rule is not exist, api will return success(200)
|
|
return client.ecsconn.RevokeSecurityGroup(args)
|
|
}
|
|
|
|
func (client *AliyunClient) RevokeSecurityGroupEgress(args *ecs.RevokeSecurityGroupEgressArgs) error {
|
|
//when the rule is not exist, api will return success(200)
|
|
return client.ecsconn.RevokeSecurityGroupEgress(args)
|
|
}
|