Skip to content

Commit

Permalink
Feat: Add support to Get and Assign AWS EKS Credentials to a Project (#…
Browse files Browse the repository at this point in the history
…862)

* Feat: Add support to Get and Assign AWS EKS Credentials to a Project

* fix example

* added more data sources and examples and updated integration test

* fix depends on
  • Loading branch information
TomerHeber authored May 28, 2024
1 parent dbeba01 commit 31d80fa
Show file tree
Hide file tree
Showing 7 changed files with 231 additions and 0 deletions.
55 changes: 55 additions & 0 deletions env0/data_kubernetes_credentials.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package env0

import (
"context"
"fmt"

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

func dataKubernetesCredentials(credentialsType CloudType) *schema.Resource {
return &schema.Resource{
ReadContext: dataKuberentesCredentialsRead(credentialsType),

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Description: fmt.Sprintf("the name of %s credentials", credentialsType),
Optional: true,
ExactlyOneOf: []string{"name", "id"},
},
"id": {
Type: schema.TypeString,
Description: fmt.Sprintf("the id of %s credentials", credentialsType),
Optional: true,
ExactlyOneOf: []string{"name", "id"},
},
},
}
}

func dataKuberentesCredentialsRead(credentialsType CloudType) func(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
return func(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var credentials client.Credentials
var err error

id, ok := d.GetOk("id")
if ok {
credentials, err = getCredentialsById(id.(string), credentialsTypeToPrefixList[credentialsType], meta)
} else {
credentials, err = getCredentialsByName(d.Get("name").(string), credentialsTypeToPrefixList[credentialsType], meta)
}

if err != nil {
return DataGetFailure(fmt.Sprintf("%s credentials", credentialsType), id, err)
}

if err := writeResourceData(&credentials, d); err != nil {
return diag.Errorf("schema resource data serialization failed: %v", err)
}

return nil
}
}
129 changes: 129 additions & 0 deletions env0/data_kubernetes_credentials_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package env0

import (
"fmt"
"regexp"
"testing"

"github.com/env0/terraform-provider-env0/client"
"github.com/env0/terraform-provider-env0/client/http"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)

func TestKubernetesCredentialsDataSource(t *testing.T) {
tests := [][]string{
{"env0_aws_eks_credentials", string(client.AwsEksCredentialsType)},
{"env0_azure_aks_credentials", string(client.AzureAksCredentialsType)},
{"env0_gcp_gke_credentials", string(client.GcpGkeCredentialsType)},
{"env0_kubeconfig_credentials", string(client.KubeconfigCredentialsType)},
}

for _, test := range tests {
credentials := client.Credentials{
Id: "id0",
Name: "name0",
Type: test[1],
}

credentialsOther1 := client.Credentials{
Id: "id1",
Name: "name1",
Type: test[1],
}

credentialsOther2 := client.Credentials{
Id: "id2",
Name: "name2",
Type: test[1],
}

byName := map[string]interface{}{"name": credentials.Name}
byId := map[string]interface{}{"id": credentials.Id}

resourceType := test[0]
resourceName := "test"
accessor := dataSourceAccessor(resourceType, resourceName)

getValidTestCase := func(input map[string]interface{}) resource.TestCase {
return resource.TestCase{
Steps: []resource.TestStep{
{
Config: dataSourceConfigCreate(resourceType, resourceName, input),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr(accessor, "id", credentials.Id),
resource.TestCheckResourceAttr(accessor, "name", credentials.Name),
),
},
},
}
}

getErrorTestCase := func(input map[string]interface{}, expectedError string) resource.TestCase {
return resource.TestCase{
Steps: []resource.TestStep{
{
Config: dataSourceConfigCreate(resourceType, resourceName, input),
ExpectError: regexp.MustCompile(expectedError),
},
},
}
}

mockGetCredentials := func(returnValue client.Credentials) func(mockFunc *client.MockApiClientInterface) {
return func(mock *client.MockApiClientInterface) {
mock.EXPECT().CloudCredentials(credentials.Id).AnyTimes().Return(returnValue, nil)
}
}

mockListCredentials := func(returnValue []client.Credentials) func(mockFunc *client.MockApiClientInterface) {
return func(mock *client.MockApiClientInterface) {
mock.EXPECT().CloudCredentialsList().AnyTimes().Return(returnValue, nil)
}
}

t.Run("by id", func(t *testing.T) {
runUnitTest(t,
getValidTestCase(byId),
mockGetCredentials(credentials),
)
})

t.Run("by name - "+test[0], func(t *testing.T) {
runUnitTest(t,
getValidTestCase(byName),
mockListCredentials([]client.Credentials{credentials, credentialsOther1, credentialsOther2}),
)
})

t.Run("throw error when no name or id is supplied - "+test[0], func(t *testing.T) {
runUnitTest(t,
getErrorTestCase(map[string]interface{}{}, "one of `id,name` must be specified"),
func(mock *client.MockApiClientInterface) {},
)
})

t.Run("throw error when by name and more than one is returned - "+test[0], func(t *testing.T) {
runUnitTest(t,
getErrorTestCase(byName, "found multiple credentials"),
mockListCredentials([]client.Credentials{credentials, credentialsOther1, credentialsOther2, credentials}),
)
})

t.Run("Throw error when by name and not found - "+test[0], func(t *testing.T) {
runUnitTest(t,
getErrorTestCase(byName, "not found"),
mockListCredentials([]client.Credentials{credentialsOther1, credentialsOther2}),
)
})

t.Run("Throw error when by id and not found - "+test[0], func(t *testing.T) {
runUnitTest(t,
getErrorTestCase(byId, fmt.Sprintf("id %s not found", credentials.Id)),
func(mock *client.MockApiClientInterface) {
mock.EXPECT().CloudCredentials(credentials.Id).AnyTimes().Return(client.Credentials{}, http.NewMockFailedResponseError(404))
},
)
})
}

}
4 changes: 4 additions & 0 deletions env0/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ func Provider(version string) plugin.ProviderFunc {
"env0_azure_credentials": dataCredentials(AZURE_TYPE),
"env0_azure_oidc_credentials": dataOidcCredentials(AZURE_OIDC_TYPE),
"env0_vault_oidc_credentials": dataOidcCredentials(VAULT_OIDC_TYPE),
"env0_aws_eks_credentials": dataKubernetesCredentials(AWS_EKS_TYPE),
"env0_azure_aks_credentials": dataKubernetesCredentials(AZURE_AKS_TYPE),
"env0_gcp_gke_credentials": dataKubernetesCredentials(GCP_GKE_TYPE),
"env0_kubeconfig_credentials": dataKubernetesCredentials(KUBECONFIG_TYPE),
"env0_team": dataTeam(),
"env0_teams": dataTeams(),
"env0_environment": dataEnvironment(),
Expand Down
13 changes: 13 additions & 0 deletions examples/data-sources/env0_aws_eks_credentials/data-source.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
resource "env0_aws_eks_credentials" "example" {
name = "example"
cluster_name = "my-cluster"
cluster_region = "us-east-2"
}

data "env0_aws_eks_credentials" "by_id" {
id = env0_aws_eks_credentials.example.id
}

data "env0_aws_eks_credentials" "by_name" {
name = env0_aws_eks_credentials.example.name
}
2 changes: 2 additions & 0 deletions examples/resources/env0_aws_eks_credentials/import.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
terraform import env0_aws_eks_credentials.by_id d31a6b30-5f69-4d24-937c-22322754934e
terraform import env0_aws_eks_credentials.by_name "credentials name"
14 changes: 14 additions & 0 deletions examples/resources/env0_aws_eks_credentials/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
resource "env0_aws_eks_credentials" "credentials" {
name = "example"
cluster_name = "my-cluster"
cluster_region = "us-east-2"
}

data "env0_project" "project" {
name = "my-project"
}

resource "env0_cloud_credentials_project_assignment" "assignment" {
credential_id = env0_aws_eks_credentials.credentials.id
project_id = data.env0_project.project.id
}
14 changes: 14 additions & 0 deletions tests/integration/024_cloud_credentials/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ resource "random_string" "random" {
min_lower = 8
}

resource "env0_project" "project" {
name = "credentials-project-${random_string.random.result}"
}

resource "env0_aws_credentials" "aws_cred1" {
name = "Test Role arn1 ${random_string.random.result}"
arn = "Role ARN1"
Expand Down Expand Up @@ -67,6 +71,16 @@ resource "env0_aws_eks_credentials" "aws_eks_credentials" {
cluster_region = "us-east-2"
}

resource "env0_cloud_credentials_project_assignment" "eks_to_project_assignment" {
credential_id = env0_aws_eks_credentials.aws_eks_credentials.id
project_id = env0_project.project.id
}

data "env0_aws_eks_credentials" "aws_eks_credentials" {
depends_on = [env0_aws_eks_credentials.aws_eks_credentials]
name = "aws-eks-${random_string.random.result}"
}

resource "env0_azure_aks_credentials" "azure_aks_credentials" {
name = "azure-aks-${random_string.random.result}"
cluster_name = "my-cluster"
Expand Down

0 comments on commit 31d80fa

Please sign in to comment.