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  }