diff --git a/pkg/util/aws/disk.go b/pkg/util/aws/disk.go index f8dd57fbc8..019e20c93b 100644 --- a/pkg/util/aws/disk.go +++ b/pkg/util/aws/disk.go @@ -3,11 +3,12 @@ package aws import ( "fmt" "time" + + "github.com/aws/aws-sdk-go/service/ec2" + "github.com/coredns/coredns/plugin/pkg/log" "yunion.io/x/jsonutils" "yunion.io/x/onecloud/pkg/cloudprovider" - "github.com/aws/aws-sdk-go/service/ec2" "yunion.io/x/onecloud/pkg/compute/models" - "github.com/coredns/coredns/plugin/pkg/log" ) type SMountInstances struct { @@ -30,13 +31,13 @@ type SDisk struct { Category string // VolumeType Type string // system | data Status string // State - AttachmentStatus string // attachment.status + AttachmentStatus string // attachment.status Device string // Device InstanceId string // InstanceId Encrypted bool // Encrypted SourceSnapshotId string // SnapshotId Iops int // Iops - Tags STags + Tags TagSpec CreationTime time.Time // CreateTime AttachedTime time.Time // AttachTime @@ -246,7 +247,9 @@ func (self *SRegion) GetDisks(instanceId string, zoneId string, storageType stri filters = AppendSingleValueFilter(filters, "volume-type", storageType) } - params.SetFilters(filters) + if len(filters) > 0 { + params.SetFilters(filters) + } if len(diskIds) > 0 { params.SetVolumeIds(ConvertedList(diskIds)) @@ -254,22 +257,27 @@ func (self *SRegion) GetDisks(instanceId string, zoneId string, storageType stri ret, err := self.ec2Client.DescribeVolumes(params) if err != nil { - return nil, 0 , err + return nil, 0, err } disks := []SDisk{} for _, item := range ret.Volumes { + tagspec := TagSpec{} + tagspec.LoadingEc2Tags(item.Tags) + disk := SDisk{} disk.ZoneId = *item.AvailabilityZone disk.Status = *item.State - disk.Size = int(*item.Size) + disk.DiskName = tagspec.GetNameTag() + disk.Size = int(IntVal(item.Size)) disk.Category = *item.VolumeType disk.RegionId = self.RegionId disk.SourceSnapshotId = *item.SnapshotId disk.Encrypted = *item.Encrypted disk.DiskId = *item.VolumeId - disk.Iops = int(*item.Iops) + disk.Iops = int(IntVal(item.Iops)) disk.CreationTime = *item.CreateTime + disk.Tags = tagspec if len(item.Attachments) > 0 { disk.DeleteWithInstance = *item.Attachments[0].DeleteOnTermination disk.AttachedTime = *item.Attachments[0].AttachTime @@ -346,7 +354,7 @@ func (self *SRegion) resizeDisk(diskId string, size int64) error { params.SetVolumeId(diskId) } - _,err := self.ec2Client.ModifyVolume(params) + _, err := self.ec2Client.ModifyVolume(params) return err } diff --git a/pkg/util/aws/instance.go b/pkg/util/aws/instance.go index 96e540d26d..382bf8b1bb 100644 --- a/pkg/util/aws/instance.go +++ b/pkg/util/aws/instance.go @@ -390,15 +390,40 @@ func (self *SRegion) GetInstances(zoneId string, ids []string, offset int, limit instances := []SInstance{} for _, reservation := range res.Reservations { for _, instance := range reservation.Instances { + instanceType, err := self.GetInstanceType(StrVal(instance.InstanceType)) + if err != nil { + return nil, 0 , err + } + + tagspec := TagSpec{} + tagspec.LoadingEc2Tags(instance.Tags) + + disks := []string{} + for _, d := range instance.BlockDeviceMappings { + if d.Ebs != nil && d.Ebs.VolumeId != nil { + disks = append(disks, *d.Ebs.VolumeId) + } + } + + var secgroups SSecurityGroupIds + for _, s := range instance.SecurityGroups { + if s.GroupId != nil { + if secgroups.SecurityGroupId == nil { + secgroups.SecurityGroupId = []string{} + } + secgroups.SecurityGroupId = append(secgroups.SecurityGroupId, *s.GroupId) + } + } + sinstance := SInstance{ RegionId: self.RegionId, ZoneId: *instance.Placement.AvailabilityZone, InstanceId: *instance.InstanceId, ImageId: *instance.ImageId, - InstanceName: "// todo:xx", + InstanceName: tagspec.GetNameTag(), InstanceType: *instance.InstanceType, - Cpu: int8(*instance.CpuOptions.CoreCount), // CoreCount? - Memory: 0, // todo:? get from instance type + Cpu: int8(*instance.CpuOptions.CoreCount), + Memory: instanceType.memoryMB(), IoOptimized: *instance.EbsOptimized, KeyPairName: *instance.KeyName, CreationTime: *instance.LaunchTime, @@ -407,12 +432,12 @@ func (self *SRegion) GetInstances(zoneId string, ids []string, offset int, limit PublicDNSName: *instance.PublicDnsName, RootDeviceName: *instance.RootDeviceName, Status: *instance.State.Name, + Disks: disks, + SecurityGroupIds: secgroups, + // EipAddress: // VlanId: // VpcAttributes: - // SecurityGroupIds: // NetworkInterfaces: - // EipAddress: - // Disks: // OSName: // OSType: // Description: diff --git a/pkg/util/aws/instancetype.go b/pkg/util/aws/instancetype.go index c629fe598a..a1ae366f64 100644 --- a/pkg/util/aws/instancetype.go +++ b/pkg/util/aws/instancetype.go @@ -2,6 +2,7 @@ package aws import ( "encoding/json" + "fmt" "yunion.io/x/log" ) @@ -64,6 +65,17 @@ func (self *SRegion) GetInstanceTypes() ([]SInstanceType, error) { } } +func (self *SRegion) GetInstanceType(instanceTypeId string) (*SInstanceType, error) { + ret, _ := self.GetInstanceTypes() + for _, item := range ret { + if item.InstanceTypeId == instanceTypeId { + return &item, nil + } + } + + return nil, fmt.Errorf("instancetype %s not found", instanceTypeId) +} + func (self *SRegion) GetMatchInstanceTypes(cpu int, memMB int, gpu int, zoneId string) ([]SInstanceType, error) { types, err := self.GetInstanceTypes() if err != nil { diff --git a/pkg/util/aws/utils.go b/pkg/util/aws/utils.go index bb1215101c..f743630453 100644 --- a/pkg/util/aws/utils.go +++ b/pkg/util/aws/utils.go @@ -1,12 +1,13 @@ package aws import ( - "github.com/aws/aws-sdk-go/service/ec2" - "yunion.io/x/pkg/util/secrules" - "net" "fmt" - "yunion.io/x/log" + "net" "strings" + + "github.com/aws/aws-sdk-go/service/ec2" + "yunion.io/x/log" + "yunion.io/x/pkg/util/secrules" ) type portRange struct { @@ -14,7 +15,84 @@ type portRange struct { End int64 } -func AppendFilter(filters []*ec2.Filter, name string, values []string) ([]*ec2.Filter) { +type TagSpec struct { + ResourceType string // "customer-gateway"|"dedicated-host"|"dhcp-options"|"image"|"instance"|"internet-gateway"|"network-acl"|"network-interface"|"reserved-instances"|"route-table"|"snapshot"|"spot-instances-request"|"subnet"|"security-group"|"volume"|"vpc"|"vpn-connection"|"vpn-gateway" + Tags map[string]string +} + +func (self *TagSpec) LoadingEc2Tags(tags []*ec2.Tag) { + for _, tag := range tags { + if tag.Key != nil && tag.Value != nil { + self.SetTag(*tag.Key, *tag.Value) + } + } +} + +func (self *TagSpec) GetTagSpecifications() (*ec2.TagSpecification, error) { + if self.ResourceType == "" { + return nil, fmt.Errorf("ResourceType should not be empty") + } + + spec := &ec2.TagSpecification{ResourceType: &self.ResourceType} + tags := []*ec2.Tag{} + for k, v := range self.Tags { + if len(v) > 255 { + return nil, fmt.Errorf("%s value length should less than 255", k) + } + + tag := &ec2.Tag{} + tag.SetKey(k) + tag.SetValue(v) + tags = append(tags, tag) + } + + spec.SetTags(tags) + return spec, nil +} + +func (self *TagSpec) SetTag(k, v string) { + if self.Tags == nil { + self.Tags = make(map[string]string) + } + self.Tags[k] = v +} + +func (self *TagSpec) SetNameTag(v string) { + self.SetTag("Name", v) +} + +func (self *TagSpec) SetDescTag(v string) { + self.SetTag("Description", v) +} + +func (self *TagSpec) GetTag(k string) (string, error) { + v, ok := self.Tags[k] + if !ok { + return "", fmt.Errorf("%s not found", k) + } + + return v, nil +} + +// 找不到的情况下返回传入的默认值 +func (self *TagSpec) GetTagWithDefault(k, Default string) string { + v, ok := self.Tags[k] + if !ok { + return Default + } + + return v +} + +func (self *TagSpec) GetNameTag() (string) { + return self.GetTagWithDefault("Name", "") +} + +func (self *TagSpec) GetDescTag() (string){ + return self.GetTagWithDefault("Description", "") +} + +func AppendFilter(filters []*ec2.Filter, name string, values []string) []*ec2.Filter { f := &ec2.Filter{} v := make([]*string, len(values)) for _, value := range values { @@ -26,14 +104,14 @@ func AppendFilter(filters []*ec2.Filter, name string, values []string) ([]*ec2.F return append(filters, f) } -func AppendSingleValueFilter(filters []*ec2.Filter, name string, value string) ([]*ec2.Filter) { +func AppendSingleValueFilter(filters []*ec2.Filter, name string, value string) []*ec2.Filter { f := &ec2.Filter{} f.SetName(name) f.SetValues([]*string{&value}) return append(filters, f) } -func ConvertedList(list []string) ([]*string) { +func ConvertedList(list []string) []*string { result := make([]*string, 0) for _, item := range list { if len(item) > 0 { @@ -44,7 +122,7 @@ func ConvertedList(list []string) ([]*string) { return result } -func ConvertedPointList(list []*string) ([]string) { +func ConvertedPointList(list []*string) []string { result := make([]string, len(list)) for _, item := range list { if item != nil { @@ -105,7 +183,7 @@ func isYunionRuleAllPorts(r secrules.SecurityRule) bool { } } -func yunionPortRangeToAws(r secrules.SecurityRule) ([]portRange) { +func yunionPortRangeToAws(r secrules.SecurityRule) []portRange { // port 0 / -1 都代表所有端口 portranges := []portRange{} if len(r.Ports) == 0 { @@ -113,7 +191,7 @@ func yunionPortRangeToAws(r secrules.SecurityRule) ([]portRange) { if r.PortStart <= 0 { if r.Protocol == "tcp" || r.Protocol == "udp" { start = 0 - } else { + } else { start = -1 } } else { @@ -123,7 +201,7 @@ func yunionPortRangeToAws(r secrules.SecurityRule) ([]portRange) { if r.PortEnd <= 0 { if r.Protocol == "tcp" || r.Protocol == "udp" { end = 65535 - } else { + } else { end = -1 } } else { @@ -134,7 +212,7 @@ func yunionPortRangeToAws(r secrules.SecurityRule) ([]portRange) { } for _, port := range r.Ports { - if port <= 0 && ( r.Protocol == "tcp" || r.Protocol == "udp" ) { + if port <= 0 && (r.Protocol == "tcp" || r.Protocol == "udp") { portranges = append(portranges, portRange{0, 65535}) } else if port <= 0 { portranges = append(portranges, portRange{-1, -1}) @@ -147,7 +225,7 @@ func yunionPortRangeToAws(r secrules.SecurityRule) ([]portRange) { } // Security Rule Transform -func AwsIpPermissionToYunion(direction secrules.TSecurityRuleDirection,p ec2.IpPermission) ([]secrules.SecurityRule, error) { +func AwsIpPermissionToYunion(direction secrules.TSecurityRuleDirection, p ec2.IpPermission) ([]secrules.SecurityRule, error) { if len(p.UserIdGroupPairs) > 0 { return nil, fmt.Errorf("AwsIpPermissionToYunion not supported aws rule: UserIdGroupPairs specified") @@ -213,7 +291,7 @@ func YunionSecRuleToAws(rule secrules.SecurityRule) ([]ec2.IpPermission, error) } iprange := rule.IPNet.String() - if iprange == "" { + if iprange == "" { return nil, fmt.Errorf("YunionSecRuleToAws ignored ipnet should not be empty") } ipranges := []*ec2.IpRange{} @@ -223,10 +301,10 @@ func YunionSecRuleToAws(rule secrules.SecurityRule) ([]ec2.IpPermission, error) permissions := []ec2.IpPermission{} for _, port := range portranges { permission := ec2.IpPermission{ - FromPort: &port.Start, - IpProtocol: &rule.Protocol, - IpRanges: ipranges, - ToPort: &port.End, + FromPort: &port.Start, + IpProtocol: &rule.Protocol, + IpRanges: ipranges, + ToPort: &port.End, } permissions = append(permissions, permission) @@ -235,6 +313,6 @@ func YunionSecRuleToAws(rule secrules.SecurityRule) ([]ec2.IpPermission, error) return permissions, nil } -func awsTagSpecification(resourceType string,) { +func awsTagSpecification(resourceType string) { -} \ No newline at end of file +}