github.com/koding/terraform@v0.6.4-0.20170608090606-5d7e0339779d/builtin/providers/kubernetes/resource_kubernetes_limit_range.go (about)

     1  package kubernetes
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  
     7  	"github.com/hashicorp/terraform/helper/schema"
     8  	"k8s.io/apimachinery/pkg/api/errors"
     9  	meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    10  	pkgApi "k8s.io/apimachinery/pkg/types"
    11  	api "k8s.io/kubernetes/pkg/api/v1"
    12  	kubernetes "k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
    13  )
    14  
    15  func resourceKubernetesLimitRange() *schema.Resource {
    16  	return &schema.Resource{
    17  		Create: resourceKubernetesLimitRangeCreate,
    18  		Read:   resourceKubernetesLimitRangeRead,
    19  		Exists: resourceKubernetesLimitRangeExists,
    20  		Update: resourceKubernetesLimitRangeUpdate,
    21  		Delete: resourceKubernetesLimitRangeDelete,
    22  		Importer: &schema.ResourceImporter{
    23  			State: schema.ImportStatePassthrough,
    24  		},
    25  
    26  		Schema: map[string]*schema.Schema{
    27  			"metadata": namespacedMetadataSchema("limit range", true),
    28  			"spec": {
    29  				Type:        schema.TypeList,
    30  				Description: "Spec defines the limits enforced. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status",
    31  				Optional:    true,
    32  				MaxItems:    1,
    33  				Elem: &schema.Resource{
    34  					Schema: map[string]*schema.Schema{
    35  						"limit": {
    36  							Type:        schema.TypeList,
    37  							Description: "Limits is the list of objects that are enforced.",
    38  							Optional:    true,
    39  							Elem: &schema.Resource{
    40  								Schema: map[string]*schema.Schema{
    41  									"default": {
    42  										Type:        schema.TypeMap,
    43  										Description: "Default resource requirement limit value by resource name if resource limit is omitted.",
    44  										Optional:    true,
    45  									},
    46  									"default_request": {
    47  										Type:        schema.TypeMap,
    48  										Description: "The default resource requirement request value by resource name if resource request is omitted.",
    49  										Optional:    true,
    50  										Computed:    true,
    51  									},
    52  									"max": {
    53  										Type:        schema.TypeMap,
    54  										Description: "Max usage constraints on this kind by resource name.",
    55  										Optional:    true,
    56  									},
    57  									"max_limit_request_ratio": {
    58  										Type:        schema.TypeMap,
    59  										Description: "The named resource must have a request and limit that are both non-zero where limit divided by request is less than or equal to the enumerated value; this represents the max burst for the named resource.",
    60  										Optional:    true,
    61  									},
    62  									"min": {
    63  										Type:        schema.TypeMap,
    64  										Description: "Min usage constraints on this kind by resource name.",
    65  										Optional:    true,
    66  									},
    67  									"type": {
    68  										Type:        schema.TypeString,
    69  										Description: "Type of resource that this limit applies to.",
    70  										Optional:    true,
    71  									},
    72  								},
    73  							},
    74  						},
    75  					},
    76  				},
    77  			},
    78  		},
    79  	}
    80  }
    81  
    82  func resourceKubernetesLimitRangeCreate(d *schema.ResourceData, meta interface{}) error {
    83  	conn := meta.(*kubernetes.Clientset)
    84  
    85  	metadata := expandMetadata(d.Get("metadata").([]interface{}))
    86  	spec, err := expandLimitRangeSpec(d.Get("spec").([]interface{}), d.IsNewResource())
    87  	if err != nil {
    88  		return err
    89  	}
    90  	limitRange := api.LimitRange{
    91  		ObjectMeta: metadata,
    92  		Spec:       spec,
    93  	}
    94  	log.Printf("[INFO] Creating new limit range: %#v", limitRange)
    95  	out, err := conn.CoreV1().LimitRanges(metadata.Namespace).Create(&limitRange)
    96  	if err != nil {
    97  		return fmt.Errorf("Failed to create limit range: %s", err)
    98  	}
    99  	log.Printf("[INFO] Submitted new limit range: %#v", out)
   100  	d.SetId(buildId(out.ObjectMeta))
   101  
   102  	return resourceKubernetesLimitRangeRead(d, meta)
   103  }
   104  
   105  func resourceKubernetesLimitRangeRead(d *schema.ResourceData, meta interface{}) error {
   106  	conn := meta.(*kubernetes.Clientset)
   107  
   108  	namespace, name := idParts(d.Id())
   109  	log.Printf("[INFO] Reading limit range %s", name)
   110  	limitRange, err := conn.CoreV1().LimitRanges(namespace).Get(name, meta_v1.GetOptions{})
   111  	if err != nil {
   112  		log.Printf("[DEBUG] Received error: %#v", err)
   113  		return err
   114  	}
   115  	log.Printf("[INFO] Received limit range: %#v", limitRange)
   116  
   117  	err = d.Set("metadata", flattenMetadata(limitRange.ObjectMeta))
   118  	if err != nil {
   119  		return err
   120  	}
   121  	err = d.Set("spec", flattenLimitRangeSpec(limitRange.Spec))
   122  	if err != nil {
   123  		return err
   124  	}
   125  
   126  	return nil
   127  }
   128  
   129  func resourceKubernetesLimitRangeUpdate(d *schema.ResourceData, meta interface{}) error {
   130  	conn := meta.(*kubernetes.Clientset)
   131  
   132  	namespace, name := idParts(d.Id())
   133  
   134  	ops := patchMetadata("metadata.0.", "/metadata/", d)
   135  	if d.HasChange("spec") {
   136  		spec, err := expandLimitRangeSpec(d.Get("spec").([]interface{}), d.IsNewResource())
   137  		if err != nil {
   138  			return err
   139  		}
   140  		ops = append(ops, &ReplaceOperation{
   141  			Path:  "/spec",
   142  			Value: spec,
   143  		})
   144  	}
   145  	data, err := ops.MarshalJSON()
   146  	if err != nil {
   147  		return fmt.Errorf("Failed to marshal update operations: %s", err)
   148  	}
   149  	log.Printf("[INFO] Updating limit range %q: %v", name, string(data))
   150  	out, err := conn.CoreV1().LimitRanges(namespace).Patch(name, pkgApi.JSONPatchType, data)
   151  	if err != nil {
   152  		return fmt.Errorf("Failed to update limit range: %s", err)
   153  	}
   154  	log.Printf("[INFO] Submitted updated limit range: %#v", out)
   155  	d.SetId(buildId(out.ObjectMeta))
   156  
   157  	return resourceKubernetesLimitRangeRead(d, meta)
   158  }
   159  
   160  func resourceKubernetesLimitRangeDelete(d *schema.ResourceData, meta interface{}) error {
   161  	conn := meta.(*kubernetes.Clientset)
   162  
   163  	namespace, name := idParts(d.Id())
   164  	log.Printf("[INFO] Deleting limit range: %#v", name)
   165  	err := conn.CoreV1().LimitRanges(namespace).Delete(name, &meta_v1.DeleteOptions{})
   166  	if err != nil {
   167  		return err
   168  	}
   169  
   170  	log.Printf("[INFO] Limit range %s deleted", name)
   171  
   172  	d.SetId("")
   173  	return nil
   174  }
   175  
   176  func resourceKubernetesLimitRangeExists(d *schema.ResourceData, meta interface{}) (bool, error) {
   177  	conn := meta.(*kubernetes.Clientset)
   178  
   179  	namespace, name := idParts(d.Id())
   180  	log.Printf("[INFO] Checking limit range %s", name)
   181  	_, err := conn.CoreV1().LimitRanges(namespace).Get(name, meta_v1.GetOptions{})
   182  	if err != nil {
   183  		if statusErr, ok := err.(*errors.StatusError); ok && statusErr.ErrStatus.Code == 404 {
   184  			return false, nil
   185  		}
   186  		log.Printf("[DEBUG] Received error: %#v", err)
   187  	}
   188  	return true, err
   189  }