github.com/koding/terraform@v0.6.4-0.20170608090606-5d7e0339779d/builtin/providers/kubernetes/resource_kubernetes_persistent_volume.go (about) 1 package kubernetes 2 3 import ( 4 "fmt" 5 "log" 6 "time" 7 8 "github.com/hashicorp/terraform/helper/resource" 9 "github.com/hashicorp/terraform/helper/schema" 10 "k8s.io/apimachinery/pkg/api/errors" 11 meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 12 pkgApi "k8s.io/apimachinery/pkg/types" 13 api "k8s.io/kubernetes/pkg/api/v1" 14 kubernetes "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" 15 ) 16 17 func resourceKubernetesPersistentVolume() *schema.Resource { 18 return &schema.Resource{ 19 Create: resourceKubernetesPersistentVolumeCreate, 20 Read: resourceKubernetesPersistentVolumeRead, 21 Exists: resourceKubernetesPersistentVolumeExists, 22 Update: resourceKubernetesPersistentVolumeUpdate, 23 Delete: resourceKubernetesPersistentVolumeDelete, 24 Importer: &schema.ResourceImporter{ 25 State: schema.ImportStatePassthrough, 26 }, 27 28 Schema: map[string]*schema.Schema{ 29 "metadata": metadataSchema("persistent volume", false), 30 "spec": { 31 Type: schema.TypeList, 32 Description: "Spec of the persistent volume owned by the cluster", 33 Required: true, 34 Elem: &schema.Resource{ 35 Schema: map[string]*schema.Schema{ 36 "access_modes": { 37 Type: schema.TypeSet, 38 Description: "Contains all ways the volume can be mounted. More info: http://kubernetes.io/docs/user-guide/persistent-volumes#access-modes", 39 Required: true, 40 Elem: &schema.Schema{Type: schema.TypeString}, 41 Set: schema.HashString, 42 }, 43 "capacity": { 44 Type: schema.TypeMap, 45 Description: "A description of the persistent volume's resources and capacity. More info: http://kubernetes.io/docs/user-guide/persistent-volumes#capacity", 46 Required: true, 47 Elem: schema.TypeString, 48 ValidateFunc: validateResourceList, 49 }, 50 "persistent_volume_reclaim_policy": { 51 Type: schema.TypeString, 52 Description: "What happens to a persistent volume when released from its claim. Valid options are Retain (default) and Recycle. Recycling must be supported by the volume plugin underlying this persistent volume. More info: http://kubernetes.io/docs/user-guide/persistent-volumes#recycling-policy", 53 Optional: true, 54 Default: "Retain", 55 }, 56 "persistent_volume_source": { 57 Type: schema.TypeList, 58 Description: "The specification of a persistent volume.", 59 Required: true, 60 MaxItems: 1, 61 Elem: persistentVolumeSourceSchema(), 62 }, 63 }, 64 }, 65 }, 66 }, 67 } 68 } 69 70 func resourceKubernetesPersistentVolumeCreate(d *schema.ResourceData, meta interface{}) error { 71 conn := meta.(*kubernetes.Clientset) 72 73 metadata := expandMetadata(d.Get("metadata").([]interface{})) 74 spec, err := expandPersistentVolumeSpec(d.Get("spec").([]interface{})) 75 if err != nil { 76 return err 77 } 78 volume := api.PersistentVolume{ 79 ObjectMeta: metadata, 80 Spec: spec, 81 } 82 83 log.Printf("[INFO] Creating new persistent volume: %#v", volume) 84 out, err := conn.CoreV1().PersistentVolumes().Create(&volume) 85 if err != nil { 86 return err 87 } 88 log.Printf("[INFO] Submitted new persistent volume: %#v", out) 89 90 stateConf := &resource.StateChangeConf{ 91 Target: []string{"Available", "Bound"}, 92 Pending: []string{"Pending"}, 93 Timeout: 5 * time.Minute, 94 Refresh: func() (interface{}, string, error) { 95 out, err := conn.CoreV1().PersistentVolumes().Get(metadata.Name, meta_v1.GetOptions{}) 96 if err != nil { 97 log.Printf("[ERROR] Received error: %#v", err) 98 return out, "Error", err 99 } 100 101 statusPhase := fmt.Sprintf("%v", out.Status.Phase) 102 log.Printf("[DEBUG] Persistent volume %s status received: %#v", out.Name, statusPhase) 103 return out, statusPhase, nil 104 }, 105 } 106 _, err = stateConf.WaitForState() 107 if err != nil { 108 return err 109 } 110 log.Printf("[INFO] Persistent volume %s created", out.Name) 111 112 d.SetId(out.Name) 113 114 return resourceKubernetesPersistentVolumeRead(d, meta) 115 } 116 117 func resourceKubernetesPersistentVolumeRead(d *schema.ResourceData, meta interface{}) error { 118 conn := meta.(*kubernetes.Clientset) 119 120 name := d.Id() 121 log.Printf("[INFO] Reading persistent volume %s", name) 122 volume, err := conn.CoreV1().PersistentVolumes().Get(name, meta_v1.GetOptions{}) 123 if err != nil { 124 log.Printf("[DEBUG] Received error: %#v", err) 125 return err 126 } 127 log.Printf("[INFO] Received persistent volume: %#v", volume) 128 err = d.Set("metadata", flattenMetadata(volume.ObjectMeta)) 129 if err != nil { 130 return err 131 } 132 err = d.Set("spec", flattenPersistentVolumeSpec(volume.Spec)) 133 if err != nil { 134 return err 135 } 136 137 return nil 138 } 139 140 func resourceKubernetesPersistentVolumeUpdate(d *schema.ResourceData, meta interface{}) error { 141 conn := meta.(*kubernetes.Clientset) 142 143 ops := patchMetadata("metadata.0.", "/metadata/", d) 144 if d.HasChange("spec") { 145 specOps, err := patchPersistentVolumeSpec("/spec", "spec", d) 146 if err != nil { 147 return err 148 } 149 ops = append(ops, specOps...) 150 } 151 data, err := ops.MarshalJSON() 152 if err != nil { 153 return fmt.Errorf("Failed to marshal update operations: %s", err) 154 } 155 156 log.Printf("[INFO] Updating persistent volume %s: %s", d.Id(), ops) 157 out, err := conn.CoreV1().PersistentVolumes().Patch(d.Id(), pkgApi.JSONPatchType, data) 158 if err != nil { 159 return err 160 } 161 log.Printf("[INFO] Submitted updated persistent volume: %#v", out) 162 d.SetId(out.Name) 163 164 return resourceKubernetesPersistentVolumeRead(d, meta) 165 } 166 167 func resourceKubernetesPersistentVolumeDelete(d *schema.ResourceData, meta interface{}) error { 168 conn := meta.(*kubernetes.Clientset) 169 170 name := d.Id() 171 log.Printf("[INFO] Deleting persistent volume: %#v", name) 172 err := conn.CoreV1().PersistentVolumes().Delete(name, &meta_v1.DeleteOptions{}) 173 if err != nil { 174 return err 175 } 176 177 log.Printf("[INFO] Persistent volume %s deleted", name) 178 179 d.SetId("") 180 return nil 181 } 182 183 func resourceKubernetesPersistentVolumeExists(d *schema.ResourceData, meta interface{}) (bool, error) { 184 conn := meta.(*kubernetes.Clientset) 185 186 name := d.Id() 187 log.Printf("[INFO] Checking persistent volume %s", name) 188 _, err := conn.CoreV1().PersistentVolumes().Get(name, meta_v1.GetOptions{}) 189 if err != nil { 190 if statusErr, ok := err.(*errors.StatusError); ok && statusErr.ErrStatus.Code == 404 { 191 return false, nil 192 } 193 log.Printf("[DEBUG] Received error: %#v", err) 194 } 195 return true, err 196 }