Skip to content

Commit

Permalink
feat(cae): supports creating and deploying component
Browse files Browse the repository at this point in the history
  • Loading branch information
wuzhuanhong committed Jan 7, 2025
1 parent 6d188aa commit 47f8131
Show file tree
Hide file tree
Showing 3 changed files with 358 additions and 51 deletions.
35 changes: 29 additions & 6 deletions docs/resources/cae_component.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@ The following arguments are supported:
If omitted, the provider-level region will be used.
Changing this creates a new resource.

* `environment_id` - (Required, String, ForceNew) Specifies the environment ID to which the application and the
* `environment_id` - (Required, String, ForceNew) Specifies the ID of the environment to which the application and the
component belongs.
Changing this creates a new resource.

* `application_id` - (Required, String, ForceNew) Specifies the application ID to which the component belongs.
* `application_id` - (Required, String, ForceNew) Specifies the ID of the application to which the component belongs.
Changing this creates a new resource.

* `metadata` - (Required, List) Specifies the metadata of the component.
Expand All @@ -71,6 +71,16 @@ The following arguments are supported:
* `spec` - (Required, List) Specifies the configuration information of the component.
The [spec](#component_spec) structure is documented below.

* `deploy_after_create` - (Optional, Bool, ForceNew) Specifies whether to deploy the component after creating the resource.
Defaults to **false**.
Changing this creates a new resource.

* `configurations` - (Optional, List, ForceNew) Specifies the list of configurations of the component.
The [configurations](#component_configurations) structure is documented below.
Changing this creates a new resource.

-> This parameter is available only when the `deploy_after_create` parameter is set to **true**.

<a name="component_metadata"></a>
The `metadata` block supports:

Expand All @@ -80,7 +90,7 @@ The `metadata` block supports:

* `annotations` - (Required, Map) Specifies the key/value pairs parameters related to the component.
Currently, only `version` is supported and required.
The format is `A.B.C` or `A.B.C.D`, A, B, C and D must be interger. e.g.`1.0.0` or `1.0.0.0`
The format is `A.B.C` or `A.B.C.D`, A, B, C and D must be integer. e.g.`1.0.0` or `1.0.0.0`

<a name="component_spec"></a>
The `spec` block supports:
Expand Down Expand Up @@ -155,7 +165,7 @@ The `build` block supports:
+ **artifact_name**: Select and run the specified JAR package from multiple JAR packages generated during Maven build.
The JAR package end with **.jar**. Fuzzy match is supported. e.g. `demo-1.0.jar`, `demo*.jar`.

-> `build_cmd`, `dockerfile_path` and `artifact_name` parameters is valid only when `source.type` is set to `code`.
-> `build_cmd`, `dockerfile_path` and `artifact_name` parameters are valid only when `source.type` is set to `code`.
`dockerfile_path` and `artifact_name` parameters can't be set at the same time.
`dockerfile_content` is valid only when `source.type` is set to `softwarePackage`.

Expand All @@ -165,6 +175,19 @@ The `archive` block supports:
* `artifact_namespace` - (Required, String) Specifies the name of the SWR organization after the code source
corresponding to component is built.

<a name="component_configurations"></a>
The `configurations` block supports:

* `type` - (Required, String, ForceNew) Specifies the type of the component configuration.
Please following [reference documentation](https://support.huaweicloud.com/api-cae/CreateComponentWithConfiguration.html#CreateComponentWithConfiguration__request_ConfigurationItem).

Changing this creates a new resource.

* `data` - (Required, String, ForceNew) Specifies the component configuration detail, in JSON format.
Please following [reference documentation](https://support.huaweicloud.com/api-cae/CreateComponentWithConfiguration.html#CreateComponentWithConfiguration__response_ConfigurationData).

Changing this creates a new resource.

## Attribute Reference

In addition to all arguments above, the following attributes are exported:
Expand All @@ -185,7 +208,7 @@ $ terraform import huaweicloud_cae_component.test <environment_id>/<application_

Note that the imported state may not be identical to your resource definition, due to some attributes missing from the
API response, security or some other reason.
The missing attributes include: `metadata.0.annotations`, `spec.0.build.0.parameters`.
The missing attributes include: `metadata.0.annotations`, `spec.0.build.0.parameters`, `deploy_after_create`, `configurations`.
It is generally recommended running `terraform plan` after importing the resource.
You can then decide if changes should be applied to the resource, or the resource definition should be updated to
align with the resource. Also you can ignore changes as below.
Expand All @@ -196,7 +219,7 @@ resource "huaweicloud_cae_component" "test" {
lifecycle {
ignore_changes = [
metadata.0.annotations, spec.0.build.0.parameters,
metadata.0.annotations, spec.0.build.0.parameters, deploy_after_create, configurations,
]
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cae

import (
"fmt"
"regexp"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
Expand All @@ -13,9 +14,14 @@ import (
)

func getComponentFunc(cfg *config.Config, state *terraform.ResourceState) (interface{}, error) {
client, err := cfg.NewServiceClient("cae", acceptance.HW_REGION_NAME)
if err != nil {
return nil, fmt.Errorf("error creating CAE client: %s", err)
}

environmentId := state.Primary.Attributes["environment_id"]
applicationId := state.Primary.Attributes["application_id"]
return cae.GetComponentById(cfg, acceptance.HW_REGION_NAME, environmentId, applicationId, state.Primary.ID)
return cae.GetComponentById(client, environmentId, applicationId, state.Primary.ID)
}

func TestAccComponent_basic(t *testing.T) {
Expand Down Expand Up @@ -198,3 +204,153 @@ func testAccComponentImportStateFunc(name string) resource.ImportStateIdFunc {
return fmt.Sprintf("%s/%s/%s", environmentId, applicationId, componentId), nil
}
}

func TestAccComponent_deploy(t *testing.T) {
var (
obj interface{}
withConfiguration = "huaweicloud_cae_component.test.0"
withoutConfiguration = "huaweicloud_cae_component.test.1"
name = acceptance.RandomAccResourceNameWithDash()
rcWithConfiguration = acceptance.InitResourceCheck(withConfiguration, &obj, getComponentFunc)
rcWithoutConfiguration = acceptance.InitResourceCheck(withoutConfiguration, &obj, getComponentFunc)
)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
acceptance.TestAccPreCheck(t)
acceptance.TestAccPreCheckCaeEnvironment(t)
acceptance.TestAccPreCheckCaeApplication(t)
},
ProviderFactories: acceptance.TestAccProviderFactories,
CheckDestroy: resource.ComposeTestCheckFunc(
rcWithConfiguration.CheckResourceDestroy(),
rcWithoutConfiguration.CheckResourceDestroy(),
),
Steps: []resource.TestStep{
{
Config: testAccComponent_deploy(name),
Check: resource.ComposeTestCheckFunc(
rcWithConfiguration.CheckResourceExists(),
rcWithoutConfiguration.CheckResourceExists(),
resource.TestMatchResourceAttr(withConfiguration, "metadata.0.name", regexp.MustCompile(name)),
resource.TestCheckResourceAttr(withConfiguration, "environment_id", acceptance.HW_CAE_ENVIRONMENT_ID),
resource.TestCheckResourceAttr(withConfiguration, "application_id", acceptance.HW_CAE_APPLICATION_ID),
resource.TestCheckResourceAttr(withConfiguration, "metadata.0.annotations.version", "1.0.0"),
resource.TestCheckResourceAttr(withConfiguration, "spec.0.replica", "1"),
resource.TestCheckResourceAttr(withConfiguration, "spec.0.runtime", "Docker"),
resource.TestCheckResourceAttr(withConfiguration, "spec.0.resource_limit.0.cpu", "500m"),
resource.TestCheckResourceAttr(withConfiguration, "spec.0.resource_limit.0.memory", "1Gi"),
resource.TestCheckResourceAttr(withConfiguration, "spec.0.source.0.type", "image"),
resource.TestCheckResourceAttrSet(withConfiguration, "spec.0.source.0.url"),
),
},
{
ResourceName: "huaweicloud_cae_component.test[0]",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{
"metadata.0.annotations",
"spec.0.build.0.parameters",
"deploy_after_create",
"configurations",
},
ImportStateIdFunc: testAccComponentImportStateFunc(withConfiguration),
},
{
ResourceName: "huaweicloud_cae_component.test[1]",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{
"metadata.0.annotations",
"spec.0.build.0.parameters",
"deploy_after_create",
"configurations",
},
ImportStateIdFunc: testAccComponentImportStateFunc(withoutConfiguration),
},
},
})
}

func testAccComponent_deploy(name string) string {
return fmt.Sprintf(`
data "huaweicloud_swr_repositories" "test" {}
locals {
swr_repositories = [for v in data.huaweicloud_swr_repositories.test.repositories : v if length(v.tags) > 0][0]
}
locals {
configurations = [
{
type = "env"
data = jsonencode({
"spec" : {
"envs" : {
"key" : "value",
"foo" : "baar"
}
}
})
},
{
type = "lifecycle"
data = jsonencode({
"spec" : {
"postStart" : {
"exec" : {
"command" : [
"/bin/bash",
"-c",
"sleep",
"10",
"done"
]
}
}
}
})
}
]
}
resource "huaweicloud_cae_component" "test" {
count = 2
environment_id = "%[1]s"
application_id = "%[2]s"
metadata {
name = "%[3]s${count.index}"
annotations = {
version = "1.0.0"
}
}
spec {
replica = 1
runtime = "Docker"
source {
type = "image"
url = format("%%s:%%s", local.swr_repositories.path, local.swr_repositories.tags[0])
}
resource_limit {
cpu = "500m"
memory = "1Gi"
}
}
deploy_after_create = true
dynamic "configurations" {
for_each = count.index == 0 ? local.configurations : []
content {
type = configurations.value.type
data = configurations.value.data
}
}
}
`, acceptance.HW_CAE_ENVIRONMENT_ID, acceptance.HW_CAE_APPLICATION_ID, name)
}
Loading

0 comments on commit 47f8131

Please sign in to comment.