Merge branch 'liamjbennett-codebuild'

This commit is contained in:
stack72 2017-02-02 16:14:33 +00:00
commit a089539d3b
No known key found for this signature in database
GPG Key ID: 8619A619B085CB16
11 changed files with 4612 additions and 3 deletions

View File

@ -24,6 +24,7 @@ import (
"github.com/aws/aws-sdk-go/service/cloudwatch"
"github.com/aws/aws-sdk-go/service/cloudwatchevents"
"github.com/aws/aws-sdk-go/service/cloudwatchlogs"
"github.com/aws/aws-sdk-go/service/codebuild"
"github.com/aws/aws-sdk-go/service/codecommit"
"github.com/aws/aws-sdk-go/service/codedeploy"
"github.com/aws/aws-sdk-go/service/databasemigrationservice"
@ -146,6 +147,7 @@ type AWSClient struct {
lightsailconn *lightsail.Lightsail
opsworksconn *opsworks.OpsWorks
glacierconn *glacier.Glacier
codebuildconn *codebuild.CodeBuild
codedeployconn *codedeploy.CodeDeploy
codecommitconn *codecommit.CodeCommit
sfnconn *sfn.SFN
@ -277,6 +279,7 @@ func (c *Config) Client() (interface{}, error) {
client.cloudwatcheventsconn = cloudwatchevents.New(sess)
client.cloudwatchlogsconn = cloudwatchlogs.New(sess)
client.codecommitconn = codecommit.New(sess)
client.codebuildconn = codebuild.New(sess)
client.codedeployconn = codedeploy.New(sess)
client.dmsconn = databasemigrationservice.New(sess)
client.dsconn = directoryservice.New(sess)

View File

@ -238,6 +238,7 @@ func Provider() terraform.ResourceProvider {
"aws_codedeploy_deployment_group": resourceAwsCodeDeployDeploymentGroup(),
"aws_codecommit_repository": resourceAwsCodeCommitRepository(),
"aws_codecommit_trigger": resourceAwsCodeCommitTrigger(),
"aws_codebuild_project": resourceAwsCodeBuildProject(),
"aws_customer_gateway": resourceAwsCustomerGateway(),
"aws_db_event_subscription": resourceAwsDbEventSubscription(),
"aws_db_instance": resourceAwsDbInstance(),

View File

@ -0,0 +1,713 @@
package aws
import (
"bytes"
"fmt"
"log"
"regexp"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/codebuild"
"github.com/hashicorp/terraform/helper/hashcode"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
)
func resourceAwsCodeBuildProject() *schema.Resource {
return &schema.Resource{
Create: resourceAwsCodeBuildProjectCreate,
Read: resourceAwsCodeBuildProjectRead,
Update: resourceAwsCodeBuildProjectUpdate,
Delete: resourceAwsCodeBuildProjectDelete,
Schema: map[string]*schema.Schema{
"artifacts": &schema.Schema{
Type: schema.TypeSet,
Required: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Optional: true,
},
"location": {
Type: schema.TypeString,
Optional: true,
},
"namespace_type": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validateAwsCodeBuildArifactsNamespaceType,
},
"packaging": {
Type: schema.TypeString,
Optional: true,
},
"path": {
Type: schema.TypeString,
Optional: true,
},
"type": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validateAwsCodeBuildArifactsType,
},
},
},
Set: resourceAwsCodeBuildProjectArtifactsHash,
},
"description": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ValidateFunc: validateAwsCodeBuildProjectDescription,
},
"encryption_key": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"environment": &schema.Schema{
Type: schema.TypeSet,
Required: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"compute_type": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validateAwsCodeBuildEnvironmentComputeType,
},
"environment_variable": &schema.Schema{
Type: schema.TypeList,
Optional: true,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
},
"value": {
Type: schema.TypeString,
Required: true,
},
},
},
},
"image": {
Type: schema.TypeString,
Required: true,
},
"type": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validateAwsCodeBuildEnvironmentType,
},
},
},
Set: resourceAwsCodeBuildProjectEnvironmentHash,
},
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validateAwsCodeBuildProjectName,
},
"service_role": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"source": &schema.Schema{
Type: schema.TypeSet,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"auth": &schema.Schema{
Type: schema.TypeSet,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"resource": {
Type: schema.TypeString,
Optional: true,
},
"type": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validateAwsCodeBuildSourceAuthType,
},
},
},
Optional: true,
},
"buildspec": {
Type: schema.TypeString,
Optional: true,
},
"location": {
Type: schema.TypeString,
Optional: true,
},
"type": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validateAwsCodeBuildSourceType,
},
},
},
Required: true,
MaxItems: 1,
},
"timeout": {
Type: schema.TypeInt,
Optional: true,
ValidateFunc: validateAwsCodeBuildTimeout,
},
"tags": tagsSchema(),
},
}
}
func resourceAwsCodeBuildProjectCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).codebuildconn
projectEnv := expandProjectEnvironment(d)
projectSource := expandProjectSource(d)
projectArtifacts := expandProjectArtifacts(d)
params := &codebuild.CreateProjectInput{
Environment: projectEnv,
Name: aws.String(d.Get("name").(string)),
Source: &projectSource,
Artifacts: &projectArtifacts,
}
if v, ok := d.GetOk("description"); ok {
params.Description = aws.String(v.(string))
}
if v, ok := d.GetOk("encryption_key"); ok {
params.EncryptionKey = aws.String(v.(string))
}
if v, ok := d.GetOk("service_role"); ok {
params.ServiceRole = aws.String(v.(string))
}
if v, ok := d.GetOk("timeout"); ok {
params.TimeoutInMinutes = aws.Int64(int64(v.(int)))
}
var resp *codebuild.CreateProjectOutput
err := resource.Retry(30*time.Second, func() *resource.RetryError {
var err error
resp, err = conn.CreateProject(params)
if err != nil {
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
})
if err != nil {
return fmt.Errorf("[ERROR] Error creating CodeBuild project: %s", err)
}
d.SetId(*resp.Project.Arn)
return resourceAwsCodeBuildProjectUpdate(d, meta)
}
func expandProjectArtifacts(d *schema.ResourceData) codebuild.ProjectArtifacts {
configs := d.Get("artifacts").(*schema.Set).List()
data := configs[0].(map[string]interface{})
projectArtifacts := codebuild.ProjectArtifacts{
Type: aws.String(data["type"].(string)),
}
if data["location"].(string) != "" {
projectArtifacts.Location = aws.String(data["location"].(string))
}
if data["name"].(string) != "" {
projectArtifacts.Name = aws.String(data["name"].(string))
}
if data["namespace_type"].(string) != "" {
projectArtifacts.NamespaceType = aws.String(data["namespace_type"].(string))
}
if data["packaging"].(string) != "" {
projectArtifacts.Packaging = aws.String(data["packaging"].(string))
}
if data["path"].(string) != "" {
projectArtifacts.Path = aws.String(data["path"].(string))
}
return projectArtifacts
}
func expandProjectEnvironment(d *schema.ResourceData) *codebuild.ProjectEnvironment {
configs := d.Get("environment").(*schema.Set).List()
projectEnv := &codebuild.ProjectEnvironment{}
envConfig := configs[0].(map[string]interface{})
if v := envConfig["compute_type"]; v != nil {
projectEnv.ComputeType = aws.String(v.(string))
}
if v := envConfig["image"]; v != nil {
projectEnv.Image = aws.String(v.(string))
}
if v := envConfig["type"]; v != nil {
projectEnv.Type = aws.String(v.(string))
}
if v := envConfig["environment_variable"]; v != nil {
envVariables := v.([]interface{})
if len(envVariables) > 0 {
projectEnvironmentVariables := make([]*codebuild.EnvironmentVariable, 0, len(envVariables))
for _, envVariablesConfig := range envVariables {
config := envVariablesConfig.(map[string]interface{})
projectEnvironmentVar := &codebuild.EnvironmentVariable{}
if v := config["name"].(string); v != "" {
projectEnvironmentVar.Name = &v
}
if v := config["value"].(string); v != "" {
projectEnvironmentVar.Value = &v
}
projectEnvironmentVariables = append(projectEnvironmentVariables, projectEnvironmentVar)
}
projectEnv.EnvironmentVariables = projectEnvironmentVariables
}
}
return projectEnv
}
func expandProjectSource(d *schema.ResourceData) codebuild.ProjectSource {
configs := d.Get("source").(*schema.Set).List()
projectSource := codebuild.ProjectSource{}
for _, configRaw := range configs {
data := configRaw.(map[string]interface{})
sourceType := data["type"].(string)
location := data["location"].(string)
buildspec := data["buildspec"].(string)
projectSource = codebuild.ProjectSource{
Type: &sourceType,
Location: &location,
Buildspec: &buildspec,
}
if v, ok := data["auth"]; ok {
if len(v.(*schema.Set).List()) > 0 {
auth := v.(*schema.Set).List()[0].(map[string]interface{})
projectSource.Auth = &codebuild.SourceAuth{
Type: aws.String(auth["type"].(string)),
Resource: aws.String(auth["resource"].(string)),
}
}
}
}
return projectSource
}
func resourceAwsCodeBuildProjectRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).codebuildconn
resp, err := conn.BatchGetProjects(&codebuild.BatchGetProjectsInput{
Names: []*string{
aws.String(d.Id()),
},
})
if err != nil {
return fmt.Errorf("[ERROR] Error retreiving Projects: %q", err)
}
// if nothing was found, then return no state
if len(resp.Projects) == 0 {
log.Printf("[INFO]: No projects were found, removing from state")
d.SetId("")
return nil
}
project := resp.Projects[0]
if err := d.Set("artifacts", flattenAwsCodebuildProjectArtifacts(project.Artifacts)); err != nil {
return err
}
if err := d.Set("environment", schema.NewSet(resourceAwsCodeBuildProjectEnvironmentHash, flattenAwsCodebuildProjectEnvironment(project.Environment))); err != nil {
return err
}
if err := d.Set("source", flattenAwsCodebuildProjectSource(project.Source)); err != nil {
return err
}
d.Set("description", project.Description)
d.Set("encryption_key", project.EncryptionKey)
d.Set("name", project.Name)
d.Set("service_role", project.ServiceRole)
d.Set("timeout", project.TimeoutInMinutes)
if err := d.Set("tags", tagsToMapCodeBuild(project.Tags)); err != nil {
return err
}
return nil
}
func resourceAwsCodeBuildProjectUpdate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).codebuildconn
params := &codebuild.UpdateProjectInput{
Name: aws.String(d.Get("name").(string)),
}
if d.HasChange("environment") {
projectEnv := expandProjectEnvironment(d)
params.Environment = projectEnv
}
if d.HasChange("source") {
projectSource := expandProjectSource(d)
params.Source = &projectSource
}
if d.HasChange("artifacts") {
projectArtifacts := expandProjectArtifacts(d)
params.Artifacts = &projectArtifacts
}
if d.HasChange("description") {
params.Description = aws.String(d.Get("description").(string))
}
if d.HasChange("encryption_key") {
params.EncryptionKey = aws.String(d.Get("encryption_key").(string))
}
if d.HasChange("service_role") {
params.ServiceRole = aws.String(d.Get("service_role").(string))
}
if d.HasChange("timeout") {
params.TimeoutInMinutes = aws.Int64(int64(d.Get("timeout").(int)))
}
if d.HasChange("tags") {
params.Tags = tagsFromMapCodeBuild(d.Get("tags").(map[string]interface{}))
}
_, err := conn.UpdateProject(params)
if err != nil {
return fmt.Errorf(
"[ERROR] Error updating CodeBuild project (%s): %s",
d.Id(), err)
}
return resourceAwsCodeBuildProjectRead(d, meta)
}
func resourceAwsCodeBuildProjectDelete(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).codebuildconn
_, err := conn.DeleteProject(&codebuild.DeleteProjectInput{
Name: aws.String(d.Id()),
})
if err != nil {
return err
}
d.SetId("")
return nil
}
func flattenAwsCodebuildProjectArtifacts(artifacts *codebuild.ProjectArtifacts) *schema.Set {
artifactSet := schema.Set{
F: resourceAwsCodeBuildProjectArtifactsHash,
}
values := map[string]interface{}{}
values["type"] = *artifacts.Type
if artifacts.Location != nil {
values["location"] = *artifacts.Location
}
if artifacts.Name != nil {
values["name"] = *artifacts.Name
}
if artifacts.NamespaceType != nil {
values["namespace_type"] = *artifacts.NamespaceType
}
if artifacts.Packaging != nil {
values["packaging"] = *artifacts.Packaging
}
if artifacts.Path != nil {
values["path"] = *artifacts.Path
}
artifactSet.Add(values)
return &artifactSet
}
func flattenAwsCodebuildProjectEnvironment(environment *codebuild.ProjectEnvironment) []interface{} {
envConfig := map[string]interface{}{}
envConfig["type"] = *environment.Type
envConfig["compute_type"] = *environment.ComputeType
envConfig["image"] = *environment.Image
if environment.EnvironmentVariables != nil {
envConfig["environment_variable"] = environmentVariablesToMap(environment.EnvironmentVariables)
}
return []interface{}{envConfig}
}
func flattenAwsCodebuildProjectSource(source *codebuild.ProjectSource) *schema.Set {
sourceSet := schema.Set{
F: resourceAwsCodeBuildProjectSourceHash,
}
sourceConfig := map[string]interface{}{}
sourceConfig["type"] = *source.Type
if source.Auth != nil {
sourceConfig["auth"] = sourceAuthToMap(source.Auth)
}
if source.Buildspec != nil {
sourceConfig["buildspec"] = *source.Buildspec
}
if source.Location != nil {
sourceConfig["location"] = *source.Location
}
sourceSet.Add(sourceConfig)
return &sourceSet
}
func resourceAwsCodeBuildProjectArtifactsHash(v interface{}) int {
var buf bytes.Buffer
m := v.(map[string]interface{})
artifactType := m["type"].(string)
buf.WriteString(fmt.Sprintf("%s-", artifactType))
return hashcode.String(buf.String())
}
func resourceAwsCodeBuildProjectEnvironmentHash(v interface{}) int {
var buf bytes.Buffer
m := v.(map[string]interface{})
environmentType := m["type"].(string)
computeType := m["compute_type"].(string)
image := m["image"].(string)
buf.WriteString(fmt.Sprintf("%s-", environmentType))
buf.WriteString(fmt.Sprintf("%s-", computeType))
buf.WriteString(fmt.Sprintf("%s-", image))
return hashcode.String(buf.String())
}
func resourceAwsCodeBuildProjectSourceHash(v interface{}) int {
var buf bytes.Buffer
m := v.(map[string]interface{})
sourceType := m["type"].(string)
buildspec := m["buildspec"].(string)
location := m["location"].(string)
buf.WriteString(fmt.Sprintf("%s-", sourceType))
buf.WriteString(fmt.Sprintf("%s-", buildspec))
buf.WriteString(fmt.Sprintf("%s-", location))
return hashcode.String(buf.String())
}
func environmentVariablesToMap(environmentVariables []*codebuild.EnvironmentVariable) []map[string]interface{} {
envVariables := make([]map[string]interface{}, len(environmentVariables))
if len(environmentVariables) > 0 {
for i := 0; i < len(environmentVariables); i++ {
env := environmentVariables[i]
item := make(map[string]interface{})
item["name"] = *env.Name
item["value"] = *env.Value
envVariables = append(envVariables, item)
}
}
return envVariables
}
func sourceAuthToMap(sourceAuth *codebuild.SourceAuth) map[string]interface{} {
auth := map[string]interface{}{}
auth["type"] = *sourceAuth.Type
if sourceAuth.Type != nil {
auth["resource"] = *sourceAuth.Resource
}
return auth
}
func validateAwsCodeBuildArifactsType(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)
types := map[string]bool{
"CODEPIPELINE": true,
"NO_ARTIFACTS": true,
"S3": true,
}
if !types[value] {
errors = append(errors, fmt.Errorf("CodeBuild: Arifacts Type can only be CODEPIPELINE / NO_ARTIFACTS / S3"))
}
return
}
func validateAwsCodeBuildArifactsNamespaceType(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)
types := map[string]bool{
"NONE": true,
"BUILD_ID": true,
}
if !types[value] {
errors = append(errors, fmt.Errorf("CodeBuild: Arifacts Namespace Type can only be NONE / BUILD_ID"))
}
return
}
func validateAwsCodeBuildProjectName(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)
if !regexp.MustCompile(`^[A-Za-z0-9]`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"first character of %q must be a letter or number", value))
}
if !regexp.MustCompile(`^[A-Za-z0-9\-_]+$`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"only alphanumeric characters, hyphens and underscores allowed in %q", value))
}
if len(value) > 255 {
errors = append(errors, fmt.Errorf(
"%q cannot be greater than 255 characters", value))
}
return
}
func validateAwsCodeBuildProjectDescription(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)
if len(value) > 255 {
errors = append(errors, fmt.Errorf("%q cannot be greater than 255 characters", value))
}
return
}
func validateAwsCodeBuildEnvironmentComputeType(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)
types := map[string]bool{
"BUILD_GENERAL1_SMALL": true,
"BUILD_GENERAL1_MEDIUM": true,
"BUILD_GENERAL1_LARGE": true,
}
if !types[value] {
errors = append(errors, fmt.Errorf("CodeBuild: Environment Compute Type can only be BUILD_GENERAL1_SMALL / BUILD_GENERAL1_MEDIUM / BUILD_GENERAL1_LARGE"))
}
return
}
func validateAwsCodeBuildEnvironmentType(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)
types := map[string]bool{
"LINUX_CONTAINER": true,
}
if !types[value] {
errors = append(errors, fmt.Errorf("CodeBuild: Environment Type can only be LINUX_CONTAINER"))
}
return
}
func validateAwsCodeBuildSourceType(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)
types := map[string]bool{
"CODECOMMIT": true,
"CODEPIPELINE": true,
"GITHUB": true,
"S3": true,
}
if !types[value] {
errors = append(errors, fmt.Errorf("CodeBuild: Source Type can only be CODECOMMIT / CODEPIPELINE / GITHUB / S3"))
}
return
}
func validateAwsCodeBuildSourceAuthType(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)
types := map[string]bool{
"OAUTH": true,
}
if !types[value] {
errors = append(errors, fmt.Errorf("CodeBuild: Source Auth Type can only be OAUTH"))
}
return
}
func validateAwsCodeBuildTimeout(v interface{}, k string) (ws []string, errors []error) {
value := v.(int)
if value < 5 || value > 480 {
errors = append(errors, fmt.Errorf("%q must be greater than 5 minutes and less than 480 minutes (8 hours)", value))
}
return
}

View File

@ -0,0 +1,367 @@
package aws
import (
"fmt"
"strings"
"testing"
"unicode"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/codebuild"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)
func TestAccAWSCodeBuildProject_basic(t *testing.T) {
name := acctest.RandString(10)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSCodeBuildProjectDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccAWSCodeBuildProjectConfig_basic(name),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSCodeBuildProjectExists("aws_codebuild_project.foo"),
),
},
},
})
}
func TestAccAWSCodeBuildProject_artifactsTypeValidation(t *testing.T) {
cases := []struct {
Value string
ErrCount int
}{
{Value: "CODEPIPELINE", ErrCount: 0},
{Value: "NO_ARTIFACTS", ErrCount: 0},
{Value: "S3", ErrCount: 0},
{Value: "XYZ", ErrCount: 1},
}
for _, tc := range cases {
_, errors := validateAwsCodeBuildArifactsType(tc.Value, "aws_codebuild_project")
if len(errors) != tc.ErrCount {
t.Fatalf("Expected the AWS CodeBuild project artifacts type to trigger a validation error")
}
}
}
func TestAccAWSCodeBuildProject_artifactsNamespaceTypeValidation(t *testing.T) {
cases := []struct {
Value string
ErrCount int
}{
{Value: "NONE", ErrCount: 0},
{Value: "BUILD_ID", ErrCount: 0},
{Value: "XYZ", ErrCount: 1},
}
for _, tc := range cases {
_, errors := validateAwsCodeBuildArifactsNamespaceType(tc.Value, "aws_codebuild_project")
if len(errors) != tc.ErrCount {
t.Fatalf("Expected the AWS CodeBuild project artifacts namepsace_type to trigger a validation error")
}
}
}
func longTestData() string {
data := `
test-test-test-test-test-test-test-test-test-test-
test-test-test-test-test-test-test-test-test-test-
test-test-test-test-test-test-test-test-test-test-
test-test-test-test-test-test-test-test-test-test-
test-test-test-test-test-test-test-test-test-test-
test-test-test-test-test-test-test-test-test-test-
`
return strings.Map(func(r rune) rune {
if unicode.IsSpace(r) {
return -1
}
return r
}, data)
}
func TestAccAWSCodeBuildProject_nameValidation(t *testing.T) {
cases := []struct {
Value string
ErrCount int
}{
{Value: "_test", ErrCount: 1},
{Value: "test", ErrCount: 0},
{Value: "1_test", ErrCount: 0},
{Value: "test**1", ErrCount: 1},
{Value: longTestData(), ErrCount: 1},
}
for _, tc := range cases {
_, errors := validateAwsCodeBuildProjectName(tc.Value, "aws_codebuild_project")
if len(errors) != tc.ErrCount {
t.Fatalf("Expected the AWS CodeBuild project name to trigger a validation error - %s", errors)
}
}
}
func TestAccAWSCodeBuildProject_descriptionValidation(t *testing.T) {
cases := []struct {
Value string
ErrCount int
}{
{Value: "test", ErrCount: 0},
{Value: longTestData(), ErrCount: 1},
}
for _, tc := range cases {
_, errors := validateAwsCodeBuildProjectDescription(tc.Value, "aws_codebuild_project")
if len(errors) != tc.ErrCount {
t.Fatalf("Expected the AWS CodeBuild project description to trigger a validation error")
}
}
}
func TestAccAWSCodeBuildProject_environmentComputeTypeValidation(t *testing.T) {
cases := []struct {
Value string
ErrCount int
}{
{Value: "BUILD_GENERAL1_SMALL", ErrCount: 0},
{Value: "BUILD_GENERAL1_MEDIUM", ErrCount: 0},
{Value: "BUILD_GENERAL1_LARGE", ErrCount: 0},
{Value: "BUILD_GENERAL1_VERYLARGE", ErrCount: 1},
}
for _, tc := range cases {
_, errors := validateAwsCodeBuildEnvironmentComputeType(tc.Value, "aws_codebuild_project")
if len(errors) != tc.ErrCount {
t.Fatalf("Expected the AWS CodeBuild project environment compute_type to trigger a validation error")
}
}
}
func TestAccAWSCodeBuildProject_environmentTypeValidation(t *testing.T) {
cases := []struct {
Value string
ErrCount int
}{
{Value: "LINUX_CONTAINER", ErrCount: 0},
{Value: "WINDOWS_CONTAINER", ErrCount: 1},
}
for _, tc := range cases {
_, errors := validateAwsCodeBuildEnvironmentType(tc.Value, "aws_codebuild_project")
if len(errors) != tc.ErrCount {
t.Fatalf("Expected the AWS CodeBuild project environment type to trigger a validation error")
}
}
}
func TestAccAWSCodeBuildProject_sourceTypeValidation(t *testing.T) {
cases := []struct {
Value string
ErrCount int
}{
{Value: "CODECOMMIT", ErrCount: 0},
{Value: "CODEPIPELINE", ErrCount: 0},
{Value: "GITHUB", ErrCount: 0},
{Value: "S3", ErrCount: 0},
{Value: "GITLAB", ErrCount: 1},
}
for _, tc := range cases {
_, errors := validateAwsCodeBuildSourceType(tc.Value, "aws_codebuild_project")
if len(errors) != tc.ErrCount {
t.Fatalf("Expected the AWS CodeBuild project source type to trigger a validation error")
}
}
}
func TestAccAWSCodeBuildProject_sourceAuthTypeValidation(t *testing.T) {
cases := []struct {
Value string
ErrCount int
}{
{Value: "OAUTH", ErrCount: 0},
{Value: "PASSWORD", ErrCount: 1},
}
for _, tc := range cases {
_, errors := validateAwsCodeBuildSourceAuthType(tc.Value, "aws_codebuild_project")
if len(errors) != tc.ErrCount {
t.Fatalf("Expected the AWS CodeBuild project source auth to trigger a validation error")
}
}
}
func TestAccAWSCodeBuildProject_timeoutValidation(t *testing.T) {
cases := []struct {
Value int
ErrCount int
}{
{Value: 10, ErrCount: 0},
{Value: 200, ErrCount: 0},
{Value: 1, ErrCount: 1},
{Value: 500, ErrCount: 1},
}
for _, tc := range cases {
_, errors := validateAwsCodeBuildTimeout(tc.Value, "aws_codebuild_project")
if len(errors) != tc.ErrCount {
t.Fatalf("Expected the AWS CodeBuild project timeout to trigger a validation error")
}
}
}
func testAccCheckAWSCodeBuildProjectExists(n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", n)
}
if rs.Primary.ID == "" {
return fmt.Errorf("No CodeBuild Project ID is set")
}
conn := testAccProvider.Meta().(*AWSClient).codebuildconn
out, err := conn.BatchGetProjects(&codebuild.BatchGetProjectsInput{
Names: []*string{
aws.String(rs.Primary.ID),
},
})
if err != nil {
return err
}
if len(out.Projects) < 1 {
return fmt.Errorf("No project found")
}
return nil
}
}
func testAccCheckAWSCodeBuildProjectDestroy(s *terraform.State) error {
conn := testAccProvider.Meta().(*AWSClient).codebuildconn
for _, rs := range s.RootModule().Resources {
if rs.Type != "aws_codebuild_project" {
continue
}
out, err := conn.BatchGetProjects(&codebuild.BatchGetProjectsInput{
Names: []*string{
aws.String(rs.Primary.ID),
},
})
if err != nil {
return err
}
if out != nil && len(out.Projects) > 0 {
return fmt.Errorf("Expected AWS CodeBuild Project to be gone, but was still found")
}
return nil
}
return fmt.Errorf("Default error in CodeBuild Test")
}
func testAccAWSCodeBuildProjectConfig_basic(rName string) string {
return fmt.Sprintf(`
resource "aws_iam_role" "codebuild_role" {
name = "codebuild-role-%s"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "codebuild.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
}
resource "aws_iam_policy" "codebuild_policy" {
name = "codebuild-policy-%s"
path = "/service-role/"
description = "Policy used in trust relationship with CodeBuild"
policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Resource": [
"*"
],
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
]
}
]
}
POLICY
}
resource "aws_iam_policy_attachment" "codebuild_policy_attachment" {
name = "codebuild-policy-attachment-%s"
policy_arn = "${aws_iam_policy.codebuild_policy.arn}"
roles = ["${aws_iam_role.codebuild_role.id}"]
}
resource "aws_codebuild_project" "foo" {
name = "test-project-%s"
description = "test_codebuild_project"
timeout = "5"
service_role = "${aws_iam_role.codebuild_role.arn}"
artifacts {
type = "NO_ARTIFACTS"
}
environment {
compute_type = "BUILD_GENERAL1_SMALL"
image = "2"
type = "LINUX_CONTAINER"
environment_variable = {
"name" = "SOME_KEY"
"value" = "SOME_VALUE"
}
}
source {
type = "GITHUB"
location = "https://github.com/mitchellh/packer.git"
}
tags {
"Environment" = "Test"
}
}
`, rName, rName, rName, rName)
}

View File

@ -0,0 +1,67 @@
package aws
import (
"log"
"regexp"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/codebuild"
)
// diffTags takes our tags locally and the ones remotely and returns
// the set of tags that must be created, and the set of tags that must
// be destroyed.
func diffTagsCodeBuild(oldTags, newTags []*codebuild.Tag) ([]*codebuild.Tag, []*codebuild.Tag) {
// First, we're creating everything we have
create := make(map[string]interface{})
for _, t := range newTags {
create[*t.Key] = *t.Value
}
// Build the list of what to remove
var remove []*codebuild.Tag
for _, t := range oldTags {
old, ok := create[*t.Key]
if !ok || old != *t.Value {
// Delete it!
remove = append(remove, t)
}
}
return tagsFromMapCodeBuild(create), remove
}
func tagsFromMapCodeBuild(m map[string]interface{}) []*codebuild.Tag {
result := make([]*codebuild.Tag, 0, len(m))
for k, v := range m {
result = append(result, &codebuild.Tag{
Key: aws.String(k),
Value: aws.String(v.(string)),
})
}
return result
}
func tagsToMapCodeBuild(ts []*codebuild.Tag) map[string]string {
result := make(map[string]string)
for _, t := range ts {
result[*t.Key] = *t.Value
}
return result
}
// compare a tag against a list of strings and checks if it should
// be ignored or not
func tagIgnoredCodeBuild(t *codebuild.Tag) bool {
filter := []string{"^aws:*"}
for _, v := range filter {
log.Printf("[DEBUG] Matching %v with %v\n", v, *t.Key)
if r, _ := regexp.MatchString(v, *t.Key); r == true {
log.Printf("[DEBUG] Found AWS specific tag %s (val: %s), ignoring.\n", *t.Key, *t.Value)
return true
}
}
return false
}

View File

@ -0,0 +1,103 @@
package aws
import (
"fmt"
"reflect"
"testing"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/codebuild"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)
func TestDiffTagsCodeBuild(t *testing.T) {
cases := []struct {
Old, New map[string]interface{}
Create, Remove map[string]string
}{
// Basic add/remove
{
Old: map[string]interface{}{
"foo": "bar",
},
New: map[string]interface{}{
"bar": "baz",
},
Create: map[string]string{
"bar": "baz",
},
Remove: map[string]string{
"foo": "bar",
},
},
// Modify
{
Old: map[string]interface{}{
"foo": "bar",
},
New: map[string]interface{}{
"foo": "baz",
},
Create: map[string]string{
"foo": "baz",
},
Remove: map[string]string{
"foo": "bar",
},
},
}
for i, tc := range cases {
c, r := diffTagsCodeBuild(tagsFromMapCodeBuild(tc.Old), tagsFromMapCodeBuild(tc.New))
cm := tagsToMapCodeBuild(c)
rm := tagsToMapCodeBuild(r)
if !reflect.DeepEqual(cm, tc.Create) {
t.Fatalf("%d: bad create: %#v", i, cm)
}
if !reflect.DeepEqual(rm, tc.Remove) {
t.Fatalf("%d: bad remove: %#v", i, rm)
}
}
}
func TestIgnoringTagsCodeBuild(t *testing.T) {
var ignoredTags []*codebuild.Tag
ignoredTags = append(ignoredTags, &codebuild.Tag{
Key: aws.String("aws:cloudformation:logical-id"),
Value: aws.String("foo"),
})
ignoredTags = append(ignoredTags, &codebuild.Tag{
Key: aws.String("aws:foo:bar"),
Value: aws.String("baz"),
})
for _, tag := range ignoredTags {
if !tagIgnoredCodeBuild(tag) {
t.Fatalf("Tag %v with value %v not ignored, but should be!", *tag.Key, *tag.Value)
}
}
}
// testAccCheckTags can be used to check the tags on a resource.
func testAccCheckTagsCodeBuild(
ts *[]*codebuild.Tag, key string, value string) resource.TestCheckFunc {
return func(s *terraform.State) error {
m := tagsToMapCodeBuild(*ts)
v, ok := m[key]
if value != "" && !ok {
return fmt.Errorf("Missing tag: %s", key)
} else if value == "" && ok {
return fmt.Errorf("Extra tag: %s", key)
}
if value == "" {
return nil
}
if v != value {
return fmt.Errorf("%s: bad value: %s", key, v)
}
return nil
}
}

3207
vendor/github.com/aws/aws-sdk-go/service/codebuild/api.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,131 @@
// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
package codebuild
import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/client"
"github.com/aws/aws-sdk-go/aws/client/metadata"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/aws/signer/v4"
"github.com/aws/aws-sdk-go/private/protocol/jsonrpc"
)
// AWS CodeBuild is a fully-managed build service in the cloud. AWS CodeBuild
// compiles your source code, runs unit tests, and produces artifacts that are
// ready to deploy. AWS CodeBuild eliminates the need to provision, manage,
// and scale your own build servers. It provides prepackaged build environments
// for the most popular programming languages and build tools such as Apach
// Maven, Gradle, and more. You can also fully customize build environments
// in AWS CodeBuild to use your own build tools. AWS CodeBuild scales automatically
// to meet peak build requests, and you pay only for the build time you consume.
// For more information about AWS CodeBuild, see the AWS CodeBuild User Guide.
//
// AWS CodeBuild supports these operations:
//
// * BatchGetProjects: Gets information about one or more build projects.
// A build project defines how AWS CodeBuild will run a build. This includes
// information such as where to get the source code to build, the build environment
// to use, the build commands to run, and where to store the build output.
// A build environment represents a combination of operating system, programming
// language runtime, and tools that AWS CodeBuild will use to run a build.
// Also, you can add tags to build projects to help manage your resources
// and costs.
//
// * CreateProject: Creates a build project.
//
// * DeleteProject: Deletes a build project.
//
// * ListProjects: Gets a list of build project names, with each build project
// name representing a single build project.
//
// * UpdateProject: Changes the settings of an existing build project.
//
// * BatchGetBuilds: Gets information about one or more builds.
//
// * ListBuilds: Gets a list of build IDs, with each build ID representing
// a single build.
//
// * ListBuildsForProject: Gets a list of build IDs for the specified build
// project, with each build ID representing a single build.
//
// * StartBuild: Starts running a build.
//
// * StopBuild: Attempts to stop running a build.
//
// * ListCuratedEnvironmentImages: Gets information about Docker images that
// are managed by AWS CodeBuild.
//The service client's operations are safe to be used concurrently.
// It is not safe to mutate any of the client's properties though.
type CodeBuild struct {
*client.Client
}
// Used for custom client initialization logic
var initClient func(*client.Client)
// Used for custom request initialization logic
var initRequest func(*request.Request)
// A ServiceName is the name of the service the client will make API calls to.
const ServiceName = "codebuild"
// New creates a new instance of the CodeBuild client with a session.
// If additional configuration is needed for the client instance use the optional
// aws.Config parameter to add your extra config.
//
// Example:
// // Create a CodeBuild client from just a session.
// svc := codebuild.New(mySession)
//
// // Create a CodeBuild client with additional configuration
// svc := codebuild.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
func New(p client.ConfigProvider, cfgs ...*aws.Config) *CodeBuild {
c := p.ClientConfig(ServiceName, cfgs...)
return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion)
}
// newClient creates, initializes and returns a new service client instance.
func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string) *CodeBuild {
svc := &CodeBuild{
Client: client.New(
cfg,
metadata.ClientInfo{
ServiceName: ServiceName,
SigningRegion: signingRegion,
Endpoint: endpoint,
APIVersion: "2016-10-06",
JSONVersion: "1.1",
TargetPrefix: "CodeBuild_20161006",
},
handlers,
),
}
// Handlers
svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler)
svc.Handlers.Build.PushBackNamed(jsonrpc.BuildHandler)
svc.Handlers.Unmarshal.PushBackNamed(jsonrpc.UnmarshalHandler)
svc.Handlers.UnmarshalMeta.PushBackNamed(jsonrpc.UnmarshalMetaHandler)
svc.Handlers.UnmarshalError.PushBackNamed(jsonrpc.UnmarshalErrorHandler)
// Run custom client initialization if present
if initClient != nil {
initClient(svc.Client)
}
return svc
}
// newRequest creates a new request for a CodeBuild operation and runs any
// custom request initialization.
func (c *CodeBuild) newRequest(op *request.Operation, params, data interface{}) *request.Request {
req := c.NewRequest(op, params, data)
// Run custom request initialization if present
if initRequest != nil {
initRequest(req)
}
return req
}

8
vendor/vendor.json vendored
View File

@ -764,6 +764,14 @@
"version": "v1.6.18",
"versionExact": "v1.6.18"
},
{
"checksumSHA1": "MTlPViWUHDJ1wVPusVAeFSZWU2k=",
"path": "github.com/aws/aws-sdk-go/service/codebuild",
"revision": "918c42e2bcdb277aa821401c906e88254501bdf4",
"revisionTime": "2016-12-01T20:26:07Z",
"version": "v1.5.13",
"versionExact": "v1.5.13"
},
{
"checksumSHA1": "lHCqaKjIV/AO1B8nxDUyM0AW/+0=",
"path": "github.com/aws/aws-sdk-go/service/codecommit",

View File

@ -11,9 +11,7 @@ description: |-
The KMS secret data source allows you to use data encrypted with the AWS KMS
service within your resource definitions.
## Note about encrypted data
Using this data provider will allow you to conceal secret data within your
~> **NOTE**: Using this data provider will allow you to conceal secret data within your
resource definitions but does not take care of protecting that data in the
logging output, plan output or state output.

View File

@ -245,6 +245,17 @@
</ul>
</li>
<li<%= sidebar_current(/^docs-aws-resource-codebuild/) %>>
<a href="#">CodeBuild Resources</a>
<ul class="nav nav-visible">
<li<%= sidebar_current("docs-aws-resource-codebuild-project") %>>
<a href="/docs/providers/aws/r/code_build_project.html">aws_codebuild_project</a>
</li>
</ul>
</li>
<li<%= sidebar_current(/^docs-aws-resource-codecommit/) %>>
<a href="#">CodeCommit Resources</a>
<ul class="nav nav-visible">