github.com/amanya/packer@v0.12.1-0.20161117214323-902ac5ab2eb6/builder/amazon/ebs/builder_acc_test.go (about) 1 package ebs 2 3 import ( 4 "fmt" 5 "os" 6 "testing" 7 8 "github.com/aws/aws-sdk-go/aws" 9 "github.com/aws/aws-sdk-go/aws/session" 10 "github.com/aws/aws-sdk-go/service/ec2" 11 "github.com/mitchellh/packer/builder/amazon/common" 12 builderT "github.com/mitchellh/packer/helper/builder/testing" 13 "github.com/mitchellh/packer/packer" 14 ) 15 16 func TestBuilderAcc_basic(t *testing.T) { 17 builderT.Test(t, builderT.TestCase{ 18 PreCheck: func() { testAccPreCheck(t) }, 19 Builder: &Builder{}, 20 Template: testBuilderAccBasic, 21 }) 22 } 23 24 func TestBuilderAcc_regionCopy(t *testing.T) { 25 builderT.Test(t, builderT.TestCase{ 26 PreCheck: func() { testAccPreCheck(t) }, 27 Builder: &Builder{}, 28 Template: testBuilderAccRegionCopy, 29 Check: checkRegionCopy([]string{"us-east-1", "us-west-2"}), 30 }) 31 } 32 33 func TestBuilderAcc_forceDeregister(t *testing.T) { 34 // Build the same AMI name twice, with force_deregister on the second run 35 builderT.Test(t, builderT.TestCase{ 36 PreCheck: func() { testAccPreCheck(t) }, 37 Builder: &Builder{}, 38 Template: buildForceDeregisterConfig("false", "dereg"), 39 SkipArtifactTeardown: true, 40 }) 41 42 builderT.Test(t, builderT.TestCase{ 43 PreCheck: func() { testAccPreCheck(t) }, 44 Builder: &Builder{}, 45 Template: buildForceDeregisterConfig("true", "dereg"), 46 }) 47 } 48 49 func TestBuilderAcc_amiSharing(t *testing.T) { 50 builderT.Test(t, builderT.TestCase{ 51 PreCheck: func() { testAccPreCheck(t) }, 52 Builder: &Builder{}, 53 Template: testBuilderAccSharing, 54 Check: checkAMISharing(2, "932021504756", "all"), 55 }) 56 } 57 58 func TestBuilderAcc_encryptedBoot(t *testing.T) { 59 builderT.Test(t, builderT.TestCase{ 60 PreCheck: func() { testAccPreCheck(t) }, 61 Builder: &Builder{}, 62 Template: testBuilderAccEncrypted, 63 Check: checkBootEncrypted(), 64 }) 65 } 66 67 func checkAMISharing(count int, uid, group string) builderT.TestCheckFunc { 68 return func(artifacts []packer.Artifact) error { 69 if len(artifacts) > 1 { 70 return fmt.Errorf("more than 1 artifact") 71 } 72 73 // Get the actual *Artifact pointer so we can access the AMIs directly 74 artifactRaw := artifacts[0] 75 artifact, ok := artifactRaw.(*common.Artifact) 76 if !ok { 77 return fmt.Errorf("unknown artifact: %#v", artifactRaw) 78 } 79 80 // describe the image, get block devices with a snapshot 81 ec2conn, _ := testEC2Conn() 82 imageResp, err := ec2conn.DescribeImageAttribute(&ec2.DescribeImageAttributeInput{ 83 Attribute: aws.String("launchPermission"), 84 ImageId: aws.String(artifact.Amis["us-east-1"]), 85 }) 86 87 if err != nil { 88 return fmt.Errorf("Error retrieving Image Attributes for AMI Artifact (%#v) in AMI Sharing Test: %s", artifact, err) 89 } 90 91 // Launch Permissions are in addition to the userid that created it, so if 92 // you add 3 additional ami_users, you expect 2 Launch Permissions here 93 if len(imageResp.LaunchPermissions) != count { 94 return fmt.Errorf("Error in Image Attributes, expected (%d) Launch Permissions, got (%d)", count, len(imageResp.LaunchPermissions)) 95 } 96 97 userFound := false 98 for _, lp := range imageResp.LaunchPermissions { 99 if lp.UserId != nil && uid == *lp.UserId { 100 userFound = true 101 } 102 } 103 104 if !userFound { 105 return fmt.Errorf("Error in Image Attributes, expected User ID (%s) to have Launch Permissions, but was not found", uid) 106 } 107 108 groupFound := false 109 for _, lp := range imageResp.LaunchPermissions { 110 if lp.Group != nil && group == *lp.Group { 111 groupFound = true 112 } 113 } 114 115 if !groupFound { 116 return fmt.Errorf("Error in Image Attributes, expected Group ID (%s) to have Launch Permissions, but was not found", group) 117 } 118 119 return nil 120 } 121 } 122 123 func checkRegionCopy(regions []string) builderT.TestCheckFunc { 124 return func(artifacts []packer.Artifact) error { 125 if len(artifacts) > 1 { 126 return fmt.Errorf("more than 1 artifact") 127 } 128 129 // Get the actual *Artifact pointer so we can access the AMIs directly 130 artifactRaw := artifacts[0] 131 artifact, ok := artifactRaw.(*common.Artifact) 132 if !ok { 133 return fmt.Errorf("unknown artifact: %#v", artifactRaw) 134 } 135 136 // Verify that we copied to only the regions given 137 regionSet := make(map[string]struct{}) 138 for _, r := range regions { 139 regionSet[r] = struct{}{} 140 } 141 for r := range artifact.Amis { 142 if _, ok := regionSet[r]; !ok { 143 return fmt.Errorf("unknown region: %s", r) 144 } 145 146 delete(regionSet, r) 147 } 148 if len(regionSet) > 0 { 149 return fmt.Errorf("didn't copy to: %#v", regionSet) 150 } 151 152 return nil 153 } 154 } 155 156 func checkBootEncrypted() builderT.TestCheckFunc { 157 return func(artifacts []packer.Artifact) error { 158 159 // Get the actual *Artifact pointer so we can access the AMIs directly 160 artifactRaw := artifacts[0] 161 artifact, ok := artifactRaw.(*common.Artifact) 162 if !ok { 163 return fmt.Errorf("unknown artifact: %#v", artifactRaw) 164 } 165 166 // describe the image, get block devices with a snapshot 167 ec2conn, _ := testEC2Conn() 168 imageResp, err := ec2conn.DescribeImages(&ec2.DescribeImagesInput{ 169 ImageIds: []*string{aws.String(artifact.Amis["us-east-1"])}, 170 }) 171 172 if err != nil { 173 return fmt.Errorf("Error retrieving Image Attributes for AMI (%s) in AMI Encrypted Boot Test: %s", artifact, err) 174 } 175 176 image := imageResp.Images[0] // Only requested a single AMI ID 177 178 rootDeviceName := image.RootDeviceName 179 180 for _, bd := range image.BlockDeviceMappings { 181 if *bd.DeviceName == *rootDeviceName { 182 if *bd.Ebs.Encrypted != true { 183 return fmt.Errorf("volume not encrypted: %s", *bd.Ebs.SnapshotId) 184 } 185 } 186 } 187 188 return nil 189 } 190 } 191 192 func testAccPreCheck(t *testing.T) { 193 if v := os.Getenv("AWS_ACCESS_KEY_ID"); v == "" { 194 t.Fatal("AWS_ACCESS_KEY_ID must be set for acceptance tests") 195 } 196 197 if v := os.Getenv("AWS_SECRET_ACCESS_KEY"); v == "" { 198 t.Fatal("AWS_SECRET_ACCESS_KEY must be set for acceptance tests") 199 } 200 } 201 202 func testEC2Conn() (*ec2.EC2, error) { 203 access := &common.AccessConfig{RawRegion: "us-east-1"} 204 config, err := access.Config() 205 if err != nil { 206 return nil, err 207 } 208 209 session, err := session.NewSession(config) 210 if err != nil { 211 return nil, err 212 } 213 return ec2.New(session), nil 214 } 215 216 const testBuilderAccBasic = ` 217 { 218 "builders": [{ 219 "type": "test", 220 "region": "us-east-1", 221 "instance_type": "m3.medium", 222 "source_ami": "ami-76b2a71e", 223 "ssh_username": "ubuntu", 224 "ami_name": "packer-test {{timestamp}}" 225 }] 226 } 227 ` 228 229 const testBuilderAccRegionCopy = ` 230 { 231 "builders": [{ 232 "type": "test", 233 "region": "us-east-1", 234 "instance_type": "m3.medium", 235 "source_ami": "ami-76b2a71e", 236 "ssh_username": "ubuntu", 237 "ami_name": "packer-test {{timestamp}}", 238 "ami_regions": ["us-east-1", "us-west-2"] 239 }] 240 } 241 ` 242 243 const testBuilderAccForceDeregister = ` 244 { 245 "builders": [{ 246 "type": "test", 247 "region": "us-east-1", 248 "instance_type": "m3.medium", 249 "source_ami": "ami-76b2a71e", 250 "ssh_username": "ubuntu", 251 "force_deregister": "%s", 252 "ami_name": "packer-test-%s" 253 }] 254 } 255 ` 256 257 // share with catsby 258 const testBuilderAccSharing = ` 259 { 260 "builders": [{ 261 "type": "test", 262 "region": "us-east-1", 263 "instance_type": "m3.medium", 264 "source_ami": "ami-76b2a71e", 265 "ssh_username": "ubuntu", 266 "ami_name": "packer-test {{timestamp}}", 267 "ami_users":["932021504756"], 268 "ami_groups":["all"] 269 }] 270 } 271 ` 272 273 const testBuilderAccEncrypted = ` 274 { 275 "builders": [{ 276 "type": "test", 277 "region": "us-east-1", 278 "instance_type": "m3.medium", 279 "source_ami":"ami-c15bebaa", 280 "ssh_username": "ubuntu", 281 "ami_name": "packer-enc-test {{timestamp}}", 282 "encrypt_boot": true 283 }] 284 } 285 ` 286 287 func buildForceDeregisterConfig(name, flag string) string { 288 return fmt.Sprintf(testBuilderAccForceDeregister, name, flag) 289 }