sigs.k8s.io/cluster-api-provider-aws@v1.5.5/cmd/clusterawsadm/ami/list.go (about) 1 /* 2 Copyright 2021 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package ami 18 19 import ( 20 "fmt" 21 "time" 22 23 "github.com/aws/aws-sdk-go/aws" 24 "github.com/aws/aws-sdk-go/aws/session" 25 "github.com/aws/aws-sdk-go/service/ec2" 26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 27 28 amiv1 "sigs.k8s.io/cluster-api-provider-aws/cmd/clusterawsadm/api/ami/v1beta1" 29 ) 30 31 // ListInput defines the specs required to construct an AWSAMIList. 32 type ListInput struct { 33 Region string 34 KubernetesVersion string 35 OperatingSystem string 36 OwnerID string 37 } 38 39 const lastNReleases = 3 40 41 // List will create an AWSAMIList from a given ListInput. 42 func List(input ListInput) (*amiv1.AWSAMIList, error) { 43 supportedOsList := []string{} 44 if input.OperatingSystem == "" { 45 supportedOsList = getSupportedOsList() 46 } else { 47 supportedOsList = append(supportedOsList, input.OperatingSystem) 48 } 49 imageRegionList := []string{} 50 if input.Region == "" { 51 imageRegionList = getimageRegionList() 52 } else { 53 imageRegionList = append(imageRegionList, input.Region) 54 } 55 56 supportedVersions := []string{} 57 if input.KubernetesVersion == "" { 58 var err error 59 supportedVersions, err = getSupportedKubernetesVersions(lastNReleases) 60 if err != nil { 61 fmt.Println("Failed to calculate supported Kubernetes versions") 62 return nil, err 63 } 64 } else { 65 supportedVersions = append(supportedVersions, input.KubernetesVersion) 66 } 67 listByVersion := amiv1.AWSAMIList{ 68 TypeMeta: metav1.TypeMeta{ 69 Kind: amiv1.AWSAMIListKind, 70 APIVersion: amiv1.SchemeGroupVersion.String(), 71 }, 72 Items: []amiv1.AWSAMI{}, 73 } 74 for _, region := range imageRegionList { 75 imageMap := make(map[string][]*ec2.Image) 76 sess, err := session.NewSessionWithOptions(session.Options{ 77 SharedConfigState: session.SharedConfigEnable, 78 Config: aws.Config{Region: aws.String(region)}, 79 }) 80 if err != nil { 81 return nil, err 82 } 83 84 ec2Client := ec2.New(sess) 85 imagesForRegion, err := getAllImages(ec2Client, input.OwnerID) 86 if err != nil { 87 return nil, err 88 } 89 90 for key, image := range imagesForRegion { 91 images, ok := imageMap[key] 92 if !ok { 93 images = make([]*ec2.Image, 0) 94 } 95 imageMap[key] = append(images, image...) 96 } 97 for _, version := range supportedVersions { 98 for _, os := range supportedOsList { 99 image, err := findAMI(imageMap, os, version) 100 if err != nil { 101 return nil, err 102 } 103 if image == nil { 104 continue 105 } 106 creationTimestamp, err := time.Parse(time.RFC3339, aws.StringValue(image.CreationDate)) 107 if err != nil { 108 return nil, err 109 } 110 111 listByVersion.Items = append(listByVersion.Items, amiv1.AWSAMI{ 112 TypeMeta: metav1.TypeMeta{ 113 Kind: amiv1.AWSAMIKind, 114 APIVersion: amiv1.SchemeGroupVersion.String(), 115 }, 116 ObjectMeta: metav1.ObjectMeta{ 117 Name: aws.StringValue(image.Name), 118 CreationTimestamp: metav1.NewTime(creationTimestamp), 119 }, 120 Spec: amiv1.AWSAMISpec{ 121 OS: os, 122 Region: region, 123 ImageID: aws.StringValue(image.ImageId), 124 KubernetesVersion: version, 125 }, 126 }) 127 } 128 } 129 } 130 131 return &listByVersion, nil 132 }