Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Placement parameter #378

Merged
merged 1 commit into from
Mar 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/resources/machine.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ resource "juju_machine" "this_machine" {
- `constraints` (String) Machine constraints that overwrite those available from 'juju get-model-constraints' and provider's defaults.
- `disks` (String) Storage constraints for disks to attach to the machine(s).
- `name` (String) A name for the machine resource in Terraform.
- `placement` (String) Additional information about how to allocate the machine in the cloud.
- `private_key_file` (String) The file path to read the private key from.
- `public_key_file` (String) The file path to read the public key from.
- `series` (String, Deprecated) The operating system series to install on the new machine(s).
Expand Down
28 changes: 27 additions & 1 deletion internal/juju/machines.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/juju/juju/cmd/juju/common"
"github.com/juju/juju/core/base"
"github.com/juju/juju/core/constraints"
"github.com/juju/juju/core/instance"
"github.com/juju/juju/core/model"
"github.com/juju/juju/environs/config"
"github.com/juju/juju/environs/manual"
Expand All @@ -37,6 +38,7 @@ type CreateMachineInput struct {
Constraints string
Disks string
Base string
Placement string
Series string
InstanceId string

Expand Down Expand Up @@ -106,6 +108,22 @@ func (c machinesClient) CreateMachine(ctx context.Context, input *CreateMachineI

var machineParams params.AddMachineParams

placement := input.Placement
if placement != "" {
machineParams.Placement, err = instance.ParsePlacement(placement)
if err == instance.ErrPlacementScopeMissing {
modelUUID, err := c.ModelUUID(input.ModelName)
if err != nil {
return nil, err
}
placement = modelUUID + ":" + placement
machineParams.Placement, err = instance.ParsePlacement(placement)
if err != nil {
return nil, err
}
}
}

if input.Constraints == "" {
modelConstraints, err := modelConfigAPIClient.GetModelConstraints()
if err != nil {
Expand Down Expand Up @@ -300,11 +318,19 @@ func (c machinesClient) ReadMachine(input ReadMachineInput) (ReadMachineResponse
return response, err
}

machineStatus, exists := status.Machines[input.ID]
machineIDParts := strings.Split(input.ID, "/")
machineStatus, exists := status.Machines[machineIDParts[0]]
if !exists {
return response, fmt.Errorf("no status returned for machine: %s", input.ID)
}
c.Tracef("ReadMachine:Machine status result", map[string]interface{}{"machineStatus": machineStatus})
if len(machineIDParts) > 1 {
// check for containers
machineStatus, exists = machineStatus.Containers[input.ID]
if !exists {
return response, fmt.Errorf("no status returned for container in machine: %s", input.ID)
}
}
response.ID = machineStatus.Id
response.Base, response.Series, err = baseAndSeriesFromParams(&machineStatus.Base)
if err != nil {
Expand Down
17 changes: 17 additions & 0 deletions internal/provider/resource_machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ type machineResourceModel struct {
Disks types.String `tfsdk:"disks"`
Base types.String `tfsdk:"base"`
Series types.String `tfsdk:"series"`
Placement types.String `tfsdk:"placement"`
MachineID types.String `tfsdk:"machine_id"`
SSHAddress types.String `tfsdk:"ssh_address"`
PublicKeyFile types.String `tfsdk:"public_key_file"`
Expand Down Expand Up @@ -87,6 +88,7 @@ const (
ConstraintsKey = "constraints"
DisksKey = "disks"
SeriesKey = "series"
PlacementKey = "placement"
BaseKey = "base"
MachineIDKey = "machine_id"
SSHAddressKey = "ssh_address"
Expand Down Expand Up @@ -169,6 +171,20 @@ func (r *machineResource) Schema(_ context.Context, req resource.SchemaRequest,
},
DeprecationMessage: "Configure base instead. This attribute will be removed in the next major version of the provider.",
},
PlacementKey: schema.StringAttribute{
Description: "Additional information about how to allocate the machine in the cloud.",
Optional: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.RequiresReplaceIfConfigured(),
stringplanmodifier.UseStateForUnknown(),
},
Validators: []validator.String{
stringvalidator.ConflictsWith(path.Expressions{
path.MatchRoot(SSHAddressKey),
path.MatchRoot(ConstraintsKey),
}...),
},
},
MachineIDKey: schema.StringAttribute{
Description: "The id of the machine Juju creates.",
Computed: true,
Expand Down Expand Up @@ -257,6 +273,7 @@ func (r *machineResource) Create(ctx context.Context, req resource.CreateRequest
Base: data.Base.ValueString(),
Series: data.Series.ValueString(),
SSHAddress: data.SSHAddress.ValueString(),
Placement: data.Placement.ValueString(),
PublicKeyFile: data.PublicKeyFile.ValueString(),
PrivateKeyFile: data.PrivateKeyFile.ValueString(),
})
Expand Down
52 changes: 52 additions & 0 deletions internal/provider/resource_machine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/hashicorp/terraform-plugin-testing/helper/acctest"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
internaltesting "github.com/juju/terraform-provider-juju/internal/testing"
)

func TestAcc_ResourceMachine(t *testing.T) {
Expand Down Expand Up @@ -64,6 +65,33 @@ func TestAcc_ResourceMachine_Minimal(t *testing.T) {
})
}

func TestAcc_ResourceMachine_WithPlacement(t *testing.T) {
if testingCloud != LXDCloudTesting {
t.Skip(t.Name() + " only runs with LXD")
}
modelName := acctest.RandomWithPrefix("tf-test-machine")
resourceName := "juju_machine.this_machine_1"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: frameworkProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccResourceMachineWithPlacement(modelName),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "model", modelName),
resource.TestCheckResourceAttr(resourceName, "machine_id", "0/lxd/0"),
resource.TestCheckResourceAttr(resourceName, "placement", "lxd:0"),
),
},
{
ImportStateVerify: false,
ImportState: true,
ResourceName: resourceName,
},
},
})
}

func testAccResourceMachineBasicMinimal(modelName string) string {
return fmt.Sprintf(`
resource "juju_model" "this" {
Expand Down Expand Up @@ -173,3 +201,27 @@ resource "juju_machine" "this_machine" {
}
`, modelName, IP, pubKeyPath, privKeyPath)
}

func testAccResourceMachineWithPlacement(modelName string) string {
return internaltesting.GetStringFromTemplateWithData(
"testAccResourceMachineWithPlacement",
`
resource "juju_model" "{{.ModelName}}" {
name = "{{.ModelName}}"
}

resource "juju_machine" "this_machine" {
name = "manually_provisioned_machine"
model = juju_model.{{.ModelName}}.name
}

resource "juju_machine" "this_machine_1" {
model = juju_model.{{.ModelName}}.name
name = "this_machine"
placement = "lxd:0"
depends_on = [juju_machine.this_machine]
}
`, internaltesting.TemplateData{
"ModelName": modelName,
})
}
Loading