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