Skip to content
This repository has been archived by the owner on Jun 13, 2024. It is now read-only.

Wait conditions #35

Merged
merged 1 commit into from
May 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ After the version is published, verify it exists on the [Kubernetes Collection G

## More Information

For more information about Ansible's Kubernetes integration, join the `#ansible-community` channel on Freenode IRC, and browse the resources in the [Kubernetes Working Group](https://github.com/ansible/community/wiki/Kubernetes) Community wiki page.
For more information about Ansible's Kubernetes integration, join the `#ansible-kubernetes` channel on Freenode IRC, and browse the resources in the [Kubernetes Working Group](https://github.com/ansible/community/wiki/Kubernetes) Community wiki page.

## License

Expand Down
2 changes: 2 additions & 0 deletions molecule/default/molecule.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ provisioner:
ansible_python_interpreter: '{{ ansible_playbook_python }}'
env:
ANSIBLE_FORCE_COLOR: 'true'
options:
vvv: True
scenario:
name: default
test_sequence:
Expand Down
156 changes: 156 additions & 0 deletions molecule/default/tasks/apply.yml
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,162 @@
- k8s_service_3.result.spec.ports | length == 1
- k8s_service_3.result.spec.ports[0].port == 8081

- name: Insert new service port
k8s:
definition:
apiVersion: v1
kind: Service
metadata:
name: apply-svc
namespace: "{{ apply_namespace }}"
spec:
selector:
app: whatever
ports:
- name: mesh
port: 8080
targetPort: 8080
- name: http
port: 8081
targetPort: 8081
apply: yes
register: k8s_service_4

- name: Check ports are correct
assert:
that:
- k8s_service_4 is changed
- k8s_service_4.result.spec.ports | length == 2
- k8s_service_4.result.spec.ports[0].port == 8080
- k8s_service_4.result.spec.ports[1].port == 8081

- name: Remove new service port (check mode)
k8s:
definition:
apiVersion: v1
kind: Service
metadata:
name: apply-svc
namespace: "{{ apply_namespace }}"
spec:
selector:
app: whatever
ports:
- name: http
port: 8081
targetPort: 8081
apply: yes
check_mode: yes
register: k8s_service_check

- name: Check ports are correct
assert:
that:
- k8s_service_check is changed
- k8s_service_check.result.spec.ports | length == 1
- k8s_service_check.result.spec.ports[0].port == 8081

- name: Remove new service port
k8s:
definition:
apiVersion: v1
kind: Service
metadata:
name: apply-svc
namespace: "{{ apply_namespace }}"
spec:
selector:
app: whatever
ports:
- name: http
port: 8081
targetPort: 8081
apply: yes
register: k8s_service_5

- name: Check ports are correct
assert:
that:
- k8s_service_5 is changed
- k8s_service_5.result.spec.ports | length == 1
- k8s_service_5.result.spec.ports[0].port == 8081

- name: Add a serviceaccount
k8s:
definition:
apiVersion: v1
kind: ServiceAccount
metadata:
name: apply-deploy
namespace: "{{ apply_namespace }}"

- name: Add a deployment
k8s:
definition:
apiVersion: apps/v1
kind: Deployment
metadata:
name: apply-deploy
namespace: "{{ apply_namespace }}"
spec:
replicas: 1
selector:
matchLabels:
app: "{{ k8s_pod_name }}"
template: "{{ k8s_pod_template }}"
wait: yes
apply: yes
vars:
k8s_pod_name: apply-deploy
k8s_pod_image: gcr.io/kuar-demo/kuard-amd64:v0.10.0-green
k8s_pod_service_account: apply-deploy
k8s_pod_ports:
- containerPort: 8080
name: http
protocol: TCP

- name: Remove the serviceaccount
k8s:
state: absent
definition:
apiVersion: v1
kind: ServiceAccount
metadata:
name: apply-deploy
namespace: "{{ apply_namespace }}"

- name: Update the earlier deployment
k8s:
definition:
apiVersion: apps/v1
kind: Deployment
metadata:
name: apply-deploy
namespace: "{{ apply_namespace }}"
spec:
replicas: 1
selector:
matchLabels:
app: "{{ k8s_pod_name }}"
template: "{{ k8s_pod_template }}"
wait: yes
apply: yes
vars:
k8s_pod_name: apply-deploy
k8s_pod_image: gcr.io/kuar-demo/kuard-amd64:v0.10.0-purple
k8s_pod_service_account: apply-deploy
k8s_pod_ports:
- containerPort: 8080
name: http
protocol: TCP
register: deploy_after_serviceaccount_removal
ignore_errors: yes

- name: Ensure that updating deployment after service account removal failed
assert:
that:
- deploy_after_serviceaccount_removal is failed

always:
- name: Remove namespace
k8s:
Expand Down
3 changes: 3 additions & 0 deletions molecule/default/vars/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ k8s_pod_metadata:
app: "{{ k8s_pod_name }}"

k8s_pod_spec:
serviceAccount: "{{ k8s_pod_service_account }}"
containers:
- image: "{{ k8s_pod_image }}"
imagePullPolicy: Always
Expand All @@ -20,6 +21,8 @@ k8s_pod_spec:
memory: "100Mi"
ports: "{{ k8s_pod_ports }}"

k8s_pod_service_account: default

k8s_pod_command: []

k8s_pod_ports: []
Expand Down
6 changes: 4 additions & 2 deletions plugins/module_utils/raw.py
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,8 @@ def _deployment_ready(deployment):
# Furthermore deployment.status.availableReplicas == deployment.status.replicas == None if status is empty
return (deployment.status and deployment.status.replicas is not None and
deployment.status.availableReplicas == deployment.status.replicas and
deployment.status.observedGeneration == deployment.metadata.generation)
deployment.status.observedGeneration == deployment.metadata.generation and
not deployment.status.unavailableReplicas)

def _pod_ready(pod):
return (pod.status and pod.status.containerStatuses is not None and
Expand All @@ -478,7 +479,8 @@ def _pod_ready(pod):
def _daemonset_ready(daemonset):
return (daemonset.status and daemonset.status.desiredNumberScheduled is not None and
daemonset.status.numberReady == daemonset.status.desiredNumberScheduled and
daemonset.status.observedGeneration == daemonset.metadata.generation)
daemonset.status.observedGeneration == daemonset.metadata.generation and
not daemonset.status.unavailableReplicas)

def _custom_condition(resource):
if not resource.status or not resource.status.conditions:
Expand Down
30 changes: 16 additions & 14 deletions plugins/module_utils/scale.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,16 @@

try:
import yaml
from openshift import watch
from openshift.dynamic.client import ResourceInstance
from openshift.helper.exceptions import KubernetesException
except ImportError as exc:
class KubernetesException(Exception):
from openshift.dynamic.exceptions import NotFoundError
except ImportError:
pass
try:
from openshift import watch
willthames marked this conversation as resolved.
Show resolved Hide resolved
except ImportError:
try:
from openshift.dynamic.client import watch
except ImportError:
pass


Expand Down Expand Up @@ -114,7 +119,7 @@ def execute_module(self):
try:
existing = resource.get(name=name, namespace=namespace)
return_attributes['result'] = existing.to_dict()
except KubernetesException as exc:
except NotFoundError as exc:
self.fail_json(msg='Failed to retrieve requested object: {0}'.format(exc),
error=exc.value.get('status'))

Expand Down Expand Up @@ -189,15 +194,12 @@ def _create_stream(self, resource, namespace, wait_time):
""" Create a stream of events for the object """
w = None
stream = None
try:
w = watch.Watch()
w._api_client = self.client.client
if namespace:
stream = w.stream(resource.get, serialize=False, namespace=namespace, timeout_seconds=wait_time)
else:
stream = w.stream(resource.get, serialize=False, namespace=namespace, timeout_seconds=wait_time)
except KubernetesException:
pass
w = watch.Watch()
w._api_client = self.client.client
if namespace:
willthames marked this conversation as resolved.
Show resolved Hide resolved
stream = w.stream(resource.get, serialize=False, namespace=namespace, timeout_seconds=wait_time)
else:
stream = w.stream(resource.get, serialize=False, namespace=namespace, timeout_seconds=wait_time)
return w, stream

def _read_stream(self, resource, watcher, stream, name, replicas):
Expand Down