github.phpd.cn/hashicorp/packer@v1.3.2/builder/amazon/common/ami_config_test.go (about) 1 package common 2 3 import ( 4 "fmt" 5 "reflect" 6 "testing" 7 8 "github.com/aws/aws-sdk-go/aws" 9 "github.com/aws/aws-sdk-go/service/ec2" 10 "github.com/aws/aws-sdk-go/service/ec2/ec2iface" 11 ) 12 13 func testAMIConfig() *AMIConfig { 14 return &AMIConfig{ 15 AMIName: "foo", 16 } 17 } 18 19 func getFakeAccessConfig(region string) *AccessConfig { 20 c := testAccessConfig() 21 c.RawRegion = region 22 return c 23 } 24 25 func TestAMIConfigPrepare_name(t *testing.T) { 26 c := testAMIConfig() 27 accessConf := testAccessConfig() 28 c.AMISkipRegionValidation = true 29 if err := c.Prepare(accessConf, nil); err != nil { 30 t.Fatalf("shouldn't have err: %s", err) 31 } 32 33 c.AMIName = "" 34 if err := c.Prepare(accessConf, nil); err == nil { 35 t.Fatal("should have error") 36 } 37 } 38 39 type mockEC2Client struct { 40 ec2iface.EC2API 41 } 42 43 func (m *mockEC2Client) DescribeRegions(*ec2.DescribeRegionsInput) (*ec2.DescribeRegionsOutput, error) { 44 return &ec2.DescribeRegionsOutput{ 45 Regions: []*ec2.Region{ 46 {RegionName: aws.String("us-east-1")}, 47 {RegionName: aws.String("us-east-2")}, 48 {RegionName: aws.String("us-west-1")}, 49 }, 50 }, nil 51 } 52 53 func TestAMIConfigPrepare_regions(t *testing.T) { 54 c := testAMIConfig() 55 c.AMIRegions = nil 56 c.AMISkipRegionValidation = true 57 58 var errs []error 59 var err error 60 accessConf := testAccessConfig() 61 mockConn := &mockEC2Client{} 62 if errs = c.prepareRegions(accessConf); len(errs) > 0 { 63 t.Fatalf("shouldn't have err: %#v", errs) 64 } 65 66 c.AMISkipRegionValidation = false 67 c.AMIRegions, err = listEC2Regions(mockConn) 68 if err != nil { 69 t.Fatalf("shouldn't have err: %s", err.Error()) 70 } 71 if errs = c.prepareRegions(accessConf); len(errs) > 0 { 72 t.Fatalf("shouldn't have err: %#v", errs) 73 } 74 75 c.AMIRegions = []string{"foo"} 76 if errs = c.prepareRegions(accessConf); len(errs) == 0 { 77 t.Fatal("should have error") 78 } 79 errs = errs[:0] 80 81 c.AMIRegions = []string{"us-east-1", "us-west-1", "us-east-1"} 82 if errs = c.prepareRegions(accessConf); len(errs) > 0 { 83 t.Fatalf("bad: %s", errs[0]) 84 } 85 86 expected := []string{"us-east-1", "us-west-1"} 87 if !reflect.DeepEqual(c.AMIRegions, expected) { 88 t.Fatalf("bad: %#v", c.AMIRegions) 89 } 90 91 c.AMIRegions = []string{"custom"} 92 c.AMISkipRegionValidation = true 93 if errs = c.prepareRegions(accessConf); len(errs) > 0 { 94 t.Fatal("shouldn't have error") 95 } 96 c.AMISkipRegionValidation = false 97 98 c.AMIRegions = []string{"us-east-1", "us-east-2", "us-west-1"} 99 c.AMIRegionKMSKeyIDs = map[string]string{ 100 "us-east-1": "123-456-7890", 101 "us-west-1": "789-012-3456", 102 "us-east-2": "456-789-0123", 103 } 104 if errs = c.prepareRegions(accessConf); len(errs) > 0 { 105 t.Fatal(fmt.Sprintf("shouldn't have error: %s", errs[0])) 106 } 107 108 c.AMIRegions = []string{"us-east-1", "us-east-2", "us-west-1"} 109 c.AMIRegionKMSKeyIDs = map[string]string{ 110 "us-east-1": "123-456-7890", 111 "us-west-1": "789-012-3456", 112 "us-east-2": "", 113 } 114 if errs = c.prepareRegions(accessConf); len(errs) > 0 { 115 t.Fatal("should have passed; we are able to use default KMS key if not sharing") 116 } 117 118 c.SnapshotUsers = []string{"user-foo", "user-bar"} 119 c.AMIRegions = []string{"us-east-1", "us-east-2", "us-west-1"} 120 c.AMIRegionKMSKeyIDs = map[string]string{ 121 "us-east-1": "123-456-7890", 122 "us-west-1": "789-012-3456", 123 "us-east-2": "", 124 } 125 if errs = c.prepareRegions(accessConf); len(errs) > 0 { 126 t.Fatal("should have an error b/c can't use default KMS key if sharing") 127 } 128 129 c.AMIRegions = []string{"us-east-1", "us-west-1"} 130 c.AMIRegionKMSKeyIDs = map[string]string{ 131 "us-east-1": "123-456-7890", 132 "us-west-1": "789-012-3456", 133 "us-east-2": "456-789-0123", 134 } 135 if errs = c.prepareRegions(accessConf); len(errs) > 0 { 136 t.Fatal("should have error b/c theres a region in the key map that isn't in ami_regions") 137 } 138 139 c.AMIRegions = []string{"us-east-1", "us-west-1", "us-east-2"} 140 c.AMIRegionKMSKeyIDs = map[string]string{ 141 "us-east-1": "123-456-7890", 142 "us-west-1": "789-012-3456", 143 } 144 145 c.AMISkipRegionValidation = true 146 if err := c.Prepare(accessConf, nil); err == nil { 147 t.Fatal("should have error b/c theres a region in in ami_regions that isn't in the key map") 148 } 149 c.AMISkipRegionValidation = false 150 151 c.SnapshotUsers = []string{"foo", "bar"} 152 c.AMIKmsKeyId = "123-abc-456" 153 c.AMIEncryptBootVolume = true 154 c.AMIRegions = []string{"us-east-1", "us-west-1"} 155 c.AMIRegionKMSKeyIDs = map[string]string{ 156 "us-east-1": "123-456-7890", 157 "us-west-1": "", 158 } 159 if errs = c.prepareRegions(accessConf); len(errs) > 0 { 160 t.Fatal("should have error b/c theres a region in in ami_regions that isn't in the key map") 161 } 162 163 // allow rawregion to exist in ami_regions list. 164 accessConf = getFakeAccessConfig("us-east-1") 165 c.AMIRegions = []string{"us-east-1", "us-west-1", "us-east-2"} 166 c.AMIRegionKMSKeyIDs = nil 167 if errs = c.prepareRegions(accessConf); len(errs) > 0 { 168 t.Fatal("should allow user to have the raw region in ami_regions") 169 } 170 171 } 172 173 func TestAMIConfigPrepare_Share_EncryptedBoot(t *testing.T) { 174 c := testAMIConfig() 175 c.AMISkipRegionValidation = true 176 c.AMIUsers = []string{"testAccountID"} 177 c.AMIEncryptBootVolume = true 178 179 accessConf := testAccessConfig() 180 181 c.AMIKmsKeyId = "" 182 if err := c.Prepare(accessConf, nil); err == nil { 183 t.Fatal("shouldn't be able to share ami with encrypted boot volume") 184 } 185 186 c.AMIKmsKeyId = "89c3fb9a-de87-4f2a-aedc-fddc5138193c" 187 if err := c.Prepare(accessConf, nil); err == nil { 188 t.Fatal("shouldn't be able to share ami with encrypted boot volume") 189 } 190 } 191 192 func TestAMINameValidation(t *testing.T) { 193 c := testAMIConfig() 194 c.AMISkipRegionValidation = true 195 196 accessConf := testAccessConfig() 197 198 c.AMIName = "aa" 199 if err := c.Prepare(accessConf, nil); err == nil { 200 t.Fatal("shouldn't be able to have an ami name with less than 3 characters") 201 } 202 203 var longAmiName string 204 for i := 0; i < 129; i++ { 205 longAmiName += "a" 206 } 207 c.AMIName = longAmiName 208 if err := c.Prepare(accessConf, nil); err == nil { 209 t.Fatal("shouldn't be able to have an ami name with great than 128 characters") 210 } 211 212 c.AMIName = "+aaa" 213 if err := c.Prepare(accessConf, nil); err == nil { 214 t.Fatal("shouldn't be able to have an ami name with invalid characters") 215 } 216 217 c.AMIName = "fooBAR1()[] ./-'@_" 218 if err := c.Prepare(accessConf, nil); err != nil { 219 t.Fatal("should be able to use all of the allowed AMI characters") 220 } 221 222 c.AMIName = `xyz-base-2017-04-05-1934` 223 if err := c.Prepare(accessConf, nil); err != nil { 224 t.Fatalf("expected `xyz-base-2017-04-05-1934` to pass validation.") 225 } 226 227 }