Skip to content

Commit

Permalink
workload status wait (#42)
Browse files Browse the repository at this point in the history
* workload status wait
- wait for workload (sts, deploy, ds) using kubectl's status viewer logic
- add configurable timeouts to allow failing faster if needed
- save the state on resource create before polling for the result to avoid losing state
  • Loading branch information
pepov committed Mar 31, 2020
1 parent cea58b9 commit e3c0694
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 7 deletions.
3 changes: 2 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ commands:
background: true
command: |
sudo -E minikube tunnel
setup_go:
description: Setup Go
parameters:
Expand Down Expand Up @@ -123,6 +123,7 @@ jobs:
name: Run tests
command: go test .


integration-test-012-k8s1-16:
executor: minikube
steps:
Expand Down
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ test-integration: build bin/terraform ## Execute integration tests
cp build/terraform-provider-k8s .
bin/terraform init ${EXAMPLE_DIR}
bin/terraform apply -auto-approve ${EXAMPLE_DIR}
${MAKE} test-integration-destroy EXAMPLE_DIR=${EXAMPLE_DIR}

.PHONY: test-integration-destroy
test-integration-destroy: EXAMPLE_DIR ?= examples/0.12
test-integration-destroy:
bin/terraform destroy -auto-approve ${EXAMPLE_DIR}
rm terraform-provider-k8s

Expand Down
30 changes: 30 additions & 0 deletions examples/fail/example.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@

resource "k8s_manifest" "nginx-deployment" {
content = <<-EOT
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
command: ["/bin/false"]
EOT
timeouts {
create = "20s"
}
}
3 changes: 3 additions & 0 deletions examples/fail/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
terraform {
required_version = ">= 0.12"
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ require (
google.golang.org/grpc v1.23.1 // indirect
k8s.io/apimachinery v0.17.2
k8s.io/client-go v0.17.2
k8s.io/kubectl v0.17.2
sigs.k8s.io/controller-runtime v0.4.0
)
71 changes: 71 additions & 0 deletions go.sum

Large diffs are not rendered by default.

31 changes: 25 additions & 6 deletions k8s/resource_k8s_manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
k8sschema "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/yaml"
"k8s.io/kubectl/pkg/polymorphichelpers"
"sigs.k8s.io/controller-runtime/pkg/client"
)

Expand Down Expand Up @@ -49,6 +50,11 @@ func resourceK8sManifest() *schema.Resource {
Sensitive: false,
},
},
Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(3 * time.Minute),
Update: schema.DefaultTimeout(3 * time.Minute),
Delete: schema.DefaultTimeout(1 * time.Minute),
},
}
}

Expand Down Expand Up @@ -84,17 +90,18 @@ func resourceK8sManifestCreate(d *schema.ResourceData, config interface{}) error
return err
}

err = waitForReadyStatus(d, client, object)
// this must stand before the wait to avoid losing state on error
d.SetId(buildId(object))

err = waitForReadyStatus(d, client, object, d.Timeout(schema.TimeoutCreate))
if err != nil {
return err
}

d.SetId(buildId(object))

return resourceK8sManifestRead(d, config)
}

func waitForReadyStatus(d *schema.ResourceData, c client.Client, object *unstructured.Unstructured) error {
func waitForReadyStatus(d *schema.ResourceData, c client.Client, object *unstructured.Unstructured, timeout time.Duration) error {
objectKey, err := client.ObjectKeyFromObject(object)
if err != nil {
log.Printf("[DEBUG] Received error: %#v", err)
Expand All @@ -120,6 +127,18 @@ func waitForReadyStatus(d *schema.ResourceData, c client.Client, object *unstruc
if s, ok := object.Object["status"]; ok {
log.Printf("[DEBUG] Object has status: %#v", s)

if statusViewer, err := polymorphichelpers.StatusViewerFor(object.GetObjectKind().GroupVersionKind().GroupKind()); err == nil {
_, ready, err := statusViewer.Status(object, 0)
if err != nil {
return nil, "error", err
}
if ready {
return object, "ready", nil
}
return object, "pending", nil
}
log.Printf("[DEBUG] Object has no rollout status viewer")

var status status
err = mapstructure.Decode(s, &status)
if err != nil {
Expand Down Expand Up @@ -175,7 +194,7 @@ func waitForReadyStatus(d *schema.ResourceData, c client.Client, object *unstruc

return object, "ready", nil
},
Timeout: d.Timeout(schema.TimeoutCreate),
Timeout: timeout,
Delay: 5 * time.Second,
MinTimeout: 5 * time.Second,
ContinuousTargetOccurence: 1,
Expand Down Expand Up @@ -297,7 +316,7 @@ func resourceK8sManifestUpdate(d *schema.ResourceData, config interface{}) error
}
log.Printf("[INFO] Updated object: %#v", object)

return waitForReadyStatus(d, client, object)
return waitForReadyStatus(d, client, object, d.Timeout(schema.TimeoutUpdate))
}

func resourceK8sManifestDelete(d *schema.ResourceData, config interface{}) error {
Expand Down

0 comments on commit e3c0694

Please sign in to comment.