github.com/rahart/packer@v0.12.2-0.20161229105310-282bb6ad370f/builder/amazon/common/step_modify_ami_attributes.go (about) 1 package common 2 3 import ( 4 "fmt" 5 6 "github.com/aws/aws-sdk-go/aws" 7 "github.com/aws/aws-sdk-go/aws/session" 8 "github.com/aws/aws-sdk-go/service/ec2" 9 "github.com/mitchellh/multistep" 10 "github.com/mitchellh/packer/packer" 11 ) 12 13 type StepModifyAMIAttributes struct { 14 Users []string 15 Groups []string 16 SnapshotUsers []string 17 SnapshotGroups []string 18 ProductCodes []string 19 Description string 20 } 21 22 func (s *StepModifyAMIAttributes) Run(state multistep.StateBag) multistep.StepAction { 23 ec2conn := state.Get("ec2").(*ec2.EC2) 24 ui := state.Get("ui").(packer.Ui) 25 amis := state.Get("amis").(map[string]string) 26 snapshots := state.Get("snapshots").(map[string][]string) 27 28 // Determine if there is any work to do. 29 valid := false 30 valid = valid || s.Description != "" 31 valid = valid || (s.Users != nil && len(s.Users) > 0) 32 valid = valid || (s.Groups != nil && len(s.Groups) > 0) 33 valid = valid || (s.ProductCodes != nil && len(s.ProductCodes) > 0) 34 valid = valid || (s.SnapshotUsers != nil && len(s.SnapshotUsers) > 0) 35 valid = valid || (s.SnapshotGroups != nil && len(s.SnapshotGroups) > 0) 36 37 if !valid { 38 return multistep.ActionContinue 39 } 40 41 // Construct the modify image and snapshot attribute requests we're going 42 // to make. We need to make each separately since the EC2 API only allows 43 // changing one type at a kind currently. 44 options := make(map[string]*ec2.ModifyImageAttributeInput) 45 if s.Description != "" { 46 options["description"] = &ec2.ModifyImageAttributeInput{ 47 Description: &ec2.AttributeValue{Value: &s.Description}, 48 } 49 } 50 snapshotOptions := make(map[string]*ec2.ModifySnapshotAttributeInput) 51 52 if len(s.Groups) > 0 { 53 groups := make([]*string, len(s.Groups)) 54 addsImage := make([]*ec2.LaunchPermission, len(s.Groups)) 55 addGroups := &ec2.ModifyImageAttributeInput{ 56 LaunchPermission: &ec2.LaunchPermissionModifications{}, 57 } 58 59 for i, g := range s.Groups { 60 groups[i] = aws.String(g) 61 addsImage[i] = &ec2.LaunchPermission{ 62 Group: aws.String(g), 63 } 64 } 65 66 addGroups.UserGroups = groups 67 addGroups.LaunchPermission.Add = addsImage 68 options["groups"] = addGroups 69 } 70 71 if len(s.SnapshotGroups) > 0 { 72 groups := make([]*string, len(s.SnapshotGroups)) 73 addsSnapshot := make([]*ec2.CreateVolumePermission, len(s.SnapshotGroups)) 74 addSnapshotGroups := &ec2.ModifySnapshotAttributeInput{ 75 CreateVolumePermission: &ec2.CreateVolumePermissionModifications{}, 76 } 77 78 for i, g := range s.SnapshotGroups { 79 groups[i] = aws.String(g) 80 addsSnapshot[i] = &ec2.CreateVolumePermission{ 81 Group: aws.String(g), 82 } 83 } 84 addSnapshotGroups.GroupNames = groups 85 addSnapshotGroups.CreateVolumePermission.Add = addsSnapshot 86 snapshotOptions["groups"] = addSnapshotGroups 87 } 88 89 if len(s.Users) > 0 { 90 users := make([]*string, len(s.Users)) 91 addsImage := make([]*ec2.LaunchPermission, len(s.Users)) 92 for i, u := range s.Users { 93 users[i] = aws.String(u) 94 addsImage[i] = &ec2.LaunchPermission{UserId: aws.String(u)} 95 } 96 97 options["users"] = &ec2.ModifyImageAttributeInput{ 98 UserIds: users, 99 LaunchPermission: &ec2.LaunchPermissionModifications{ 100 Add: addsImage, 101 }, 102 } 103 } 104 105 if len(s.SnapshotUsers) > 0 { 106 users := make([]*string, len(s.SnapshotUsers)) 107 addsSnapshot := make([]*ec2.CreateVolumePermission, len(s.SnapshotUsers)) 108 for i, u := range s.SnapshotUsers { 109 users[i] = aws.String(u) 110 addsSnapshot[i] = &ec2.CreateVolumePermission{UserId: aws.String(u)} 111 } 112 113 snapshotOptions["users"] = &ec2.ModifySnapshotAttributeInput{ 114 UserIds: users, 115 CreateVolumePermission: &ec2.CreateVolumePermissionModifications{ 116 Add: addsSnapshot, 117 }, 118 } 119 } 120 121 if len(s.ProductCodes) > 0 { 122 codes := make([]*string, len(s.ProductCodes)) 123 for i, c := range s.ProductCodes { 124 codes[i] = &c 125 } 126 options["product codes"] = &ec2.ModifyImageAttributeInput{ 127 ProductCodes: codes, 128 } 129 } 130 131 // Modifying image attributes 132 for region, ami := range amis { 133 ui.Say(fmt.Sprintf("Modifying attributes on AMI (%s)...", ami)) 134 awsConfig := aws.Config{ 135 Credentials: ec2conn.Config.Credentials, 136 Region: aws.String(region), 137 } 138 session, err := session.NewSession(&awsConfig) 139 if err != nil { 140 err := fmt.Errorf("Error creating AWS session: %s", err) 141 state.Put("error", err) 142 ui.Error(err.Error()) 143 return multistep.ActionHalt 144 } 145 regionconn := ec2.New(session) 146 for name, input := range options { 147 ui.Message(fmt.Sprintf("Modifying: %s", name)) 148 input.ImageId = &ami 149 _, err := regionconn.ModifyImageAttribute(input) 150 if err != nil { 151 err := fmt.Errorf("Error modify AMI attributes: %s", err) 152 state.Put("error", err) 153 ui.Error(err.Error()) 154 return multistep.ActionHalt 155 } 156 } 157 } 158 159 // Modifying snapshot attributes 160 for region, region_snapshots := range snapshots { 161 for _, snapshot := range region_snapshots { 162 ui.Say(fmt.Sprintf("Modifying attributes on snapshot (%s)...", snapshot)) 163 awsConfig := aws.Config{ 164 Credentials: ec2conn.Config.Credentials, 165 Region: aws.String(region), 166 } 167 session := session.New(&awsConfig) 168 regionconn := ec2.New(session) 169 for name, input := range snapshotOptions { 170 ui.Message(fmt.Sprintf("Modifying: %s", name)) 171 input.SnapshotId = &snapshot 172 _, err := regionconn.ModifySnapshotAttribute(input) 173 if err != nil { 174 err := fmt.Errorf("Error modify snapshot attributes: %s", err) 175 state.Put("error", err) 176 ui.Error(err.Error()) 177 return multistep.ActionHalt 178 } 179 } 180 } 181 } 182 183 return multistep.ActionContinue 184 } 185 186 func (s *StepModifyAMIAttributes) Cleanup(state multistep.StateBag) { 187 // No cleanup... 188 }