Skip to content

Commit

Permalink
BREAKING - Update DaemonSet schema to match API.
Browse files Browse the repository at this point in the history
  • Loading branch information
sl1pm4t committed Feb 19, 2018
1 parent 4c209e1 commit 290c4a3
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 16 deletions.
110 changes: 106 additions & 4 deletions kubernetes/resource_kubernetes_daemonset.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ package kubernetes
import (
"fmt"
"log"
"strings"
"time"

"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/terraform"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
pkgApi "k8s.io/apimachinery/pkg/types"
Expand All @@ -23,6 +25,8 @@ func resourceKubernetesDaemonSet() *schema.Resource {
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
SchemaVersion: 1,
MigrateState: resourceKubernetesDaemonSetStateUpgrader,

Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(10 * time.Minute),
Expand Down Expand Up @@ -92,11 +96,39 @@ func resourceKubernetesDaemonSet() *schema.Resource {
},
"template": {
Type: schema.TypeList,
Description: "Describes the pod that will be created if insufficient replicas are detected. This takes precedence over a TemplateRef. More info: http://kubernetes.io/docs/user-guide/replication-controller#pod-template",
Description: "Template describes the pods that will be created.",
Required: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: podSpecFields(false),
Schema: map[string]*schema.Schema{
"metadata": metadataSchema("daemonsetSpec", true),
"spec": &schema.Schema{
Type: schema.TypeList,
Description: "Spec describes the pods that will be created.",
Required: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: podSpecFields(false),
},
},
"active_deadline_seconds": relocatedAttribute("active_deadline_seconds"),
"container": relocatedAttribute("container"),
"dns_policy": relocatedAttribute("dns_policy"),
"host_ipc": relocatedAttribute("host_ipc"),
"host_network": relocatedAttribute("host_network"),
"host_pid": relocatedAttribute("host_pid"),
"hostname": relocatedAttribute("hostname"),
"init_container": relocatedAttribute("init_container"),
"node_name": relocatedAttribute("node_name"),
"node_selector": relocatedAttribute("node_selector"),
"restart_policy": relocatedAttribute("restart_policy"),
"security_context": relocatedAttribute("security_context"),
"service_account_name": relocatedAttribute("service_account_name"),
"automount_service_account_token": relocatedAttribute("automount_service_account_token"),
"subdomain": relocatedAttribute("subdomain"),
"termination_grace_period_seconds": relocatedAttribute("termination_grace_period_seconds"),
"volume": relocatedAttribute("volume"),
},
},
},
},
Expand All @@ -114,7 +146,9 @@ func resourceKubernetesDaemonSetCreate(d *schema.ResourceData, meta interface{})
if err != nil {
return err
}
spec.Template.ObjectMeta.Annotations = metadata.Annotations
if metadata.Namespace == "" {
metadata.Namespace = "default"
}

daemonset := v1beta1.DaemonSet{
ObjectMeta: metadata,
Expand Down Expand Up @@ -151,7 +185,7 @@ func resourceKubernetesDaemonSetRead(d *schema.ResourceData, meta interface{}) e
return err
}

spec, err := flattenDaemonSetSpec(daemonset.Spec)
spec, err := flattenDaemonSetSpec(daemonset.Spec, d)
if err != nil {
return err
}
Expand Down Expand Up @@ -228,3 +262,71 @@ func resourceKubernetesDaemonSetExists(d *schema.ResourceData, meta interface{})
}
return true, err
}

func resourceKubernetesDaemonSetStateUpgrader(
v int, is *terraform.InstanceState, meta interface{}) (*terraform.InstanceState, error) {
if is.Empty() {
log.Println("[DEBUG] Empty InstanceState; nothing to migrate.")
return is, nil
}

var err error

switch v {
case 0:
log.Println("[INFO] Found Kubernetes DaemonSet State v0; migrating to v1")
is, err = migrateDaemonSetStateV0toV1(is)
if err != nil {
return is, err
}

default:
return is, fmt.Errorf("Unexpected schema version: %d", v)
}

return is, err
}

// This deployment resource originally had the podSpec directly below spec.template level
// This migration moves the state to spec.template.spec match the Kubernetes documented structure
func migrateDaemonSetStateV0toV1(is *terraform.InstanceState) (*terraform.InstanceState, error) {
log.Printf("[DEBUG] Attributes before migration: %#v", is.Attributes)

newTemplate := make(map[string]string)

for k, v := range is.Attributes {
log.Println("[DEBUG] - checking attribute for state upgrade: ", k, v)
if strings.HasPrefix(k, "name") {
// don't clobber an existing metadata.0.name value
if _, ok := is.Attributes["metadata.0.name"]; ok {
continue
}

newK := "metadata.0.name"

newTemplate[newK] = v
log.Printf("[DEBUG] moved attribute %s -> %s ", k, newK)
delete(is.Attributes, k)

} else if !strings.HasPrefix(k, "spec.0.template") {
continue

} else if strings.HasPrefix(k, "spec.0.template.0.spec") || strings.HasPrefix(k, "spec.0.template.0.metadata") {
continue

} else {
newK := strings.Replace(k, "spec.0.template.0", "spec.0.template.0.spec.0", 1)

newTemplate[newK] = v
log.Printf("[DEBUG] moved attribute %s -> %s ", k, newK)
delete(is.Attributes, k)
}
}

for k, v := range newTemplate {
is.Attributes[k] = v
}

log.Printf("[DEBUG] Attributes after migration: %#v", is.Attributes)
return is, nil
}
3 changes: 2 additions & 1 deletion kubernetes/resource_kubernetes_deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ func resourceKubernetesDeployment() *schema.Resource {
"host_network": relocatedAttribute("host_network"),
"host_pid": relocatedAttribute("host_pid"),
"hostname": relocatedAttribute("hostname"),
"init_container": relocatedAttribute("init_container"),
"node_name": relocatedAttribute("node_name"),
"node_selector": relocatedAttribute("node_selector"),
"restart_policy": relocatedAttribute("restart_policy"),
Expand All @@ -154,7 +155,7 @@ func relocatedAttribute(name string) *schema.Schema {
s := &schema.Schema{
Type: schema.TypeString,
Optional: true,
Removed: fmt.Sprintf("%s has been relocated to deployment/spec/template/spec/%s. Please update your Terraform config.", name, name),
Removed: fmt.Sprintf("%s has been relocated to [resource]/spec/template/spec/%s. Please update your Terraform config.", name, name),
}
return s
}
Expand Down
50 changes: 39 additions & 11 deletions kubernetes/structures_daemonset.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,34 @@ package kubernetes
import (
"strconv"

"github.com/hashicorp/terraform/helper/schema"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/client-go/pkg/api/v1"
"k8s.io/client-go/pkg/apis/extensions/v1beta1"
)

func flattenDaemonSetSpec(in v1beta1.DaemonSetSpec) ([]interface{}, error) {
func flattenDaemonSetSpec(in v1beta1.DaemonSetSpec, d *schema.ResourceData) ([]interface{}, error) {
att := make(map[string]interface{})
att["min_ready_seconds"] = in.MinReadySeconds

att["selector"] = in.Selector.MatchLabels
att["strategy"] = flattenDaemonSetStrategy(in.UpdateStrategy)
// podSpec, err := flattenPodSpec(in.Template.Spec)
// if err != nil {
// return nil, err
// }
// att["template"] = podSpec

templateMetadata := flattenMetadata(in.Template.ObjectMeta, d)
podSpec, err := flattenPodSpec(in.Template.Spec)
if err != nil {
return nil, err
}
att["template"] = podSpec
template := make(map[string]interface{})
template["metadata"] = templateMetadata
template["spec"] = podSpec
att["template"] = []interface{}{template}

return []interface{}{att}, nil
}
Expand Down Expand Up @@ -56,15 +67,32 @@ func expandDaemonSetSpec(deployment []interface{}) (v1beta1.DaemonSetSpec, error
}
}
obj.UpdateStrategy = expandDaemonSetStrategy(in["strategy"].([]interface{}))
podSpec, err := expandPodSpec(in["template"].([]interface{}))
if err != nil {
return obj, err
}
obj.Template = v1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: obj.Selector.MatchLabels,
},
Spec: podSpec,

// podSpec, err := expandPodSpec(in["template"].([]interface{}))
// if err != nil {
// return obj, err
// }
// obj.Template = v1.PodTemplateSpec{
// ObjectMeta: metav1.ObjectMeta{
// Labels: obj.Selector.MatchLabels,
// },
// Spec: podSpec,
// }

for _, v := range in["template"].([]interface{}) {
template := v.(map[string]interface{})
podSpec, err := expandPodSpec(template["spec"].([]interface{}))
if err != nil {
return obj, err
}
obj.Template = v1.PodTemplateSpec{
Spec: podSpec,
}

if metaCfg, ok := template["metadata"]; ok {
metadata := expandMetadata(metaCfg.([]interface{}))
obj.Template.ObjectMeta = metadata
}
}

return obj, nil
Expand Down

0 comments on commit 290c4a3

Please sign in to comment.