Skip to content

Commit

Permalink
Merge pull request #75 from itmecho/feature/deployment-data-source
Browse files Browse the repository at this point in the history
Adds Deployment Data Source
  • Loading branch information
sl1pm4t committed Nov 14, 2018
2 parents 3c07717 + 6d9f301 commit c47d4f1
Show file tree
Hide file tree
Showing 4 changed files with 163 additions and 0 deletions.
73 changes: 73 additions & 0 deletions kubernetes/data_souce_helpers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package kubernetes

import (
"github.com/hashicorp/terraform/helper/schema"
)

// datasourceSchemaFromResourceSchema is a recursive func that
// converts an existing Resource schema to a Datasource schema.
// All schema elements are copied, but certain attributes are ignored or changed:
// - all attributes have Computed = true
// - all attributes have ForceNew, Required = false
// - Validation funcs and attributes (e.g. MaxItems) are not copied
func datasourceSchemaFromResourceSchema(rs map[string]*schema.Schema) map[string]*schema.Schema {
ds := make(map[string]*schema.Schema, len(rs))
for k, v := range rs {
dv := &schema.Schema{
Computed: true,
ForceNew: false,
Required: false,
Description: v.Description,
Type: v.Type,
}

switch v.Type {
case schema.TypeSet:
dv.Set = v.Set
fallthrough
case schema.TypeList:
// List & Set types are generally used for 2 cases:
// - a list/set of simple primitive values (e.g. list of strings)
// - a sub resource
if elem, ok := v.Elem.(*schema.Resource); ok {
// handle the case where the Element is a sub-resource
dv.Elem = &schema.Resource{
Schema: datasourceSchemaFromResourceSchema(elem.Schema),
}
} else {
// handle simple primitive case
dv.Elem = v.Elem
}

default:
// Elem of all other types are copied as-is
dv.Elem = v.Elem

}
ds[k] = dv

}
return ds
}

// fixDatasourceSchemaFlags is a convenience func that toggles the Computed,
// Optional + Required flags on a schema element. This is useful when the schema
// has been generated (using `datasourceSchemaFromResourceSchema` above for
// example) and therefore the attribute flags were not set appropriately when
// first added to the schema definition. Currently only supports top-level
// schema elements.
func fixDatasourceSchemaFlags(schema map[string]*schema.Schema, required bool, keys ...string) {
for _, v := range keys {
schema[v].Computed = false
schema[v].Optional = !required
schema[v].Required = required
}
}

func addRequiredFieldsToSchema(schema map[string]*schema.Schema, keys ...string) {
fixDatasourceSchemaFlags(schema, true, keys...)
}

func addOptionalFieldsToSchema(schema map[string]*schema.Schema, keys ...string) {
fixDatasourceSchemaFlags(schema, false, keys...)
}
31 changes: 31 additions & 0 deletions kubernetes/data_source_kubernetes_deployment.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package kubernetes

import (
"github.com/hashicorp/terraform/helper/schema"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func dataSourceKubernetesDeployment() *schema.Resource {
dsSchema := datasourceSchemaFromResourceSchema(resourceKubernetesDeployment().Schema)

addRequiredFieldsToSchema(dsSchema, "metadata")
addRequiredFieldsToSchema(dsSchema["metadata"].Elem.(*schema.Resource).Schema, "name")

addRequiredFieldsToSchema(dsSchema["metadata"].Elem.(*schema.Resource).Schema, "namespace")

return &schema.Resource{
Read: dataSourceKubernetesDeploymentRead,

Schema: dsSchema,
}
}

func dataSourceKubernetesDeploymentRead(d *schema.ResourceData, meta interface{}) error {
om := meta_v1.ObjectMeta{
Namespace: d.Get("metadata.0.namespace").(string),
Name: d.Get("metadata.0.name").(string),
}
d.SetId(buildId(om))

return resourceKubernetesDeploymentRead(d, meta)
}
58 changes: 58 additions & 0 deletions kubernetes/data_source_kubernetes_deployment_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package kubernetes

import (
"fmt"
"testing"

"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)

func TestAccKubernetesDataSourceDeployment_basic(t *testing.T) {
name := fmt.Sprintf("tf-acc-test-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccKubernetesDataSourceDeploymentConfig_basic(name),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("data.kubernetes_deployment.test", "metadata.0.name", name),
resource.TestCheckResourceAttrSet("data.kubernetes_deployment.test", "metadata.0.generation"),
resource.TestCheckResourceAttrSet("data.kubernetes_deployment.test", "metadata.0.resource_version"),
resource.TestCheckResourceAttrSet("data.kubernetes_deployment.test", "metadata.0.self_link"),
resource.TestCheckResourceAttrSet("data.kubernetes_deployment.test", "metadata.0.uid"),
resource.TestCheckResourceAttr("data.kubernetes_deployment.test", "spec.#", "1"),
resource.TestCheckResourceAttr("data.kubernetes_deployment.test", "spec.0.min_ready_seconds", "0"),
resource.TestCheckResourceAttr("data.kubernetes_deployment.test", "spec.0.paused", "false"),
resource.TestCheckResourceAttr("data.kubernetes_deployment.test", "spec.0.progress_deadline_seconds", "600"),
resource.TestCheckResourceAttr("data.kubernetes_deployment.test", "spec.0.replicas", "1"),
resource.TestCheckResourceAttr("data.kubernetes_deployment.test", "spec.0.revision_history_limit", "10"),
resource.TestCheckResourceAttr("data.kubernetes_deployment.test", "spec.0.strategy.#", "1"),
resource.TestCheckResourceAttr("data.kubernetes_deployment.test", "spec.0.strategy.0.type", "RollingUpdate"),
resource.TestCheckResourceAttr("data.kubernetes_deployment.test", "spec.0.strategy.0.rolling_update.#", "1"),
resource.TestCheckResourceAttr("data.kubernetes_deployment.test", "spec.0.strategy.0.rolling_update.0.max_surge", "25%"),
resource.TestCheckResourceAttr("data.kubernetes_deployment.test", "spec.0.strategy.0.rolling_update.0.max_unavailable", "25%"),
resource.TestCheckResourceAttr("data.kubernetes_deployment.test", "spec.0.template.#", "1"),
resource.TestCheckResourceAttr("data.kubernetes_deployment.test", "spec.0.template.0.metadata.0.name", ""),
resource.TestCheckResourceAttr("data.kubernetes_deployment.test", "spec.0.template.0.spec.#", "1"),
resource.TestCheckResourceAttr("data.kubernetes_deployment.test", "spec.0.template.0.spec.0.container.#", "1"),
resource.TestCheckResourceAttr("data.kubernetes_deployment.test", "spec.0.template.0.spec.0.container.0.name", "tf-acc-test"),
resource.TestCheckResourceAttr("data.kubernetes_deployment.test", "spec.0.template.0.spec.0.container.0.image", "nginx:1.7.8"),
),
},
},
})
}

func testAccKubernetesDataSourceDeploymentConfig_basic(name string) string {
return testAccKubernetesDeploymentConfig_basic(name, 1) + `
data "kubernetes_deployment" "test" {
metadata {
name = "${kubernetes_deployment.test.metadata.0.name}"
namespace = "${kubernetes_deployment.test.metadata.0.namespace}"
}
}
`
}
1 change: 1 addition & 0 deletions kubernetes/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ func Provider() terraform.ResourceProvider {
},

DataSourcesMap: map[string]*schema.Resource{
"kubernetes_deployment": dataSourceKubernetesDeployment(),
"kubernetes_secret": dataSourceKubernetesSecret(),
"kubernetes_service": dataSourceKubernetesService(),
"kubernetes_storage_class": dataSourceKubernetesStorageClass(),
Expand Down

0 comments on commit c47d4f1

Please sign in to comment.