chore: implemented OSC API in step_security_group

This commit is contained in:
PacoDw 2020-08-21 11:30:10 -05:00
parent d9a7626249
commit c3a4b60ea5
1 changed files with 88 additions and 64 deletions

View File

@ -5,13 +5,13 @@ import (
"fmt" "fmt"
"log" "log"
"strings" "strings"
"time"
"github.com/antihax/optional"
"github.com/hashicorp/packer/common/uuid" "github.com/hashicorp/packer/common/uuid"
"github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/communicator"
"github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/packer"
"github.com/outscale/osc-go/oapi" "github.com/outscale/osc-sdk-go/osc"
) )
type StepSecurityGroup struct { type StepSecurityGroup struct {
@ -24,50 +24,56 @@ type StepSecurityGroup struct {
} }
func (s *StepSecurityGroup) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { func (s *StepSecurityGroup) Run(_ context.Context, state multistep.StateBag) multistep.StepAction {
oapiconn := state.Get("oapi").(*oapi.Client) var (
ui := state.Get("ui").(packer.Ui) ui = state.Get("ui").(packer.Ui)
netId := state.Get("net_id").(string) conn = state.Get("osc").(*osc.APIClient)
netID = state.Get("net_id").(string)
)
if len(s.SecurityGroupIds) > 0 { if len(s.SecurityGroupIds) > 0 {
resp, err := oapiconn.POST_ReadSecurityGroups( resp, _, err := conn.SecurityGroupApi.ReadSecurityGroups(context.Background(), &osc.ReadSecurityGroupsOpts{
oapi.ReadSecurityGroupsRequest{ ReadSecurityGroupsRequest: optional.NewInterface(osc.ReadSecurityGroupsRequest{
Filters: oapi.FiltersSecurityGroup{ Filters: osc.FiltersSecurityGroup{
SecurityGroupIds: s.SecurityGroupIds, SecurityGroupIds: s.SecurityGroupIds,
}, },
}, }),
) })
if err != nil || resp.OK == nil || len(resp.OK.SecurityGroups) <= 0 {
if err != nil || len(resp.SecurityGroups) == 0 {
err := fmt.Errorf("Couldn't find specified security group: %s", err) err := fmt.Errorf("Couldn't find specified security group: %s", err)
log.Printf("[DEBUG] %s", err.Error()) log.Printf("[DEBUG] %s", err.Error())
state.Put("error", err) state.Put("error", err)
return multistep.ActionHalt return multistep.ActionHalt
} }
log.Printf("Using specified security groups: %v", s.SecurityGroupIds) log.Printf("Using specified security groups: %v", s.SecurityGroupIds)
state.Put("securityGroupIds", s.SecurityGroupIds) state.Put("securityGroupIds", s.SecurityGroupIds)
return multistep.ActionContinue return multistep.ActionContinue
} }
if !s.SecurityGroupFilter.Empty() { if !s.SecurityGroupFilter.Empty() {
filterReq := buildSecurityGroupFilters(s.SecurityGroupFilter.Filters)
params := oapi.ReadSecurityGroupsRequest{} log.Printf("Using SecurityGroup Filters %v", filterReq)
if netId != "" {
s.SecurityGroupFilter.Filters["net-id"] = netId
}
params.Filters = buildSecurityGroupFilters(s.SecurityGroupFilter.Filters)
log.Printf("Using SecurityGroup Filters %v", params) resp, _, err := conn.SecurityGroupApi.ReadSecurityGroups(context.Background(), &osc.ReadSecurityGroupsOpts{
ReadSecurityGroupsRequest: optional.NewInterface(osc.ReadSecurityGroupsRequest{
Filters: filterReq,
}),
})
sgResp, err := oapiconn.POST_ReadSecurityGroups(params) if err != nil || len(resp.SecurityGroups) == 0 {
if err != nil || sgResp.OK == nil {
err := fmt.Errorf("Couldn't find security groups for filter: %s", err) err := fmt.Errorf("Couldn't find security groups for filter: %s", err)
log.Printf("[DEBUG] %s", err.Error()) log.Printf("[DEBUG] %s", err.Error())
state.Put("error", err) state.Put("error", err)
return multistep.ActionHalt return multistep.ActionHalt
} }
securityGroupIds := []string{} securityGroupIds := []string{}
for _, sg := range sgResp.OK.SecurityGroups { for _, sg := range resp.SecurityGroups {
securityGroupIds = append(securityGroupIds, sg.SecurityGroupId) securityGroupIds = append(securityGroupIds, sg.SecurityGroupId)
} }
@ -77,24 +83,20 @@ func (s *StepSecurityGroup) Run(_ context.Context, state multistep.StateBag) mul
return multistep.ActionContinue return multistep.ActionContinue
} }
port := s.CommConfig.Port() /* Create the group */
if port == 0 { groupName := fmt.Sprintf("packer_osc_%s", uuid.TimeOrderedUUID())
if s.CommConfig.Type != "none" {
panic("port must be set to a non-zero value.")
}
}
// Create the group
groupName := fmt.Sprintf("packer_%s", uuid.TimeOrderedUUID())
ui.Say(fmt.Sprintf("Creating temporary security group for this instance: %s", groupName)) ui.Say(fmt.Sprintf("Creating temporary security group for this instance: %s", groupName))
group := oapi.CreateSecurityGroupRequest{
createSGReq := osc.CreateSecurityGroupRequest{
SecurityGroupName: groupName, SecurityGroupName: groupName,
NetId: netID,
Description: "Temporary group for Packer", Description: "Temporary group for Packer",
} }
group.NetId = netId resp, _, err := conn.SecurityGroupApi.CreateSecurityGroup(context.Background(), &osc.CreateSecurityGroupOpts{
CreateSecurityGroupRequest: optional.NewInterface(createSGReq),
})
groupResp, err := oapiconn.POST_CreateSecurityGroup(group)
if err != nil { if err != nil {
ui.Error(err.Error()) ui.Error(err.Error())
state.Put("error", err) state.Put("error", err)
@ -102,38 +104,36 @@ func (s *StepSecurityGroup) Run(_ context.Context, state multistep.StateBag) mul
} }
// Set the group ID so we can delete it later // Set the group ID so we can delete it later
s.createdGroupId = groupResp.OK.SecurityGroup.SecurityGroupId s.createdGroupId = resp.SecurityGroup.SecurityGroupId
// Wait for the security group become available for authorizing port := s.CommConfig.Port()
log.Printf("[DEBUG] Waiting for temporary security group: %s", s.createdGroupId) if port == 0 {
err = waitForSecurityGroup(oapiconn, s.createdGroupId) if s.CommConfig.Type != "none" {
if err == nil { state.Put("error", "port must be set to a non-zero value.")
log.Printf("[DEBUG] Found security group %s", s.createdGroupId) return multistep.ActionHalt
} else { }
err := fmt.Errorf("Timed out waiting for security group %s: %s", s.createdGroupId, err)
log.Printf("[DEBUG] %s", err.Error())
state.Put("error", err)
return multistep.ActionHalt
} }
// Authorize the SSH access for the security group // Authorize the SSH access for the security group
groupRules := oapi.CreateSecurityGroupRuleRequest{ createSGRReq := osc.CreateSecurityGroupRuleRequest{
SecurityGroupId: groupResp.OK.SecurityGroup.SecurityGroupId, SecurityGroupId: resp.SecurityGroup.SecurityGroupId,
Flow: "Inbound", Flow: "Inbound",
Rules: []oapi.SecurityGroupRule{ Rules: []osc.SecurityGroupRule{
{ {
FromPortRange: int64(port), FromPortRange: int32(port),
ToPortRange: int64(port), ToPortRange: int32(port),
IpRanges: []string{s.TemporarySGSourceCidr}, IpRanges: []string{s.TemporarySGSourceCidr},
IpProtocol: "tcp", IpProtocol: "tcp",
}, },
}, },
} }
ui.Say(fmt.Sprintf( ui.Say(fmt.Sprintf("Authorizing access to port %d from %s in the temporary security group...", port, s.TemporarySGSourceCidr))
"Authorizing access to port %d from %s in the temporary security group...",
port, s.TemporarySGSourceCidr)) conn.SecurityGroupRuleApi.CreateSecurityGroupRule(context.Background(), &osc.CreateSecurityGroupRuleOpts{
_, err = oapiconn.POST_CreateSecurityGroupRule(groupRules) CreateSecurityGroupRuleRequest: optional.NewInterface(createSGRReq),
})
if err != nil { if err != nil {
err := fmt.Errorf("Error authorizing temporary security group: %s", err) err := fmt.Errorf("Error authorizing temporary security group: %s", err)
state.Put("error", err) state.Put("error", err)
@ -152,24 +152,48 @@ func (s *StepSecurityGroup) Cleanup(state multistep.StateBag) {
return return
} }
oapiconn := state.Get("oapi").(*oapi.Client) var (
ui := state.Get("ui").(packer.Ui) ui = state.Get("ui").(packer.Ui)
conn = state.Get("osc").(*osc.APIClient)
)
ui.Say("Deleting temporary security group...") ui.Say("Deleting temporary security group...")
var err error _, _, err := conn.SecurityGroupApi.DeleteSecurityGroup(context.Background(), &osc.DeleteSecurityGroupOpts{
for i := 0; i < 5; i++ { DeleteSecurityGroupRequest: optional.NewInterface(osc.DeleteSecurityGroupRequest{
_, err = oapiconn.POST_DeleteSecurityGroup(oapi.DeleteSecurityGroupRequest{SecurityGroupId: s.createdGroupId}) SecurityGroupId: s.createdGroupId,
if err == nil { }),
break })
}
log.Printf("Error deleting security group: %s", err)
time.Sleep(5 * time.Second)
}
if err != nil { if err != nil {
ui.Error(fmt.Sprintf( ui.Error(fmt.Sprintf(
"Error cleaning up security group. Please delete the group manually: %s", s.createdGroupId)) "Error cleaning up security group. Please delete the group manually: %s", s.createdGroupId))
} }
} }
func buildSecurityGroupFilters(input map[string]string) osc.FiltersSecurityGroup {
var filters osc.FiltersSecurityGroup
for k, v := range input {
filterValue := []string{v}
switch name := k; name {
case "account_ids":
filters.AccountIds = filterValue
case "security_group_ids":
filters.SecurityGroupIds = filterValue
case "security_group_names":
filters.SecurityGroupNames = filterValue
case "tag_keys":
filters.TagKeys = filterValue
case "tag_values":
filters.TagValues = filterValue
case "tags":
filters.Tags = filterValue
default:
log.Printf("[Debug] Unknown Filter Name: %s.", name)
}
}
return filters
}