2018-01-22 19:54:49 -05:00
|
|
|
package classic
|
|
|
|
|
|
|
|
import (
|
2018-01-25 17:43:55 -05:00
|
|
|
"context"
|
2018-01-22 19:54:49 -05:00
|
|
|
"fmt"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/hashicorp/go-oracle-terraform/compute"
|
2018-02-08 17:55:04 -05:00
|
|
|
"github.com/hashicorp/packer/common/uuid"
|
2018-01-25 17:45:09 -05:00
|
|
|
"github.com/hashicorp/packer/helper/multistep"
|
2018-01-22 19:54:49 -05:00
|
|
|
"github.com/hashicorp/packer/packer"
|
|
|
|
)
|
|
|
|
|
|
|
|
type stepSecurity struct{}
|
|
|
|
|
2018-01-25 17:42:39 -05:00
|
|
|
func (s *stepSecurity) Run(_ context.Context, state multistep.StateBag) multistep.StepAction {
|
2018-01-22 19:54:49 -05:00
|
|
|
ui := state.Get("ui").(packer.Ui)
|
2018-02-08 17:55:04 -05:00
|
|
|
config := state.Get("config").(*Config)
|
|
|
|
|
|
|
|
commType := ""
|
|
|
|
if config.Comm.Type == "ssh" {
|
|
|
|
commType = "SSH"
|
|
|
|
} else if config.Comm.Type == "winrm" {
|
|
|
|
commType = "WINRM"
|
|
|
|
}
|
2018-01-23 14:07:04 -05:00
|
|
|
|
2018-02-08 17:55:04 -05:00
|
|
|
ui.Say(fmt.Sprintf("Configuring security lists and rules to enable %s access...", commType))
|
2018-01-23 14:07:04 -05:00
|
|
|
|
2018-01-22 19:54:49 -05:00
|
|
|
client := state.Get("client").(*compute.ComputeClient)
|
2018-02-08 17:55:04 -05:00
|
|
|
runUUID := uuid.TimeOrderedUUID()
|
2018-01-22 19:54:49 -05:00
|
|
|
|
2018-02-08 17:55:04 -05:00
|
|
|
namePrefix := fmt.Sprintf("/Compute-%s/%s/", config.IdentityDomain, config.Username)
|
|
|
|
secListName := fmt.Sprintf("Packer_%s_Allow_%s_%s", commType, config.ImageName, runUUID)
|
2018-01-22 19:54:49 -05:00
|
|
|
secListClient := client.SecurityLists()
|
|
|
|
secListInput := compute.CreateSecurityListInput{
|
2018-02-08 17:55:04 -05:00
|
|
|
Description: fmt.Sprintf("Packer-generated security list to give packer %s access", commType),
|
|
|
|
Name: namePrefix + secListName,
|
2018-01-22 19:54:49 -05:00
|
|
|
}
|
|
|
|
_, err := secListClient.CreateSecurityList(&secListInput)
|
|
|
|
if err != nil {
|
|
|
|
if !strings.Contains(err.Error(), "already exists") {
|
2018-01-23 14:07:04 -05:00
|
|
|
err = fmt.Errorf("Error creating security List to"+
|
2018-02-08 17:55:04 -05:00
|
|
|
" allow Packer to connect to Oracle instance via %s: %s", commType, err)
|
2018-01-22 19:54:49 -05:00
|
|
|
ui.Error(err.Error())
|
|
|
|
state.Put("error", err)
|
|
|
|
return multistep.ActionHalt
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// DOCS NOTE: user must have Compute_Operations role
|
2018-02-08 17:55:04 -05:00
|
|
|
// Create security rule that allows Packer to connect via SSH or winRM
|
|
|
|
var application string
|
|
|
|
if commType == "SSH" {
|
|
|
|
application = "/oracle/public/ssh"
|
|
|
|
} else if commType == "WINRM" {
|
|
|
|
// Check to see whether a winRM security application is already defined
|
|
|
|
applicationClient := client.SecurityApplications()
|
|
|
|
application = fmt.Sprintf("packer_winRM_%s", runUUID)
|
|
|
|
applicationInput := compute.CreateSecurityApplicationInput{
|
|
|
|
Description: "Allows Packer to connect to instance via winRM",
|
|
|
|
DPort: "5985-5986",
|
|
|
|
Name: application,
|
|
|
|
Protocol: "TCP",
|
|
|
|
}
|
|
|
|
_, err = applicationClient.CreateSecurityApplication(&applicationInput)
|
|
|
|
if err != nil {
|
|
|
|
err = fmt.Errorf("Error creating security application to"+
|
|
|
|
" allow Packer to connect to Oracle instance via %s: %s", commType, err)
|
|
|
|
ui.Error(err.Error())
|
|
|
|
state.Put("error", err)
|
|
|
|
return multistep.ActionHalt
|
|
|
|
}
|
|
|
|
state.Put("winrm_application", application)
|
|
|
|
}
|
2018-01-22 19:54:49 -05:00
|
|
|
secRulesClient := client.SecRules()
|
2018-02-08 17:55:04 -05:00
|
|
|
secRuleName := fmt.Sprintf("Packer-allow-%s-Rule_%s_%s", commType,
|
|
|
|
config.ImageName, runUUID)
|
2018-01-22 19:54:49 -05:00
|
|
|
secRulesInput := compute.CreateSecRuleInput{
|
|
|
|
Action: "PERMIT",
|
2018-02-08 17:55:04 -05:00
|
|
|
Application: application,
|
|
|
|
Description: "Packer-generated security rule to allow ssh/winrm",
|
|
|
|
DestinationList: "seclist:" + namePrefix + secListName,
|
|
|
|
Name: namePrefix + secRuleName,
|
2018-01-23 14:07:04 -05:00
|
|
|
SourceList: config.SSHSourceList,
|
2018-01-22 19:54:49 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
_, err = secRulesClient.CreateSecRule(&secRulesInput)
|
|
|
|
if err != nil {
|
2018-02-08 17:55:04 -05:00
|
|
|
err = fmt.Errorf("Error creating security rule to"+
|
|
|
|
" allow Packer to connect to Oracle instance: %s", err)
|
|
|
|
ui.Error(err.Error())
|
|
|
|
state.Put("error", err)
|
|
|
|
return multistep.ActionHalt
|
2018-01-22 19:54:49 -05:00
|
|
|
}
|
2018-01-23 14:07:04 -05:00
|
|
|
state.Put("security_rule_name", secRuleName)
|
2018-01-22 19:54:49 -05:00
|
|
|
state.Put("security_list", secListName)
|
|
|
|
return multistep.ActionContinue
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *stepSecurity) Cleanup(state multistep.StateBag) {
|
2018-04-02 14:56:11 -04:00
|
|
|
secRuleName, ok := state.GetOk("security_rule_name")
|
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
secListName, ok := state.GetOk("security_list")
|
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-01-23 14:07:04 -05:00
|
|
|
client := state.Get("client").(*compute.ComputeClient)
|
|
|
|
ui := state.Get("ui").(packer.Ui)
|
2018-02-08 17:55:04 -05:00
|
|
|
config := state.Get("config").(*Config)
|
|
|
|
|
2018-01-26 16:43:19 -05:00
|
|
|
ui.Say("Deleting temporary rules and lists...")
|
2018-01-25 12:17:30 -05:00
|
|
|
|
2018-02-08 17:55:04 -05:00
|
|
|
namePrefix := fmt.Sprintf("/Compute-%s/%s/", config.IdentityDomain, config.Username)
|
2018-01-23 14:07:04 -05:00
|
|
|
// delete security rules that Packer generated
|
|
|
|
secRulesClient := client.SecRules()
|
2018-04-02 14:56:11 -04:00
|
|
|
ruleInput := compute.DeleteSecRuleInput{Name: namePrefix + secRuleName.(string)}
|
2018-01-25 12:17:30 -05:00
|
|
|
err := secRulesClient.DeleteSecRule(&ruleInput)
|
2018-01-23 14:07:04 -05:00
|
|
|
if err != nil {
|
|
|
|
ui.Say(fmt.Sprintf("Error deleting the packer-generated security rule %s; "+
|
2018-04-02 14:56:11 -04:00
|
|
|
"please delete manually. (error: %s)", secRuleName.(string), err.Error()))
|
2018-01-23 14:07:04 -05:00
|
|
|
}
|
2018-01-25 12:17:30 -05:00
|
|
|
|
|
|
|
// delete security list that Packer generated
|
|
|
|
secListClient := client.SecurityLists()
|
2018-04-02 14:56:11 -04:00
|
|
|
input := compute.DeleteSecurityListInput{Name: namePrefix + secListName.(string)}
|
2018-01-25 12:17:30 -05:00
|
|
|
err = secListClient.DeleteSecurityList(&input)
|
|
|
|
if err != nil {
|
|
|
|
ui.Say(fmt.Sprintf("Error deleting the packer-generated security list %s; "+
|
2018-04-02 14:56:11 -04:00
|
|
|
"please delete manually. (error : %s)", secListName.(string), err.Error()))
|
2018-01-25 12:17:30 -05:00
|
|
|
}
|
2018-02-08 17:55:04 -05:00
|
|
|
|
|
|
|
// Some extra cleanup if we used the winRM communicator
|
|
|
|
if config.Comm.Type == "winrm" {
|
|
|
|
// Delete the packer-generated application
|
2018-04-02 14:56:11 -04:00
|
|
|
application, ok := state.GetOk("winrm_application")
|
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
2018-02-08 17:55:04 -05:00
|
|
|
applicationClient := client.SecurityApplications()
|
|
|
|
deleteApplicationInput := compute.DeleteSecurityApplicationInput{
|
2018-04-02 14:56:11 -04:00
|
|
|
Name: namePrefix + application.(string),
|
2018-02-08 17:55:04 -05:00
|
|
|
}
|
|
|
|
err = applicationClient.DeleteSecurityApplication(&deleteApplicationInput)
|
|
|
|
if err != nil {
|
|
|
|
ui.Say(fmt.Sprintf("Error deleting the packer-generated winrm security application %s; "+
|
2018-04-02 14:56:11 -04:00
|
|
|
"please delete manually. (error : %s)", application.(string), err.Error()))
|
2018-02-08 17:55:04 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-22 19:54:49 -05:00
|
|
|
}
|