provider/kubernetes: Add support for persistent_volume_claim (#13527)

This commit is contained in:
Radek Simko 2017-04-12 08:33:26 +01:00 committed by GitHub
parent 9343a9da82
commit 1cf0cd87cb
6 changed files with 1189 additions and 4 deletions

View File

@ -86,10 +86,11 @@ func Provider() terraform.ResourceProvider {
},
ResourcesMap: map[string]*schema.Resource{
"kubernetes_config_map": resourceKubernetesConfigMap(),
"kubernetes_namespace": resourceKubernetesNamespace(),
"kubernetes_persistent_volume": resourceKubernetesPersistentVolume(),
"kubernetes_secret": resourceKubernetesSecret(),
"kubernetes_config_map": resourceKubernetesConfigMap(),
"kubernetes_namespace": resourceKubernetesNamespace(),
"kubernetes_persistent_volume": resourceKubernetesPersistentVolume(),
"kubernetes_persistent_volume_claim": resourceKubernetesPersistentVolumeClaim(),
"kubernetes_secret": resourceKubernetesSecret(),
},
ConfigureFunc: providerConfigure,
}

View File

@ -0,0 +1,266 @@
package kubernetes
import (
"fmt"
"log"
"time"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
pkgApi "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/errors"
api "k8s.io/kubernetes/pkg/api/v1"
kubernetes "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5"
)
func resourceKubernetesPersistentVolumeClaim() *schema.Resource {
return &schema.Resource{
Create: resourceKubernetesPersistentVolumeClaimCreate,
Read: resourceKubernetesPersistentVolumeClaimRead,
Exists: resourceKubernetesPersistentVolumeClaimExists,
Update: resourceKubernetesPersistentVolumeClaimUpdate,
Delete: resourceKubernetesPersistentVolumeClaimDelete,
Importer: &schema.ResourceImporter{
State: func(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
d.Set("wait_until_bound", true)
return []*schema.ResourceData{d}, nil
},
},
Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(5 * time.Minute),
},
Schema: map[string]*schema.Schema{
"metadata": namespacedMetadataSchema("persistent volume claim", true),
"spec": {
Type: schema.TypeList,
Description: "Spec defines the desired characteristics of a volume requested by a pod author. More info: http://kubernetes.io/docs/user-guide/persistent-volumes#persistentvolumeclaims",
Required: true,
ForceNew: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"access_modes": {
Type: schema.TypeSet,
Description: "A set of the desired access modes the volume should have. More info: http://kubernetes.io/docs/user-guide/persistent-volumes#access-modes-1",
Required: true,
ForceNew: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},
"resources": {
Type: schema.TypeList,
Description: "A list of the minimum resources the volume should have. More info: http://kubernetes.io/docs/user-guide/persistent-volumes#resources",
Required: true,
ForceNew: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"limits": {
Type: schema.TypeMap,
Description: "Map describing the maximum amount of compute resources allowed. More info: http://kubernetes.io/docs/user-guide/compute-resources/",
Optional: true,
ForceNew: true,
},
"requests": {
Type: schema.TypeMap,
Description: "Map describing the minimum amount of compute resources required. If this is omitted for a container, it defaults to `limits` if that is explicitly specified, otherwise to an implementation-defined value. More info: http://kubernetes.io/docs/user-guide/compute-resources/",
Optional: true,
ForceNew: true,
},
},
},
},
"selector": {
Type: schema.TypeList,
Description: "A label query over volumes to consider for binding.",
Optional: true,
ForceNew: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"match_expressions": {
Type: schema.TypeList,
Description: "A list of label selector requirements. The requirements are ANDed.",
Optional: true,
ForceNew: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"key": {
Type: schema.TypeString,
Description: "The label key that the selector applies to.",
Optional: true,
ForceNew: true,
},
"operator": {
Type: schema.TypeString,
Description: "A key's relationship to a set of values. Valid operators ard `In`, `NotIn`, `Exists` and `DoesNotExist`.",
Optional: true,
ForceNew: true,
},
"values": {
Type: schema.TypeSet,
Description: "An array of string values. If the operator is `In` or `NotIn`, the values array must be non-empty. If the operator is `Exists` or `DoesNotExist`, the values array must be empty. This array is replaced during a strategic merge patch.",
Optional: true,
ForceNew: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},
},
},
},
"match_labels": {
Type: schema.TypeMap,
Description: "A map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of `match_expressions`, whose key field is \"key\", the operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.",
Optional: true,
ForceNew: true,
},
},
},
},
"volume_name": {
Type: schema.TypeString,
Description: "The binding reference to the PersistentVolume backing this claim.",
Optional: true,
ForceNew: true,
Computed: true,
},
},
},
},
"wait_until_bound": {
Type: schema.TypeBool,
Description: "Whether to wait for the claim to reach `Bound` state (to find volume in which to claim the space)",
Optional: true,
Default: true,
},
},
}
}
func resourceKubernetesPersistentVolumeClaimCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*kubernetes.Clientset)
metadata := expandMetadata(d.Get("metadata").([]interface{}))
spec, err := expandPersistentVolumeClaimSpec(d.Get("spec").([]interface{}))
if err != nil {
return err
}
claim := api.PersistentVolumeClaim{
ObjectMeta: metadata,
Spec: spec,
}
log.Printf("[INFO] Creating new persistent volume claim: %#v", claim)
out, err := conn.CoreV1().PersistentVolumeClaims(metadata.Namespace).Create(&claim)
if err != nil {
return err
}
log.Printf("[INFO] Submitted new persistent volume claim: %#v", out)
d.SetId(buildId(out.ObjectMeta))
name := out.ObjectMeta.Name
if d.Get("wait_until_bound").(bool) {
stateConf := &resource.StateChangeConf{
Target: []string{"Bound"},
Pending: []string{"Pending"},
Timeout: d.Timeout(schema.TimeoutCreate),
Refresh: func() (interface{}, string, error) {
out, err := conn.CoreV1().PersistentVolumeClaims(metadata.Namespace).Get(name)
if err != nil {
log.Printf("[ERROR] Received error: %#v", err)
return out, "", err
}
statusPhase := fmt.Sprintf("%v", out.Status.Phase)
log.Printf("[DEBUG] Persistent volume claim %s status received: %#v", out.Name, statusPhase)
return out, statusPhase, nil
},
}
_, err = stateConf.WaitForState()
if err != nil {
return err
}
}
log.Printf("[INFO] Persistent volume claim %s created", out.Name)
return resourceKubernetesPersistentVolumeClaimRead(d, meta)
}
func resourceKubernetesPersistentVolumeClaimRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*kubernetes.Clientset)
namespace, name := idParts(d.Id())
log.Printf("[INFO] Reading persistent volume claim %s", name)
claim, err := conn.CoreV1().PersistentVolumeClaims(namespace).Get(name)
if err != nil {
log.Printf("[DEBUG] Received error: %#v", err)
return err
}
log.Printf("[INFO] Received persistent volume claim: %#v", claim)
err = d.Set("metadata", flattenMetadata(claim.ObjectMeta))
if err != nil {
return err
}
err = d.Set("spec", flattenPersistentVolumeClaimSpec(claim.Spec))
if err != nil {
return err
}
return nil
}
func resourceKubernetesPersistentVolumeClaimUpdate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*kubernetes.Clientset)
namespace, name := idParts(d.Id())
ops := patchMetadata("metadata.0.", "/metadata/", d)
// The whole spec is ForceNew = nothing to update there
data, err := ops.MarshalJSON()
if err != nil {
return fmt.Errorf("Failed to marshal update operations: %s", err)
}
log.Printf("[INFO] Updating persistent volume claim: %s", ops)
out, err := conn.CoreV1().PersistentVolumeClaims(namespace).Patch(name, pkgApi.JSONPatchType, data)
if err != nil {
return err
}
log.Printf("[INFO] Submitted updated persistent volume claim: %#v", out)
return resourceKubernetesPersistentVolumeClaimRead(d, meta)
}
func resourceKubernetesPersistentVolumeClaimDelete(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*kubernetes.Clientset)
namespace, name := idParts(d.Id())
log.Printf("[INFO] Deleting persistent volume claim: %#v", name)
err := conn.CoreV1().PersistentVolumeClaims(namespace).Delete(name, &api.DeleteOptions{})
if err != nil {
return err
}
log.Printf("[INFO] Persistent volume claim %s deleted", name)
d.SetId("")
return nil
}
func resourceKubernetesPersistentVolumeClaimExists(d *schema.ResourceData, meta interface{}) (bool, error) {
conn := meta.(*kubernetes.Clientset)
namespace, name := idParts(d.Id())
log.Printf("[INFO] Checking persistent volume claim %s", name)
_, err := conn.CoreV1().PersistentVolumeClaims(namespace).Get(name)
if err != nil {
if statusErr, ok := err.(*errors.StatusError); ok && statusErr.ErrStatus.Code == 404 {
return false, nil
}
log.Printf("[DEBUG] Received error: %#v", err)
}
return true, err
}

View File

@ -0,0 +1,667 @@
package kubernetes
import (
"fmt"
"testing"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
api "k8s.io/kubernetes/pkg/api/v1"
kubernetes "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5"
)
func TestAccKubernetesPersistentVolumeClaim_basic(t *testing.T) {
var conf api.PersistentVolumeClaim
name := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(10))
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
IDRefreshName: "kubernetes_persistent_volume_claim.test",
Providers: testAccProviders,
CheckDestroy: testAccCheckKubernetesPersistentVolumeClaimDestroy,
Steps: []resource.TestStep{
{
Config: testAccKubernetesPersistentVolumeClaimConfig_basic(name),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckKubernetesPersistentVolumeClaimExists("kubernetes_persistent_volume_claim.test", &conf),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "metadata.0.annotations.%", "1"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "metadata.0.annotations.TestAnnotationOne", "one"),
testAccCheckMetaAnnotations(&conf.ObjectMeta, map[string]string{"TestAnnotationOne": "one"}),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "metadata.0.labels.%", "3"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "metadata.0.labels.TestLabelOne", "one"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "metadata.0.labels.TestLabelThree", "three"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "metadata.0.labels.TestLabelFour", "four"),
testAccCheckMetaLabels(&conf.ObjectMeta, map[string]string{"TestLabelOne": "one", "TestLabelThree": "three", "TestLabelFour": "four"}),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "metadata.0.name", name),
resource.TestCheckResourceAttrSet("kubernetes_persistent_volume_claim.test", "metadata.0.generation"),
resource.TestCheckResourceAttrSet("kubernetes_persistent_volume_claim.test", "metadata.0.resource_version"),
resource.TestCheckResourceAttrSet("kubernetes_persistent_volume_claim.test", "metadata.0.self_link"),
resource.TestCheckResourceAttrSet("kubernetes_persistent_volume_claim.test", "metadata.0.uid"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.access_modes.#", "1"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.access_modes.1254135962", "ReadWriteMany"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.resources.#", "1"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.resources.0.requests.%", "1"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.resources.0.requests.storage", "5Gi"),
),
},
{
Config: testAccKubernetesPersistentVolumeClaimConfig_metaModified(name),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckKubernetesPersistentVolumeClaimExists("kubernetes_persistent_volume_claim.test", &conf),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "metadata.0.annotations.%", "2"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "metadata.0.annotations.TestAnnotationOne", "one"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "metadata.0.annotations.TestAnnotationTwo", "two"),
testAccCheckMetaAnnotations(&conf.ObjectMeta, map[string]string{"TestAnnotationOne": "one", "TestAnnotationTwo": "two"}),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "metadata.0.labels.%", "3"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "metadata.0.labels.TestLabelOne", "one"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "metadata.0.labels.TestLabelTwo", "two"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "metadata.0.labels.TestLabelThree", "three"),
testAccCheckMetaLabels(&conf.ObjectMeta, map[string]string{"TestLabelOne": "one", "TestLabelTwo": "two", "TestLabelThree": "three"}),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "metadata.0.name", name),
resource.TestCheckResourceAttrSet("kubernetes_persistent_volume_claim.test", "metadata.0.generation"),
resource.TestCheckResourceAttrSet("kubernetes_persistent_volume_claim.test", "metadata.0.resource_version"),
resource.TestCheckResourceAttrSet("kubernetes_persistent_volume_claim.test", "metadata.0.self_link"),
resource.TestCheckResourceAttrSet("kubernetes_persistent_volume_claim.test", "metadata.0.uid"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.access_modes.#", "1"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.access_modes.1254135962", "ReadWriteMany"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.resources.#", "1"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.resources.0.requests.%", "1"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.resources.0.requests.storage", "5Gi"),
),
},
},
})
}
func TestAccKubernetesPersistentVolumeClaim_importBasic(t *testing.T) {
resourceName := "kubernetes_persistent_volume_claim.test"
volumeName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(10))
claimName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(10))
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckKubernetesPersistentVolumeClaimDestroy,
Steps: []resource.TestStep{
{
Config: testAccKubernetesPersistentVolumeClaimConfig_import(volumeName, claimName),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}
func TestAccKubernetesPersistentVolumeClaim_volumeMatch(t *testing.T) {
var pvcConf api.PersistentVolumeClaim
var pvConf api.PersistentVolume
claimName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(10))
volumeName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(10))
volumeNameModified := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(10))
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
IDRefreshName: "kubernetes_persistent_volume_claim.test",
Providers: testAccProviders,
CheckDestroy: testAccCheckKubernetesPersistentVolumeClaimDestroy,
Steps: []resource.TestStep{
{
Config: testAccKubernetesPersistentVolumeClaimConfig_volumeMatch(volumeName, claimName),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckKubernetesPersistentVolumeClaimExists("kubernetes_persistent_volume_claim.test", &pvcConf),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "metadata.0.annotations.%", "0"),
testAccCheckMetaAnnotations(&pvcConf.ObjectMeta, map[string]string{"pv.kubernetes.io/bind-completed": "yes"}),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "metadata.0.labels.%", "0"),
testAccCheckMetaLabels(&pvcConf.ObjectMeta, map[string]string{}),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "metadata.0.name", claimName),
resource.TestCheckResourceAttrSet("kubernetes_persistent_volume_claim.test", "metadata.0.generation"),
resource.TestCheckResourceAttrSet("kubernetes_persistent_volume_claim.test", "metadata.0.resource_version"),
resource.TestCheckResourceAttrSet("kubernetes_persistent_volume_claim.test", "metadata.0.self_link"),
resource.TestCheckResourceAttrSet("kubernetes_persistent_volume_claim.test", "metadata.0.uid"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.access_modes.#", "1"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.access_modes.1254135962", "ReadWriteMany"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.resources.#", "1"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.resources.0.requests.%", "1"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.resources.0.requests.storage", "5Gi"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.volume_name", volumeName),
testAccCheckKubernetesPersistentVolumeExists("kubernetes_persistent_volume.test", &pvConf),
testAccCheckMetaAnnotations(&pvConf.ObjectMeta, map[string]string{"pv.kubernetes.io/bound-by-controller": "yes"}),
),
},
{
Config: testAccKubernetesPersistentVolumeClaimConfig_volumeMatch_modified(volumeNameModified, claimName),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckKubernetesPersistentVolumeClaimExists("kubernetes_persistent_volume_claim.test", &pvcConf),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "metadata.0.annotations.%", "0"),
testAccCheckMetaAnnotations(&pvcConf.ObjectMeta, map[string]string{"pv.kubernetes.io/bind-completed": "yes"}),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "metadata.0.labels.%", "0"),
testAccCheckMetaLabels(&pvcConf.ObjectMeta, map[string]string{}),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "metadata.0.name", claimName),
resource.TestCheckResourceAttrSet("kubernetes_persistent_volume_claim.test", "metadata.0.generation"),
resource.TestCheckResourceAttrSet("kubernetes_persistent_volume_claim.test", "metadata.0.resource_version"),
resource.TestCheckResourceAttrSet("kubernetes_persistent_volume_claim.test", "metadata.0.self_link"),
resource.TestCheckResourceAttrSet("kubernetes_persistent_volume_claim.test", "metadata.0.uid"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.access_modes.#", "1"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.access_modes.1254135962", "ReadWriteMany"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.resources.#", "1"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.resources.0.requests.%", "1"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.resources.0.requests.storage", "5Gi"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.volume_name", volumeNameModified),
testAccCheckKubernetesPersistentVolumeExists("kubernetes_persistent_volume.test2", &pvConf),
testAccCheckMetaAnnotations(&pvConf.ObjectMeta, map[string]string{"pv.kubernetes.io/bound-by-controller": "yes"}),
),
},
},
})
}
func TestAccKubernetesPersistentVolumeClaim_labelsMatch(t *testing.T) {
var conf api.PersistentVolumeClaim
claimName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(10))
volumeName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(10))
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
IDRefreshName: "kubernetes_persistent_volume_claim.test",
Providers: testAccProviders,
CheckDestroy: testAccCheckKubernetesPersistentVolumeClaimDestroy,
Steps: []resource.TestStep{
{
Config: testAccKubernetesPersistentVolumeClaimConfig_labelsMatch(volumeName, claimName),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckKubernetesPersistentVolumeClaimExists("kubernetes_persistent_volume_claim.test", &conf),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "metadata.0.annotations.%", "0"),
testAccCheckMetaAnnotations(&conf.ObjectMeta, map[string]string{"pv.kubernetes.io/bind-completed": "yes", "pv.kubernetes.io/bound-by-controller": "yes"}),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "metadata.0.labels.%", "0"),
testAccCheckMetaLabels(&conf.ObjectMeta, map[string]string{}),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "metadata.0.name", claimName),
resource.TestCheckResourceAttrSet("kubernetes_persistent_volume_claim.test", "metadata.0.generation"),
resource.TestCheckResourceAttrSet("kubernetes_persistent_volume_claim.test", "metadata.0.resource_version"),
resource.TestCheckResourceAttrSet("kubernetes_persistent_volume_claim.test", "metadata.0.self_link"),
resource.TestCheckResourceAttrSet("kubernetes_persistent_volume_claim.test", "metadata.0.uid"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.access_modes.#", "1"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.access_modes.1254135962", "ReadWriteMany"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.resources.#", "1"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.resources.0.requests.%", "1"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.resources.0.requests.storage", "5Gi"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.selector.#", "1"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.selector.0.match_labels.%", "1"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.selector.0.match_labels.TfAccTestEnvironment", "blablah"),
),
},
},
})
}
func TestAccKubernetesPersistentVolumeClaim_labelsMatchExpression(t *testing.T) {
var conf api.PersistentVolumeClaim
claimName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(10))
volumeName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(10))
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
IDRefreshName: "kubernetes_persistent_volume_claim.test",
Providers: testAccProviders,
CheckDestroy: testAccCheckKubernetesPersistentVolumeClaimDestroy,
Steps: []resource.TestStep{
{
Config: testAccKubernetesPersistentVolumeClaimConfig_labelsMatchExpression(volumeName, claimName),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckKubernetesPersistentVolumeClaimExists("kubernetes_persistent_volume_claim.test", &conf),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "metadata.0.annotations.%", "0"),
testAccCheckMetaAnnotations(&conf.ObjectMeta, map[string]string{"pv.kubernetes.io/bind-completed": "yes", "pv.kubernetes.io/bound-by-controller": "yes"}),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "metadata.0.labels.%", "0"),
testAccCheckMetaLabels(&conf.ObjectMeta, map[string]string{}),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "metadata.0.name", claimName),
resource.TestCheckResourceAttrSet("kubernetes_persistent_volume_claim.test", "metadata.0.generation"),
resource.TestCheckResourceAttrSet("kubernetes_persistent_volume_claim.test", "metadata.0.resource_version"),
resource.TestCheckResourceAttrSet("kubernetes_persistent_volume_claim.test", "metadata.0.self_link"),
resource.TestCheckResourceAttrSet("kubernetes_persistent_volume_claim.test", "metadata.0.uid"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.access_modes.#", "1"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.access_modes.1254135962", "ReadWriteMany"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.resources.#", "1"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.resources.0.requests.%", "1"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.resources.0.requests.storage", "5Gi"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.selector.#", "1"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.selector.0.match_expressions.#", "1"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.selector.0.match_expressions.0.key", "TfAccTestEnvironment"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.selector.0.match_expressions.0.operator", "In"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.selector.0.match_expressions.0.values.#", "3"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.selector.0.match_expressions.0.values.1187371253", "three"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.selector.0.match_expressions.0.values.2053932785", "one"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.selector.0.match_expressions.0.values.298486374", "two"),
),
},
},
})
}
func TestAccKubernetesPersistentVolumeClaim_volumeUpdate(t *testing.T) {
var pvcConf api.PersistentVolumeClaim
var pvConf api.PersistentVolume
claimName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(10))
volumeName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(10))
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
IDRefreshName: "kubernetes_persistent_volume_claim.test",
Providers: testAccProviders,
CheckDestroy: testAccCheckKubernetesPersistentVolumeClaimDestroy,
Steps: []resource.TestStep{
{
Config: testAccKubernetesPersistentVolumeClaimConfig_volumeUpdate(volumeName, claimName, "5Gi"),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckKubernetesPersistentVolumeClaimExists("kubernetes_persistent_volume_claim.test", &pvcConf),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "metadata.0.annotations.%", "0"),
testAccCheckMetaAnnotations(&pvcConf.ObjectMeta, map[string]string{"pv.kubernetes.io/bind-completed": "yes"}),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "metadata.0.labels.%", "0"),
testAccCheckMetaLabels(&pvcConf.ObjectMeta, map[string]string{}),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "metadata.0.name", claimName),
resource.TestCheckResourceAttrSet("kubernetes_persistent_volume_claim.test", "metadata.0.generation"),
resource.TestCheckResourceAttrSet("kubernetes_persistent_volume_claim.test", "metadata.0.resource_version"),
resource.TestCheckResourceAttrSet("kubernetes_persistent_volume_claim.test", "metadata.0.self_link"),
resource.TestCheckResourceAttrSet("kubernetes_persistent_volume_claim.test", "metadata.0.uid"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.access_modes.#", "1"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.access_modes.1254135962", "ReadWriteMany"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.resources.#", "1"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.resources.0.requests.%", "1"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.resources.0.requests.storage", "5Gi"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.volume_name", volumeName),
testAccCheckKubernetesPersistentVolumeExists("kubernetes_persistent_volume.test", &pvConf),
testAccCheckMetaAnnotations(&pvConf.ObjectMeta, map[string]string{"pv.kubernetes.io/bound-by-controller": "yes"}),
testAccCheckClaimRef(&pvConf, &ObjectRefStatic{Namespace: "default", Name: claimName}),
),
},
{
Config: testAccKubernetesPersistentVolumeClaimConfig_volumeUpdate(volumeName, claimName, "10Gi"),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckKubernetesPersistentVolumeClaimExists("kubernetes_persistent_volume_claim.test", &pvcConf),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "metadata.0.annotations.%", "0"),
testAccCheckMetaAnnotations(&pvcConf.ObjectMeta, map[string]string{"pv.kubernetes.io/bind-completed": "yes"}),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "metadata.0.labels.%", "0"),
testAccCheckMetaLabels(&pvcConf.ObjectMeta, map[string]string{}),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "metadata.0.name", claimName),
resource.TestCheckResourceAttrSet("kubernetes_persistent_volume_claim.test", "metadata.0.generation"),
resource.TestCheckResourceAttrSet("kubernetes_persistent_volume_claim.test", "metadata.0.resource_version"),
resource.TestCheckResourceAttrSet("kubernetes_persistent_volume_claim.test", "metadata.0.self_link"),
resource.TestCheckResourceAttrSet("kubernetes_persistent_volume_claim.test", "metadata.0.uid"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.access_modes.#", "1"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.access_modes.1254135962", "ReadWriteMany"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.resources.#", "1"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.resources.0.requests.%", "1"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.resources.0.requests.storage", "5Gi"),
resource.TestCheckResourceAttr("kubernetes_persistent_volume_claim.test", "spec.0.volume_name", volumeName),
testAccCheckKubernetesPersistentVolumeExists("kubernetes_persistent_volume.test", &pvConf),
testAccCheckMetaAnnotations(&pvConf.ObjectMeta, map[string]string{"pv.kubernetes.io/bound-by-controller": "yes"}),
testAccCheckClaimRef(&pvConf, &ObjectRefStatic{Namespace: "default", Name: claimName}),
),
},
},
})
}
func testAccCheckKubernetesPersistentVolumeClaimDestroy(s *terraform.State) error {
conn := testAccProvider.Meta().(*kubernetes.Clientset)
for _, rs := range s.RootModule().Resources {
if rs.Type != "kubernetes_persistent_volume_claim" {
continue
}
namespace, name := idParts(rs.Primary.ID)
resp, err := conn.CoreV1().PersistentVolumeClaims(namespace).Get(name)
if err == nil {
if resp.Namespace == namespace && resp.Name == name {
return fmt.Errorf("Persistent Volume still exists: %s", rs.Primary.ID)
}
}
}
return nil
}
func testAccCheckKubernetesPersistentVolumeClaimExists(n string, obj *api.PersistentVolumeClaim) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", n)
}
conn := testAccProvider.Meta().(*kubernetes.Clientset)
namespace, name := idParts(rs.Primary.ID)
out, err := conn.CoreV1().PersistentVolumeClaims(namespace).Get(name)
if err != nil {
return err
}
*obj = *out
return nil
}
}
func testAccCheckClaimRef(pv *api.PersistentVolume, expected *ObjectRefStatic) resource.TestCheckFunc {
return func(s *terraform.State) error {
or := pv.Spec.ClaimRef
if or == nil {
return fmt.Errorf("Expected ClaimRef to be not-nil, specifically %#v", *expected)
}
if or.Namespace != expected.Namespace {
return fmt.Errorf("Expected object reference %q, given: %q", expected.Namespace, or.Namespace)
}
if or.Name != expected.Name {
return fmt.Errorf("Expected object reference %q, given: %q", expected.Name, or.Name)
}
return nil
}
}
type ObjectRefStatic struct {
Namespace string
Name string
}
func testAccKubernetesPersistentVolumeClaimConfig_basic(name string) string {
return fmt.Sprintf(`
resource "kubernetes_persistent_volume_claim" "test" {
metadata {
annotations {
TestAnnotationOne = "one"
}
labels {
TestLabelOne = "one"
TestLabelThree = "three"
TestLabelFour = "four"
}
name = "%s"
}
spec {
access_modes = ["ReadWriteMany"]
resources {
requests {
storage = "5Gi"
}
}
selector {
match_expressions {
key = "environment"
operator = "In"
values = ["non-exists-12345"]
}
}
}
wait_until_bound = false
}
`, name)
}
func testAccKubernetesPersistentVolumeClaimConfig_metaModified(name string) string {
return fmt.Sprintf(`
resource "kubernetes_persistent_volume_claim" "test" {
metadata {
annotations {
TestAnnotationOne = "one"
TestAnnotationTwo = "two"
}
labels {
TestLabelOne = "one"
TestLabelTwo = "two"
TestLabelThree = "three"
}
name = "%s"
}
spec {
access_modes = ["ReadWriteMany"]
resources {
requests {
storage = "5Gi"
}
}
selector {
match_expressions {
key = "environment"
operator = "In"
values = ["non-exists-12345"]
}
}
}
wait_until_bound = false
}
`, name)
}
func testAccKubernetesPersistentVolumeClaimConfig_import(volumeName, claimName string) string {
return fmt.Sprintf(`
resource "kubernetes_persistent_volume" "test" {
metadata {
name = "%s"
}
spec {
capacity {
storage = "10Gi"
}
access_modes = ["ReadWriteMany"]
persistent_volume_source {
gce_persistent_disk {
pd_name = "test123"
}
}
}
}
resource "kubernetes_persistent_volume_claim" "test" {
metadata {
name = "%s"
}
spec {
access_modes = ["ReadWriteMany"]
resources {
requests {
storage = "5Gi"
}
}
volume_name = "${kubernetes_persistent_volume.test.metadata.0.name}"
}
}
`, volumeName, claimName)
}
func testAccKubernetesPersistentVolumeClaimConfig_volumeMatch(volumeName, claimName string) string {
return fmt.Sprintf(`
resource "kubernetes_persistent_volume" "test" {
metadata {
name = "%s"
}
spec {
capacity {
storage = "10Gi"
}
access_modes = ["ReadWriteMany"]
persistent_volume_source {
gce_persistent_disk {
pd_name = "test123"
}
}
}
}
resource "kubernetes_persistent_volume_claim" "test" {
metadata {
name = "%s"
}
spec {
access_modes = ["ReadWriteMany"]
resources {
requests {
storage = "5Gi"
}
}
volume_name = "${kubernetes_persistent_volume.test.metadata.0.name}"
}
}
`, volumeName, claimName)
}
func testAccKubernetesPersistentVolumeClaimConfig_volumeMatch_modified(volumeName, claimName string) string {
return fmt.Sprintf(`
resource "kubernetes_persistent_volume" "test2" {
metadata {
name = "%s"
}
spec {
capacity {
storage = "10Gi"
}
access_modes = ["ReadWriteMany"]
persistent_volume_source {
gce_persistent_disk {
pd_name = "test123"
}
}
}
}
resource "kubernetes_persistent_volume_claim" "test" {
metadata {
name = "%s"
}
spec {
access_modes = ["ReadWriteMany"]
resources {
requests {
storage = "5Gi"
}
}
volume_name = "${kubernetes_persistent_volume.test2.metadata.0.name}"
}
}
`, volumeName, claimName)
}
func testAccKubernetesPersistentVolumeClaimConfig_labelsMatch(volumeName, claimName string) string {
return fmt.Sprintf(`
resource "kubernetes_persistent_volume" "test" {
metadata {
labels {
TfAccTestEnvironment = "blablah"
}
name = "%s"
}
spec {
capacity {
storage = "10Gi"
}
access_modes = ["ReadWriteMany"]
persistent_volume_source {
gce_persistent_disk {
pd_name = "test123"
}
}
}
}
resource "kubernetes_persistent_volume_claim" "test" {
metadata {
name = "%s"
}
spec {
access_modes = ["ReadWriteMany"]
resources {
requests {
storage = "5Gi"
}
}
selector {
match_labels {
TfAccTestEnvironment = "blablah"
}
}
}
}
`, volumeName, claimName)
}
func testAccKubernetesPersistentVolumeClaimConfig_labelsMatchExpression(volumeName, claimName string) string {
return fmt.Sprintf(`
resource "kubernetes_persistent_volume" "test" {
metadata {
labels {
TfAccTestEnvironment = "two"
}
name = "%s"
}
spec {
capacity {
storage = "10Gi"
}
access_modes = ["ReadWriteMany"]
persistent_volume_source {
gce_persistent_disk {
pd_name = "test123"
}
}
}
}
resource "kubernetes_persistent_volume_claim" "test" {
metadata {
name = "%s"
}
spec {
access_modes = ["ReadWriteMany"]
resources {
requests {
storage = "5Gi"
}
}
selector {
match_expressions {
key = "TfAccTestEnvironment"
operator = "In"
values = ["one", "three", "two"]
}
}
}
}
`, volumeName, claimName)
}
func testAccKubernetesPersistentVolumeClaimConfig_volumeUpdate(volumeName, claimName, storage string) string {
return fmt.Sprintf(`
resource "kubernetes_persistent_volume" "test" {
metadata {
name = "%s"
}
spec {
capacity {
storage = "%s"
}
access_modes = ["ReadWriteMany"]
persistent_volume_source {
gce_persistent_disk {
pd_name = "test123"
}
}
}
}
resource "kubernetes_persistent_volume_claim" "test" {
metadata {
name = "%s"
}
spec {
access_modes = ["ReadWriteMany"]
resources {
requests {
storage = "5Gi"
}
}
volume_name = "${kubernetes_persistent_volume.test.metadata.0.name}"
}
}
`, volumeName, storage, claimName)
}

View File

@ -0,0 +1,134 @@
package kubernetes
import (
"github.com/hashicorp/terraform/helper/schema"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/v1"
)
// Flatteners
func flattenLabelSelector(in *unversioned.LabelSelector) []interface{} {
att := make(map[string]interface{})
if len(in.MatchLabels) > 0 {
att["match_labels"] = in.MatchLabels
}
if len(in.MatchExpressions) > 0 {
att["match_expressions"] = flattenLabelSelectorRequirement(in.MatchExpressions)
}
return []interface{}{att}
}
func flattenLabelSelectorRequirement(in []unversioned.LabelSelectorRequirement) []interface{} {
att := make([]interface{}, len(in), len(in))
for i, n := range in {
m := make(map[string]interface{})
m["key"] = n.Key
m["operator"] = n.Operator
m["values"] = newStringSet(schema.HashString, n.Values)
att[i] = m
}
return att
}
func flattenPersistentVolumeClaimSpec(in v1.PersistentVolumeClaimSpec) []interface{} {
att := make(map[string]interface{})
att["access_modes"] = flattenPersistentVolumeAccessModes(in.AccessModes)
att["resources"] = flattenResourceRequirements(in.Resources)
if in.Selector != nil {
att["selector"] = flattenLabelSelector(in.Selector)
}
if in.VolumeName != "" {
att["volume_name"] = in.VolumeName
}
return []interface{}{att}
}
func flattenResourceRequirements(in v1.ResourceRequirements) []interface{} {
att := make(map[string]interface{})
if len(in.Limits) > 0 {
att["limits"] = flattenResourceList(in.Limits)
}
if len(in.Requests) > 0 {
att["requests"] = flattenResourceList(in.Requests)
}
return []interface{}{att}
}
// Expanders
func expandLabelSelector(l []interface{}) *unversioned.LabelSelector {
if len(l) == 0 || l[0] == nil {
return &unversioned.LabelSelector{}
}
in := l[0].(map[string]interface{})
obj := &unversioned.LabelSelector{}
if v, ok := in["match_labels"].(map[string]interface{}); ok && len(v) > 0 {
obj.MatchLabels = expandStringMap(v)
}
if v, ok := in["match_expressions"].([]interface{}); ok && len(v) > 0 {
obj.MatchExpressions = expandLabelSelectorRequirement(v)
}
return obj
}
func expandLabelSelectorRequirement(l []interface{}) []unversioned.LabelSelectorRequirement {
if len(l) == 0 || l[0] == nil {
return []unversioned.LabelSelectorRequirement{}
}
obj := make([]unversioned.LabelSelectorRequirement, len(l), len(l))
for i, n := range l {
in := n.(map[string]interface{})
obj[i] = unversioned.LabelSelectorRequirement{
Key: in["key"].(string),
Operator: unversioned.LabelSelectorOperator(in["operator"].(string)),
Values: sliceOfString(in["values"].(*schema.Set).List()),
}
}
return obj
}
func expandPersistentVolumeClaimSpec(l []interface{}) (v1.PersistentVolumeClaimSpec, error) {
if len(l) == 0 || l[0] == nil {
return v1.PersistentVolumeClaimSpec{}, nil
}
in := l[0].(map[string]interface{})
resourceRequirements, err := expandResourceRequirements(in["resources"].([]interface{}))
if err != nil {
return v1.PersistentVolumeClaimSpec{}, err
}
obj := v1.PersistentVolumeClaimSpec{
AccessModes: expandPersistentVolumeAccessModes(in["access_modes"].(*schema.Set).List()),
Resources: resourceRequirements,
}
if v, ok := in["selector"].([]interface{}); ok && len(v) > 0 {
obj.Selector = expandLabelSelector(v)
}
if v, ok := in["volume_name"].(string); ok {
obj.VolumeName = v
}
return obj, nil
}
func expandResourceRequirements(l []interface{}) (v1.ResourceRequirements, error) {
if len(l) == 0 || l[0] == nil {
return v1.ResourceRequirements{}, nil
}
in := l[0].(map[string]interface{})
obj := v1.ResourceRequirements{}
if v, ok := in["limits"].(map[string]interface{}); ok && len(v) > 0 {
var err error
obj.Limits, err = expandMapToResourceList(v)
if err != nil {
return obj, err
}
}
if v, ok := in["requests"].(map[string]interface{}); ok && len(v) > 0 {
var err error
obj.Requests, err = expandMapToResourceList(v)
if err != nil {
return obj, err
}
}
return obj, nil
}

View File

@ -0,0 +1,114 @@
---
layout: "kubernetes"
page_title: "Kubernetes: kubernetes_persistent_volume_claim"
sidebar_current: "docs-kubernetes-resource-persistent-volume-claim"
description: |-
This resource allows the user to request for and claim to a persistent volume.
---
# kubernetes_persistent_volume_claim
This resource allows the user to request for and claim to a persistent volume.
## Example Usage
```hcl
resource "kubernetes_persistent_volume_claim" "example" {
metadata {
name = "exampleclaimname"
}
spec {
access_modes = ["ReadWriteMany"]
resources {
requests {
storage = "5Gi"
}
}
volume_name = "${kubernetes_persistent_volume.example.metadata.0.name}"
}
}
resource "kubernetes_persistent_volume" "example" {
metadata {
name = "examplevolumename"
}
spec {
capacity {
storage = "10Gi"
}
access_modes = ["ReadWriteMany"]
persistent_volume_source {
gce_persistent_disk {
pd_name = "test-123"
}
}
}
}
```
## Argument Reference
The following arguments are supported:
* `metadata` - (Required) Standard persistent volume claim's metadata. More info: https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata
* `spec` - (Required) Spec defines the desired characteristics of a volume requested by a pod author. More info: http://kubernetes.io/docs/user-guide/persistent-volumes#persistentvolumeclaims
* `wait_until_bound` - (Optional) Whether to wait for the claim to reach `Bound` state (to find volume in which to claim the space)
## Nested Blocks
### `metadata`
#### Arguments
* `annotations` - (Optional) An unstructured key value map stored with the persistent volume claim that may be used to store arbitrary metadata. More info: http://kubernetes.io/docs/user-guide/annotations
* `generate_name` - (Optional) Prefix, used by the server, to generate a unique name ONLY IF the `name` field has not been provided. This value will also be combined with a unique suffix. Read more: https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#idempotency
* `labels` - (Optional) Map of string keys and values that can be used to organize and categorize (scope and select) the persistent volume claim. May match selectors of replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels
* `name` - (Optional) Name of the persistent volume claim, must be unique. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names
* `namespace` - (Optional) Namespace defines the space within which name of the persistent volume claim must be unique.
#### Attributes
* `generation` - A sequence number representing a specific generation of the desired state.
* `resource_version` - An opaque value that represents the internal version of this persistent volume claim that can be used by clients to determine when persistent volume claim has changed. Read more: https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#concurrency-control-and-consistency
* `self_link` - A URL representing this persistent volume claim.
* `uid` - The unique in time and space value for this persistent volume claim. More info: http://kubernetes.io/docs/user-guide/identifiers#uids
### `spec`
#### Arguments
* `access_modes` - (Required) A set of the desired access modes the volume should have. More info: http://kubernetes.io/docs/user-guide/persistent-volumes#access-modes-1
* `resources` - (Required) A list of the minimum resources the volume should have. More info: http://kubernetes.io/docs/user-guide/persistent-volumes#resources
* `selector` - (Optional) A label query over volumes to consider for binding.
* `volume_name` - (Optional) The binding reference to the PersistentVolume backing this claim.
### `match_expressions`
#### Arguments
* `key` - (Optional) The label key that the selector applies to.
* `operator` - (Optional) A key's relationship to a set of values. Valid operators ard `In`, `NotIn`, `Exists` and `DoesNotExist`.
* `values` - (Optional) An array of string values. If the operator is `In` or `NotIn`, the values array must be non-empty. If the operator is `Exists` or `DoesNotExist`, the values array must be empty. This array is replaced during a strategic merge patch.
### `resources`
#### Arguments
* `limits` - (Optional) Map describing the maximum amount of compute resources allowed. More info: http://kubernetes.io/docs/user-guide/compute-resources/
* `requests` - (Optional) Map describing the minimum amount of compute resources required. If this is omitted for a container, it defaults to `limits` if that is explicitly specified, otherwise to an implementation-defined value. More info: http://kubernetes.io/docs/user-guide/compute-resources/
### `selector`
#### Arguments
* `match_expressions` - (Optional) A list of label selector requirements. The requirements are ANDed.
* `match_labels` - (Optional) A map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of `match_expressions`, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
## Import
Persistent Volume Claim can be imported using its name, e.g.
```
$ terraform import kubernetes_persistent_volume_claim.example example-name
```

View File

@ -22,6 +22,9 @@
<li<%= sidebar_current("docs-kubernetes-resource-persistent-volume") %>>
<a href="/docs/providers/kubernetes/r/persistent_volume.html">kubernetes_persistent_volume</a>
</li>
<li<%= sidebar_current("docs-kubernetes-resource-persistent-volume-claim") %>>
<a href="/docs/providers/kubernetes/r/persistent_volume_claim.html">kubernetes_persistent_volume_claim</a>
</li>
<li<%= sidebar_current("docs-kubernetes-resource-secret") %>>
<a href="/docs/providers/kubernetes/r/secret.html">kubernetes_secret</a>
</li>