github.com/koding/terraform@v0.6.4-0.20170608090606-5d7e0339779d/builtin/providers/kubernetes/resource_kubernetes_horizontal_pod_autoscaler.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/apis/autoscaling/v1"
    12  	kubernetes "k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
    13  )
    14  
    15  func resourceKubernetesHorizontalPodAutoscaler() *schema.Resource {
    16  	return &schema.Resource{
    17  		Create: resourceKubernetesHorizontalPodAutoscalerCreate,
    18  		Read:   resourceKubernetesHorizontalPodAutoscalerRead,
    19  		Exists: resourceKubernetesHorizontalPodAutoscalerExists,
    20  		Update: resourceKubernetesHorizontalPodAutoscalerUpdate,
    21  		Delete: resourceKubernetesHorizontalPodAutoscalerDelete,
    22  		Importer: &schema.ResourceImporter{
    23  			State: schema.ImportStatePassthrough,
    24  		},
    25  
    26  		Schema: map[string]*schema.Schema{
    27  			"metadata": namespacedMetadataSchema("horizontal pod autoscaler", true),
    28  			"spec": {
    29  				Type:        schema.TypeList,
    30  				Description: "Behaviour of the autoscaler. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status.",
    31  				Required:    true,
    32  				MaxItems:    1,
    33  				Elem: &schema.Resource{
    34  					Schema: map[string]*schema.Schema{
    35  						"max_replicas": {
    36  							Type:        schema.TypeInt,
    37  							Description: "Upper limit for the number of pods that can be set by the autoscaler.",
    38  							Required:    true,
    39  						},
    40  						"min_replicas": {
    41  							Type:        schema.TypeInt,
    42  							Description: "Lower limit for the number of pods that can be set by the autoscaler, defaults to `1`.",
    43  							Optional:    true,
    44  							Default:     1,
    45  						},
    46  						"scale_target_ref": {
    47  							Type:        schema.TypeList,
    48  							Description: "Reference to scaled resource. e.g. Replication Controller",
    49  							Required:    true,
    50  							MaxItems:    1,
    51  							Elem: &schema.Resource{
    52  								Schema: map[string]*schema.Schema{
    53  									"api_version": {
    54  										Type:        schema.TypeString,
    55  										Description: "API version of the referent",
    56  										Optional:    true,
    57  									},
    58  									"kind": {
    59  										Type:        schema.TypeString,
    60  										Description: "Kind of the referent. e.g. `ReplicationController`. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds",
    61  										Required:    true,
    62  									},
    63  									"name": {
    64  										Type:        schema.TypeString,
    65  										Description: "Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names",
    66  										Required:    true,
    67  									},
    68  								},
    69  							},
    70  						},
    71  						"target_cpu_utilization_percentage": {
    72  							Type:        schema.TypeInt,
    73  							Description: "Target average CPU utilization (represented as a percentage of requested CPU) over all the pods. If not specified the default autoscaling policy will be used.",
    74  							Optional:    true,
    75  							Computed:    true,
    76  						},
    77  					},
    78  				},
    79  			},
    80  		},
    81  	}
    82  }
    83  
    84  func resourceKubernetesHorizontalPodAutoscalerCreate(d *schema.ResourceData, meta interface{}) error {
    85  	conn := meta.(*kubernetes.Clientset)
    86  
    87  	metadata := expandMetadata(d.Get("metadata").([]interface{}))
    88  	svc := api.HorizontalPodAutoscaler{
    89  		ObjectMeta: metadata,
    90  		Spec:       expandHorizontalPodAutoscalerSpec(d.Get("spec").([]interface{})),
    91  	}
    92  	log.Printf("[INFO] Creating new horizontal pod autoscaler: %#v", svc)
    93  	out, err := conn.AutoscalingV1().HorizontalPodAutoscalers(metadata.Namespace).Create(&svc)
    94  	if err != nil {
    95  		return err
    96  	}
    97  
    98  	log.Printf("[INFO] Submitted new horizontal pod autoscaler: %#v", out)
    99  	d.SetId(buildId(out.ObjectMeta))
   100  
   101  	return resourceKubernetesHorizontalPodAutoscalerRead(d, meta)
   102  }
   103  
   104  func resourceKubernetesHorizontalPodAutoscalerRead(d *schema.ResourceData, meta interface{}) error {
   105  	conn := meta.(*kubernetes.Clientset)
   106  
   107  	namespace, name := idParts(d.Id())
   108  	log.Printf("[INFO] Reading horizontal pod autoscaler %s", name)
   109  	svc, err := conn.AutoscalingV1().HorizontalPodAutoscalers(namespace).Get(name, meta_v1.GetOptions{})
   110  	if err != nil {
   111  		log.Printf("[DEBUG] Received error: %#v", err)
   112  		return err
   113  	}
   114  	log.Printf("[INFO] Received horizontal pod autoscaler: %#v", svc)
   115  	err = d.Set("metadata", flattenMetadata(svc.ObjectMeta))
   116  	if err != nil {
   117  		return err
   118  	}
   119  
   120  	flattened := flattenHorizontalPodAutoscalerSpec(svc.Spec)
   121  	log.Printf("[DEBUG] Flattened horizontal pod autoscaler spec: %#v", flattened)
   122  	err = d.Set("spec", flattened)
   123  	if err != nil {
   124  		return err
   125  	}
   126  
   127  	return nil
   128  }
   129  
   130  func resourceKubernetesHorizontalPodAutoscalerUpdate(d *schema.ResourceData, meta interface{}) error {
   131  	conn := meta.(*kubernetes.Clientset)
   132  
   133  	namespace, name := idParts(d.Id())
   134  
   135  	ops := patchMetadata("metadata.0.", "/metadata/", d)
   136  	if d.HasChange("spec") {
   137  		diffOps := patchHorizontalPodAutoscalerSpec("spec.0.", "/spec", d)
   138  		ops = append(ops, diffOps...)
   139  	}
   140  	data, err := ops.MarshalJSON()
   141  	if err != nil {
   142  		return fmt.Errorf("Failed to marshal update operations: %s", err)
   143  	}
   144  	log.Printf("[INFO] Updating horizontal pod autoscaler %q: %v", name, string(data))
   145  	out, err := conn.AutoscalingV1().HorizontalPodAutoscalers(namespace).Patch(name, pkgApi.JSONPatchType, data)
   146  	if err != nil {
   147  		return fmt.Errorf("Failed to update horizontal pod autoscaler: %s", err)
   148  	}
   149  	log.Printf("[INFO] Submitted updated horizontal pod autoscaler: %#v", out)
   150  	d.SetId(buildId(out.ObjectMeta))
   151  
   152  	return resourceKubernetesHorizontalPodAutoscalerRead(d, meta)
   153  }
   154  
   155  func resourceKubernetesHorizontalPodAutoscalerDelete(d *schema.ResourceData, meta interface{}) error {
   156  	conn := meta.(*kubernetes.Clientset)
   157  
   158  	namespace, name := idParts(d.Id())
   159  	log.Printf("[INFO] Deleting horizontal pod autoscaler: %#v", name)
   160  	err := conn.AutoscalingV1().HorizontalPodAutoscalers(namespace).Delete(name, &meta_v1.DeleteOptions{})
   161  	if err != nil {
   162  		return err
   163  	}
   164  
   165  	log.Printf("[INFO] Horizontal Pod Autoscaler %s deleted", name)
   166  
   167  	d.SetId("")
   168  	return nil
   169  }
   170  
   171  func resourceKubernetesHorizontalPodAutoscalerExists(d *schema.ResourceData, meta interface{}) (bool, error) {
   172  	conn := meta.(*kubernetes.Clientset)
   173  
   174  	namespace, name := idParts(d.Id())
   175  	log.Printf("[INFO] Checking horizontal pod autoscaler %s", name)
   176  	_, err := conn.AutoscalingV1().HorizontalPodAutoscalers(namespace).Get(name, meta_v1.GetOptions{})
   177  	if err != nil {
   178  		if statusErr, ok := err.(*errors.StatusError); ok && statusErr.ErrStatus.Code == 404 {
   179  			return false, nil
   180  		}
   181  		log.Printf("[DEBUG] Received error: %#v", err)
   182  	}
   183  	return true, err
   184  }