Skip to content

Commit

Permalink
feat: support formations and vessels (#31)
Browse files Browse the repository at this point in the history
  • Loading branch information
nrwiersma authored Jul 19, 2024
1 parent 1d447c9 commit 8a79538
Show file tree
Hide file tree
Showing 23 changed files with 5,485 additions and 29 deletions.
466 changes: 466 additions & 0 deletions docs/data-sources/formation_formation.md

Large diffs are not rendered by default.

466 changes: 466 additions & 0 deletions docs/data-sources/formation_formation_v1beta1.md

Large diffs are not rendered by default.

396 changes: 396 additions & 0 deletions docs/data-sources/formation_vessel.md

Large diffs are not rendered by default.

396 changes: 396 additions & 0 deletions docs/data-sources/formation_vessel_v1beta1.md

Large diffs are not rendered by default.

466 changes: 466 additions & 0 deletions docs/resources/formation_formation.md

Large diffs are not rendered by default.

466 changes: 466 additions & 0 deletions docs/resources/formation_formation_v1beta1.md

Large diffs are not rendered by default.

396 changes: 396 additions & 0 deletions docs/resources/formation_vessel.md

Large diffs are not rendered by default.

396 changes: 396 additions & 0 deletions docs/resources/formation_vessel_v1beta1.md

Large diffs are not rendered by default.

26 changes: 26 additions & 0 deletions ec/formation/data_source_formation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package formation

import (
"context"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/nitrado/terraform-provider-ec/ec"
)

// DataSourceFormation returns the data source resource for a Formation.
func DataSourceFormation() *schema.Resource {
return &schema.Resource{
Description: "Use this data source to access information about an existing Formation.",
ReadContext: dataSourceFormationRead,
Schema: formationSchema(),
}
}

func dataSourceFormationRead(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics {
name := d.Get("metadata.0.name").(string)
env := d.Get("metadata.0.environment").(string)
d.SetId(ec.ScopedName(env, name))

return resourceFormationRead(ctx, d, m)
}
92 changes: 92 additions & 0 deletions ec/formation/data_source_formation_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package formation_test

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/nitrado/terraform-provider-ec/ec/provider/providertest"
)

func TestDataSourceFormations(t *testing.T) {
name := "my-armadaset"
env := "dflt"
pf, _ := providertest.SetupProviderFactories(t)

resource.Test(t, resource.TestCase{
IsUnitTest: true,
ProviderFactories: pf,
Steps: []resource.TestStep{
{
Config: testDataSourceFormationConfigBasic(name, env),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("ec_formation_formation.test", "metadata.0.name", name),
resource.TestCheckResourceAttr("ec_formation_formation.test", "metadata.0.environment", env),
resource.TestCheckResourceAttr("ec_formation_formation.test", "spec.#", "1"),
resource.TestCheckResourceAttr("ec_formation_formation.test", "spec.0.description", "My Formation"),
resource.TestCheckResourceAttr("ec_formation_formation.test", "spec.0.vessels.0.region", "eu"),
resource.TestCheckResourceAttr("ec_formation_formation.test", "spec.0.template.0.metadata.0.labels.foo", "bar"),
resource.TestCheckResourceAttr("ec_formation_formation.test", "spec.0.template.0.spec.0.containers.0.name", "my-ctr"),
resource.TestCheckResourceAttr("ec_formation_formation.test", "spec.0.template.0.spec.0.containers.0.branch", "prod"),
resource.TestCheckResourceAttr("ec_formation_formation.test", "spec.0.template.0.spec.0.containers.0.image", "test-xyz"),
),
},
{
Config: testDataSourceFormationConfigBasic(name, env) +
testDataSourceFormationConfigRead(),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("data.ec_formation_formation.test", "metadata.0.name", name),
resource.TestCheckResourceAttr("ec_formation_formation.test", "metadata.0.environment", env),
resource.TestCheckResourceAttr("data.ec_formation_formation.test", "spec.#", "1"),
resource.TestCheckResourceAttr("data.ec_formation_formation.test", "spec.0.description", "My Formation"),
resource.TestCheckResourceAttr("data.ec_formation_formation.test", "spec.0.vessels.0.region", "eu"),
resource.TestCheckResourceAttr("data.ec_formation_formation.test", "spec.0.template.0.metadata.0.labels.foo", "bar"),
resource.TestCheckResourceAttr("data.ec_formation_formation.test", "spec.0.template.0.spec.0.containers.0.name", "my-ctr"),
resource.TestCheckResourceAttr("data.ec_formation_formation.test", "spec.0.template.0.spec.0.containers.0.branch", "prod"),
resource.TestCheckResourceAttr("data.ec_formation_formation.test", "spec.0.template.0.spec.0.containers.0.image", "test-xyz"),
),
},
},
})
}

func testDataSourceFormationConfigBasic(name, env string) string {
return fmt.Sprintf(`resource "ec_formation_formation" "test" {
metadata {
name = "%s"
environment = "%s"
}
spec {
description = "My Formation"
vessels {
name = "eu-vessel"
region = "eu"
}
template {
metadata {
labels = {
"foo" = "bar"
}
}
spec {
containers {
name = "my-ctr"
branch = "prod"
image = "test-xyz"
}
}
}
}
}
`, name, env)
}

func testDataSourceFormationConfigRead() string {
return `data "ec_formation_formation" "test" {
metadata {
name = "${ec_formation_formation.test.metadata.0.name}"
environment = "${ec_formation_formation.test.metadata.0.environment}"
}
}
`
}
26 changes: 26 additions & 0 deletions ec/formation/data_source_vessel.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package formation

import (
"context"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/nitrado/terraform-provider-ec/ec"
)

// DataSourceVessel returns the data source resource for a Vessel.
func DataSourceVessel() *schema.Resource {
return &schema.Resource{
Description: "Use this data source to access information about an existing Vessel.",
ReadContext: dataSourceVesselRead,
Schema: vesselSchema(),
}
}

func dataSourceVesselRead(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics {
name := d.Get("metadata.0.name").(string)
env := d.Get("metadata.0.environment").(string)
d.SetId(ec.ScopedName(env, name))

return resourceVesselRead(ctx, d, m)
}
89 changes: 89 additions & 0 deletions ec/formation/data_source_vessel_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package formation_test

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/nitrado/terraform-provider-ec/ec/provider/providertest"
)

func TestDataSourceVessels(t *testing.T) {
name := "my-vessel"
env := "dflt"
pf, _ := providertest.SetupProviderFactories(t)

resource.Test(t, resource.TestCase{
IsUnitTest: true,
ProviderFactories: pf,
Steps: []resource.TestStep{
{
Config: testDataSourceVesselsConfigBasic(name, env),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("ec_formation_vessel.test", "metadata.0.name", name),
resource.TestCheckResourceAttr("ec_formation_vessel.test", "metadata.0.environment", env),
resource.TestCheckResourceAttr("ec_formation_vessel.test", "spec.#", "1"),
resource.TestCheckResourceAttr("ec_formation_vessel.test", "spec.0.description", "My Vessel"),
resource.TestCheckResourceAttr("ec_formation_vessel.test", "spec.0.region", "eu"),
resource.TestCheckResourceAttr("ec_formation_vessel.test", "spec.0.template.0.metadata.0.labels.foo", "bar"),
resource.TestCheckResourceAttr("ec_formation_vessel.test", "spec.0.template.0.spec.0.containers.0.name", "my-ctr"),
resource.TestCheckResourceAttr("ec_formation_vessel.test", "spec.0.template.0.spec.0.containers.0.branch", "prod"),
resource.TestCheckResourceAttr("ec_formation_vessel.test", "spec.0.template.0.spec.0.containers.0.image", "test-xyz"),
),
},
{
Config: testDataSourceVesselsConfigBasic(name, env) +
testDataSourceVesselConfigRead(),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("data.ec_formation_vessel.test", "metadata.0.name", name),
resource.TestCheckResourceAttr("data.ec_formation_vessel.test", "metadata.0.environment", env),
resource.TestCheckResourceAttr("data.ec_formation_vessel.test", "spec.#", "1"),
resource.TestCheckResourceAttr("data.ec_formation_vessel.test", "spec.0.description", "My Vessel"),
resource.TestCheckResourceAttr("data.ec_formation_vessel.test", "spec.0.region", "eu"),
resource.TestCheckResourceAttr("data.ec_formation_vessel.test", "spec.0.template.0.metadata.0.labels.foo", "bar"),
resource.TestCheckResourceAttr("data.ec_formation_vessel.test", "spec.0.template.0.spec.0.containers.0.name", "my-ctr"),
resource.TestCheckResourceAttr("data.ec_formation_vessel.test", "spec.0.template.0.spec.0.containers.0.branch", "prod"),
resource.TestCheckResourceAttr("data.ec_formation_vessel.test", "spec.0.template.0.spec.0.containers.0.image", "test-xyz"),
),
},
},
})
}

func testDataSourceVesselsConfigBasic(name, env string) string {
return fmt.Sprintf(`resource "ec_formation_vessel" "test" {
metadata {
name = "%s"
environment = "%s"
}
spec {
description = "My Vessel"
region = "eu"
template {
metadata {
labels = {
"foo" = "bar"
}
}
spec {
containers {
name = "my-ctr"
branch = "prod"
image = "test-xyz"
}
}
}
}
}
`, name, env)
}

func testDataSourceVesselConfigRead() string {
return `data "ec_formation_vessel" "test" {
metadata {
name = "${ec_formation_vessel.test.metadata.0.name}"
environment = "${ec_formation_vessel.test.metadata.0.environment}"
}
}
`
}
129 changes: 129 additions & 0 deletions ec/formation/resource_formation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package formation

import (
"context"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/nitrado/terraform-provider-ec/ec"
"github.com/nitrado/terraform-provider-ec/pkg/resource"
"gitlab.com/nitrado/b2b/ec/apicore/api/errors"
metav1 "gitlab.com/nitrado/b2b/ec/apicore/apis/meta/v1"
formationv1beta1 "gitlab.com/nitrado/b2b/ec/core/pkg/api/formation/v1beta1"
)

// ResourceFormation returns the resource for a Formation.
func ResourceFormation() *schema.Resource {
return &schema.Resource{
Description: "A Formation is a configuration for multiple vessels.",
ReadContext: resourceFormationRead,
CreateContext: resourceFormationCreate,
UpdateContext: resourceFormationUpdate,
DeleteContext: resourceFormationDelete,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Schema: formationSchema(),
}
}

func resourceFormationRead(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics {
inst, _ := d.Get("instance").(string)
clientSet, err := ec.ResolveClientSet(m, inst)
if err != nil {
return diag.FromErr(err)
}

env, name := ec.SplitName(d.Id())

obj, err := clientSet.FormationV1Beta1().Formations(env).Get(ctx, name, metav1.GetOptions{})
if err != nil {
switch {
case errors.IsNotFound(err):
d.SetId("")
return nil
default:
return diag.FromErr(err)
}
}

data, err := ec.Converter().Flatten(obj, formationSchema())
if err != nil {
return diag.FromErr(err)
}

if err = resource.SetData(d, data); err != nil {
return diag.FromErr(err)
}
return nil
}

func resourceFormationCreate(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics {
inst, _ := d.Get("instance").(string)
clientSet, err := ec.ResolveClientSet(m, inst)
if err != nil {
return diag.FromErr(err)
}

obj := &formationv1beta1.Formation{}
if err = ec.Converter().Expand(d.Get("metadata").([]any), &obj.ObjectMeta); err != nil {
return diag.FromErr(err)
}
if err = ec.Converter().Expand(d.Get("spec").([]any), &obj.Spec); err != nil {
return diag.FromErr(err)
}

out, err := clientSet.FormationV1Beta1().Formations(obj.Environment).Create(ctx, obj, metav1.CreateOptions{})
if err != nil {
return diag.FromErr(err)
}

d.SetId(ec.ScopedName(out.Environment, out.Name))
return resourceFormationRead(ctx, d, m)
}

func resourceFormationUpdate(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics {
inst, _ := d.Get("instance").(string)
clientSet, err := ec.ResolveClientSet(m, inst)
if err != nil {
return diag.FromErr(err)
}

obj := &formationv1beta1.Formation{}
if err = ec.Converter().Expand(d.Get("metadata").([]any), &obj.ObjectMeta); err != nil {
return diag.FromErr(err)
}
if err = ec.Converter().Expand(d.Get("spec").([]any), &obj.Spec); err != nil {
return diag.FromErr(err)
}

out, err := clientSet.FormationV1Beta1().Formations(obj.Environment).Update(ctx, obj, metav1.UpdateOptions{})
if err != nil {
return diag.FromErr(err)
}

d.SetId(ec.ScopedName(out.Environment, out.Name))
return resourceFormationRead(ctx, d, m)
}

func resourceFormationDelete(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics {
inst, _ := d.Get("instance").(string)
clientSet, err := ec.ResolveClientSet(m, inst)
if err != nil {
return diag.FromErr(err)
}

env, name := ec.SplitName(d.Id())

if err = clientSet.FormationV1Beta1().Formations(env).Delete(ctx, name, metav1.DeleteOptions{}); err != nil {
switch {
case errors.IsNotFound(err):
// We will consider this a successful delete.
default:
return diag.FromErr(err)
}
}

d.SetId("")
return nil
}
Loading

0 comments on commit 8a79538

Please sign in to comment.