Skip to content

Commit

Permalink
feat: [CDS-57125]: Added support for IAM role (#547)
Browse files Browse the repository at this point in the history
* IAM role contract changes

* changelog

* test for data source

* Resource UT

* clustername, caData

* fix failing App test

* fix tests

* remove awsAuthConfig

* name in app

* Update go-sdk
  • Loading branch information
mankrit-singh committed Jun 20, 2023
1 parent 104043e commit a08a8c7
Show file tree
Hide file tree
Showing 11 changed files with 211 additions and 52 deletions.
3 changes: 3 additions & 0 deletions .changelog/578.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
resource/harness_platform_gitops_cluster: Added support for IAM role in GitOps
```
2 changes: 2 additions & 0 deletions docs/data-sources/platform_gitops_cluster.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ Read-Only:
- `cluster_connection_type` (String)
- `exec_provider_config` (List of Object) (see [below for nested schema](#nestedobjatt--request--cluster--config--exec_provider_config))
- `password` (String)
- `role_a_r_n` (String)
- `aws_cluster_name` (String)
- `tls_client_config` (List of Object) (see [below for nested schema](#nestedobjatt--request--cluster--config--tls_client_config))
- `username` (String)

Expand Down
4 changes: 3 additions & 1 deletion docs/resources/platform_gitops_cluster.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,11 +154,13 @@ Read-Only:

Optional:

- `aws_auth_config` (Block List) IAM authentication configuration for AWS. (see [below for nested schema](#nestedblock--request--cluster--config--aws_auth_config))
- `aws_auth_config` (Block List) IAM authentication configuration for AWS. (deprecated) (see [below for nested schema](#nestedblock--request--cluster--config--aws_auth_config))
- `bearer_token` (String) Bearer authentication token the cluster.
- `cluster_connection_type` (String) Identifies the authentication method used to connect to the cluster.
- `exec_provider_config` (Block List) Configuration for an exec provider. (see [below for nested schema](#nestedblock--request--cluster--config--exec_provider_config))
- `password` (String) Password of the server of the cluster.
- `role_a_r_n` (String) Optional role ARN. If set then used for AWS IAM Authenticator.
- `aws_cluster_name` (String) AWS Cluster name. If set then AWS CLI EKS token command will be used to access cluster.
- `tls_client_config` (Block List) Settings to enable transport layer security. (see [below for nested schema](#nestedblock--request--cluster--config--tls_client_config))
- `username` (String) Username of the server of the cluster.

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.18
require (
github.com/antihax/optional v1.0.0
github.com/docker/docker v20.10.22+incompatible
github.com/harness/harness-go-sdk v0.3.29
github.com/harness/harness-go-sdk v0.3.30
github.com/harness/harness-openapi-go-client v0.0.17
github.com/hashicorp/terraform-plugin-sdk/v2 v2.26.1
github.com/pkg/errors v0.9.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/harness/harness-go-sdk v0.3.29 h1:CPvXSrlHkO33R0yNHvhcRVHkYPDZxc5NvQzsldW2edw=
github.com/harness/harness-go-sdk v0.3.29/go.mod h1:CPXydorp4zd5Dz2u2FXiHyWL4yd5PQafOMN69cgPSvk=
github.com/harness/harness-go-sdk v0.3.30 h1:hdAXNHiaV/8fI6eHdnqvQkzLH7DiVY8Iz52HxAqX75U=
github.com/harness/harness-go-sdk v0.3.30/go.mod h1:CPXydorp4zd5Dz2u2FXiHyWL4yd5PQafOMN69cgPSvk=
github.com/harness/harness-openapi-go-client v0.0.17 h1:EZneIyi6sV+dlTgXbawxdVD0OoDmG3mnGHEJbwslRzc=
github.com/harness/harness-openapi-go-client v0.0.17/go.mod h1:u0vqYb994BJGotmEwJevF4L3BNAdU9i8ui2d22gmLPA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ func testAccDataSourceGitopsApplication(id string, accountId string, name string
org_id = harness_platform_organization.test.id
account_id = "%[2]s"
identifier = "%[1]s"
name = "%[3]s"
cluster_id = "%[8]s"
repo_id = "%[10]s"
agent_id = "%[4]s"
Expand All @@ -120,6 +121,7 @@ func testAccDataSourceGitopsApplication(id string, accountId string, name string
org_id = harness_platform_organization.test.id
agent_id = "%[4]s"
repo_id = "%[10]s"
name = "%[3]s"
}
`, id, accountId, name, agentId, clusterName, namespace, clusterServer, clusterId, repo, repoId)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ package applications_test

import (
"fmt"
"github.com/antihax/optional"
"github.com/harness/harness-go-sdk/harness/nextgen"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"os"
"strings"
"testing"

"github.com/antihax/optional"
"github.com/harness/harness-go-sdk/harness/nextgen"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"

"github.com/harness/harness-go-sdk/harness/utils"
"github.com/harness/terraform-provider-harness/internal/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
Expand Down Expand Up @@ -281,6 +282,7 @@ func testAccResourceGitopsApplicationKustomize(id string, accountId string, name
cluster_id = "%[8]s"
repo_id = "%[10]s"
agent_id = "%[4]s"
name = "%[3]s"
}
`, id, accountId, name, agentId, clusterName, namespace, clusterServer, clusterId, repo, repoId)
}
Original file line number Diff line number Diff line change
Expand Up @@ -213,24 +213,15 @@ func DataSourceGitopsCluster() *schema.Resource {
},
},
},
"aws_auth_config": {
Description: "IAM authentication configuration for AWS.",
Type: schema.TypeList,
"role_a_r_n": {
Description: "Optional role ARN. If set then used for AWS IAM Authenticator.",
Type: schema.TypeString,
Optional: true,
},
"aws_cluster_name": {
Description: "AWS Cluster name. If set then AWS CLI EKS token command will be used to access cluster.",
Type: schema.TypeString,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"cluster_name": {
Description: "AWS cluster name.",
Type: schema.TypeString,
Optional: true,
},
"role_a_r_n": {
Description: "Optional role ARN. If set then used for AWS IAM Authenticator.",
Type: schema.TypeString,
Optional: true,
},
},
},
},
"exec_provider_config": {
Description: "Configuration for an exec provider.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ package cluster_test

import (
"fmt"
"github.com/harness/harness-go-sdk/harness/utils"
"os"
"strings"
"testing"

"github.com/harness/harness-go-sdk/harness/utils"

"github.com/harness/terraform-provider-harness/internal/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)
Expand Down Expand Up @@ -37,6 +38,36 @@ func TestAccDataSourceGitopsCluster(t *testing.T) {
})
}

func TestAccDataSourceGitopsClusterIAM(t *testing.T) {

id := strings.ToLower(fmt.Sprintf("%s%s", t.Name(), utils.RandStringBytes(5)))
id = strings.ReplaceAll(id, "_", "")
name := id
agentId := os.Getenv("HARNESS_TEST_AWS_GITOPS_AGENT")
accountId := os.Getenv("HARNESS_ACCOUNT_ID")
clusterName := id
clusterServer := os.Getenv("HARNESS_TEST_AWS_CLUSTER_SERVER")
roleARN := os.Getenv("HARNESS_TEST_AWS_CLUSTER_ROLE_ARN")
awsClusterName := os.Getenv("HARNESS_TEST_AWS_CLUSTER_NAME")
caData := os.Getenv("HARNESS_TEST_AWS_CLUSTER_CA_DATA")
resourceName := "data.harness_platform_gitops_cluster.test"

resource.UnitTest(t, resource.TestCase{
PreCheck: func() { acctest.TestAccPreCheck(t) },
ProviderFactories: acctest.ProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccDataSourceGitopsClusterIAM(id, accountId, name, agentId, clusterName, clusterServer, roleARN, awsClusterName, caData),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "identifier", id),
resource.TestCheckResourceAttr(resourceName, "org_id", id),
resource.TestCheckResourceAttr(resourceName, "project_id", id),
),
},
},
})
}

func testAccDataSourceGitopsCluster(id string, accountId string, name string, agentId string, clusterName string) string {
return fmt.Sprintf(`
resource "harness_platform_organization" "test" {
Expand Down Expand Up @@ -88,3 +119,58 @@ func testAccDataSourceGitopsCluster(id string, accountId string, name string, ag
`, id, accountId, name, agentId, clusterName)

}

func testAccDataSourceGitopsClusterIAM(id string, accountId string, name string, agentId string, clusterName string, clusterServer string, roleARN string, awsClusterName string, caData string) string {
return fmt.Sprintf(`
resource "harness_platform_organization" "test" {
identifier = "%[1]s"
name = "%[3]s"
}
resource "harness_platform_project" "test" {
identifier = "%[1]s"
name = "%[3]s"
org_id = harness_platform_organization.test.id
}
resource "harness_platform_gitops_cluster" "test" {
identifier = "%[1]s"
account_id = "%[2]s"
project_id = harness_platform_project.test.id
org_id = harness_platform_organization.test.id
agent_id = "%[4]s"
request {
upsert = true
cluster {
name = "%[5]s"
server = "%[6]s"
config {
tls_client_config {
insecure = false
ca_data = "%[9]s"
}
cluster_connection_type = "IRSA"
role_a_r_n = "%[7]s"
aws_cluster_name = "%[8]s"
}
}
}
lifecycle {
ignore_changes = [
request.0.upsert, request.0.cluster.0.config.0.bearer_token, request.0.cluster.0.info,
]
}
}
data "harness_platform_gitops_cluster" "test" {
depends_on = [harness_platform_gitops_cluster.test]
identifier = harness_platform_gitops_cluster.test.id
account_id = "%[2]s"
project_id = harness_platform_project.test.id
org_id = harness_platform_organization.test.id
agent_id = "%[4]s"
}
`, id, accountId, name, agentId, clusterName, clusterServer, roleARN, awsClusterName, caData)

}
43 changes: 16 additions & 27 deletions internal/service/platform/gitops/cluster/resource_gitops_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,24 +219,15 @@ func ResourceGitopsCluster() *schema.Resource {
},
},
},
"aws_auth_config": {
Description: "IAM authentication configuration for AWS.",
Type: schema.TypeList,
"role_a_r_n": {
Description: "Optional role ARN. If set then used for AWS IAM Authenticator.",
Type: schema.TypeString,
Optional: true,
},
"aws_cluster_name": {
Description: "AWS Cluster name. If set then AWS CLI EKS token command will be used to access cluster.",
Type: schema.TypeString,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"cluster_name": {
Description: "AWS cluster name.",
Type: schema.TypeString,
Optional: true,
},
"role_a_r_n": {
Description: "Optional role ARN. If set then used for AWS IAM Authenticator.",
Type: schema.TypeString,
Optional: true,
},
},
},
},
"exec_provider_config": {
Description: "Configuration for an exec provider.",
Expand Down Expand Up @@ -606,8 +597,9 @@ func setClusterDetails(d *schema.ResourceData, cl *nextgen.Servicev1Cluster) {
awsAuthConfig["cluster_name"] = cl.Cluster.Config.AwsAuthConfig.ClusterName
awsAuthConfig["role_a_r_n"] = cl.Cluster.Config.AwsAuthConfig.RoleARN
awsAuthConfigList = append(awsAuthConfigList, awsAuthConfig)
config["aws_auth_config"] = awsAuthConfigList
}
config["role_a_r_n"] = cl.Cluster.Config.RoleARN
config["aws_cluster_name"] = cl.Cluster.Config.AwsClusterName
if cl.Cluster.Config.ExecProviderConfig != nil {
execProviderConfigList := []interface{}{}
execProviderConfig := map[string]interface{}{}
Expand Down Expand Up @@ -772,15 +764,12 @@ func buildClusterDetails(d *schema.ResourceData) *nextgen.ClustersCluster {
}
}

if clusterConfig["aws_auth_config"] != nil && len(clusterConfig["aws_auth_config"].([]interface{})) > 0 {
clusterDetails.Config.AwsAuthConfig = &nextgen.ClustersAwsAuthConfig{}
configAwsAuthConfig := clusterConfig["aws_auth_config"].([]interface{})[0].(map[string]interface{})
if configAwsAuthConfig["cluster_name"] != nil {
clusterDetails.Config.AwsAuthConfig.ClusterName = configAwsAuthConfig["cluster_name"].(string)
}
if configAwsAuthConfig["role_a_r_n"] != nil {
clusterDetails.Config.AwsAuthConfig.RoleARN = configAwsAuthConfig["role_a_r_n"].(string)
}
if clusterConfig["role_a_r_n"] != nil {
clusterDetails.Config.RoleARN = clusterConfig["role_a_r_n"].(string)
}

if clusterConfig["aws_cluster_name"] != nil {
clusterDetails.Config.AwsClusterName = clusterConfig["aws_cluster_name"].(string)
}

if clusterConfig["exec_provider_config"] != nil && len(clusterConfig["exec_provider_config"].([]interface{})) > 0 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,46 @@ func TestAccResourceGitopsCluster(t *testing.T) {
},
},
})

// Project Level with IAM
id = strings.ToLower(fmt.Sprintf("%s%s", t.Name(), utils.RandStringBytes(5)))
id = strings.ReplaceAll(id, "_", "")
name = id
clusterName = id
resourceName = "harness_platform_gitops_cluster.test"
clusterServer = os.Getenv("HARNESS_TEST_AWS_CLUSTER_SERVER")
roleARN := os.Getenv("HARNESS_TEST_AWS_CLUSTER_ROLE_ARN")
awsClusterName := os.Getenv("HARNESS_TEST_AWS_CLUSTER_NAME")
caData := os.Getenv("HARNESS_TEST_AWS_CLUSTER_CA_DATA")
agentId = os.Getenv("HARNESS_TEST_AWS_GITOPS_AGENT")
resource.UnitTest(t, resource.TestCase{
PreCheck: func() { acctest.TestAccPreCheck(t) },
ProviderFactories: acctest.ProviderFactories,
CheckDestroy: testAccResourceGitopsClusterDestroy(resourceName),
Steps: []resource.TestStep{
{
Config: testAccResourceGitopsClusterProjectLevelIAM(id, accountId, name, agentId, clusterName, clusterServer, roleARN, awsClusterName, caData),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "id", id),
resource.TestCheckResourceAttr(resourceName, "identifier", id),
),
},
{
Config: testAccResourceGitopsClusterProjectLevelIAM(id, accountId, name, agentId, clusterName, clusterServer, roleARN, awsClusterName, caData),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "id", id),
resource.TestCheckResourceAttr(resourceName, "identifier", id),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"request.0.cluster.0.info"},
ImportStateIdFunc: acctest.GitopsAgentProjectLevelResourceImportStateIdFunc(resourceName),
},
},
})
}

func testAccGetCluster(resourceName string, state *terraform.State) (*nextgen.Servicev1Cluster, error) {
Expand Down Expand Up @@ -261,3 +301,45 @@ func testAccResourceGitopsClusterProjectLevel(id string, accountId string, name
}
`, id, accountId, name, agentId, clusterName, clusterServer, clusterToken)
}

func testAccResourceGitopsClusterProjectLevelIAM(id string, accountId string, name string, agentId string, clusterName string, clusterServer string, roleARN string, awsClusterName string, caData string) string {
return fmt.Sprintf(`
resource "harness_platform_organization" "test" {
identifier = "%[1]s"
name = "%[3]s"
}
resource "harness_platform_project" "test" {
identifier = "%[1]s"
name = "%[3]s"
org_id = harness_platform_organization.test.id
}
resource "harness_platform_gitops_cluster" "test" {
identifier = "%[1]s"
account_id = "%[2]s"
agent_id = "%[4]s"
project_id = harness_platform_project.test.id
org_id = harness_platform_organization.test.id
request {
upsert = true
cluster {
server = "%[6]s"
name = "%[5]s"
config {
role_a_r_n = "%[7]s"
aws_cluster_name = "%[8]s"
tls_client_config {
insecure = false
ca_data = "%[9]s"
}
cluster_connection_type = "IRSA"
}
}
}
lifecycle {
ignore_changes = [
request.0.upsert, request.0.cluster.0.config.0.bearer_token, request.0.cluster.0.info,
]
}
}
`, id, accountId, name, agentId, clusterName, clusterServer, roleARN, awsClusterName, caData)
}

0 comments on commit a08a8c7

Please sign in to comment.