mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 08:58:59 +00:00
931 lines
34 KiB
Python
931 lines
34 KiB
Python
# -*- coding: utf-8 -*-
|
|
'''
|
|
:codeauthor: :email:`Jeff Schroeder <jeffschroeder@computer.org>`
|
|
'''
|
|
# Import Python libs
|
|
from __future__ import absolute_import, unicode_literals, print_function
|
|
import base64
|
|
|
|
from contextlib import contextmanager
|
|
|
|
|
|
# Import Salt Testing Libs
|
|
from tests.support.mixins import LoaderModuleMockMixin
|
|
from tests.support.unit import skipIf, TestCase
|
|
from tests.support.mock import (
|
|
NO_MOCK,
|
|
NO_MOCK_REASON,
|
|
MagicMock,
|
|
patch)
|
|
|
|
# Import Salt Libs
|
|
import salt.utils.stringutils
|
|
from salt.states import kubernetes
|
|
from salt.ext import six
|
|
|
|
|
|
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
|
@skipIf(kubernetes is False, "Probably Kubernetes client lib is not installed. \
|
|
Skipping test_kubernetes.py")
|
|
class KubernetesTestCase(TestCase, LoaderModuleMockMixin):
|
|
'''
|
|
Test cases for salt.states.kubernetes
|
|
'''
|
|
def setup_loader_modules(self):
|
|
return {kubernetes: {'__env__': 'base'}}
|
|
|
|
@contextmanager
|
|
def mock_func(self, func_name, return_value, test=False):
|
|
'''
|
|
Mock any of the kubernetes state function return values and set
|
|
the test options.
|
|
'''
|
|
name = 'kubernetes.{0}'.format(func_name)
|
|
mocked = {name: MagicMock(return_value=return_value)}
|
|
with patch.dict(kubernetes.__salt__, mocked) as patched:
|
|
with patch.dict(kubernetes.__opts__, {'test': test}):
|
|
yield patched
|
|
|
|
def make_configmap(self, name, namespace='default', data=None):
|
|
return self.make_ret_dict(
|
|
kind='ConfigMap',
|
|
name=name,
|
|
namespace=namespace,
|
|
data=data,
|
|
)
|
|
|
|
def make_secret(self, name, namespace='default', data=None):
|
|
secret_data = self.make_ret_dict(
|
|
kind='Secret',
|
|
name=name,
|
|
namespace=namespace,
|
|
data=data,
|
|
)
|
|
# Base64 all of the values just like kubectl does
|
|
for key, value in six.iteritems(secret_data['data']):
|
|
secret_data['data'][key] = base64.b64encode(
|
|
salt.utils.stringutils.to_bytes(value)
|
|
)
|
|
|
|
return secret_data
|
|
|
|
def make_node_labels(self, name='minikube'):
|
|
return {
|
|
'kubernetes.io/hostname': name,
|
|
'beta.kubernetes.io/os': 'linux',
|
|
'beta.kubernetes.io/arch': 'amd64',
|
|
'failure-domain.beta.kubernetes.io/region': 'us-west-1',
|
|
}
|
|
|
|
def make_node(self, name='minikube'):
|
|
node_data = self.make_ret_dict(kind='Node', name='minikube')
|
|
node_data.update({
|
|
'api_version': 'v1',
|
|
'kind': 'Node',
|
|
'metadata': {
|
|
'annotations': {
|
|
'node.alpha.kubernetes.io/ttl': '0',
|
|
},
|
|
'labels': self.make_node_labels(name=name),
|
|
'name': name,
|
|
'namespace': None,
|
|
'self_link': '/api/v1/nodes/{name}'.format(name=name),
|
|
'uid': '7811b8ae-c1a1-11e7-a55a-0800279fb61e',
|
|
},
|
|
'spec': {
|
|
'external_id': name,
|
|
},
|
|
'status': {},
|
|
})
|
|
return node_data
|
|
|
|
def make_namespace(self, name='default'):
|
|
namespace_data = self.make_ret_dict(kind='Namespace', name=name)
|
|
del namespace_data['data']
|
|
namespace_data.update({
|
|
'status': {
|
|
'phase': 'Active',
|
|
},
|
|
'spec': {
|
|
'finalizers': ['kubernetes'],
|
|
},
|
|
'metadata': {
|
|
'name': name,
|
|
'namespace': None,
|
|
'labels': None,
|
|
'self_link': '/api/v1/namespaces/{namespace}'.format(
|
|
namespace=name,
|
|
),
|
|
'annotations': None,
|
|
'uid': '752fceeb-c1a1-11e7-a55a-0800279fb61e',
|
|
},
|
|
})
|
|
return namespace_data
|
|
|
|
def make_ret_dict(self, kind, name, namespace=None, data=None):
|
|
'''
|
|
Make a minimal example configmap or secret for using in mocks
|
|
'''
|
|
|
|
assert kind in ('Secret', 'ConfigMap', 'Namespace', 'Node')
|
|
|
|
if data is None:
|
|
data = {}
|
|
|
|
self_link = '/api/v1/namespaces/{namespace}/{kind}s/{name}'.format(
|
|
namespace=namespace,
|
|
kind=kind.lower(),
|
|
name=name,
|
|
)
|
|
|
|
return_data = {
|
|
'kind': kind,
|
|
'data': data,
|
|
'api_version': 'v1',
|
|
'metadata': {
|
|
'name': name,
|
|
'labels': None,
|
|
'namespace': namespace,
|
|
'self_link': self_link,
|
|
'annotations': {
|
|
'kubernetes.io/change-cause': 'salt-call state.apply',
|
|
},
|
|
},
|
|
}
|
|
return return_data
|
|
|
|
def test_configmap_present__fail(self):
|
|
error = kubernetes.configmap_present(
|
|
name='testme',
|
|
data={1: 1},
|
|
source='salt://beyond/oblivion.jinja',
|
|
)
|
|
self.assertDictEqual(
|
|
{
|
|
'changes': {},
|
|
'result': False,
|
|
'name': 'testme',
|
|
'comment': "'source' cannot be used in combination with 'data'",
|
|
},
|
|
error,
|
|
)
|
|
|
|
def test_configmap_present__create_test_true(self):
|
|
# Create a new configmap with test=True
|
|
with self.mock_func('show_configmap', return_value=None, test=True):
|
|
ret = kubernetes.configmap_present(
|
|
name='example',
|
|
data={'example.conf': '# empty config file'},
|
|
)
|
|
self.assertDictEqual(
|
|
{
|
|
'comment': 'The configmap is going to be created',
|
|
'changes': {},
|
|
'name': 'example',
|
|
'result': None,
|
|
},
|
|
ret,
|
|
)
|
|
|
|
def test_configmap_present__create(self):
|
|
# Create a new configmap
|
|
with self.mock_func('show_configmap', return_value=None):
|
|
cm = self.make_configmap(
|
|
name='test',
|
|
namespace='default',
|
|
data={'foo': 'bar'},
|
|
)
|
|
with self.mock_func('create_configmap', return_value=cm):
|
|
actual = kubernetes.configmap_present(
|
|
name='test',
|
|
data={'foo': 'bar'},
|
|
)
|
|
self.assertDictEqual(
|
|
{
|
|
'comment': '',
|
|
'changes': {'data': {'foo': 'bar'}},
|
|
'name': 'test',
|
|
'result': True,
|
|
},
|
|
actual,
|
|
)
|
|
|
|
def test_configmap_present__create_no_data(self):
|
|
# Create a new configmap with no 'data' attribute
|
|
with self.mock_func('show_configmap', return_value=None):
|
|
cm = self.make_configmap(
|
|
name='test',
|
|
namespace='default',
|
|
)
|
|
with self.mock_func('create_configmap', return_value=cm):
|
|
actual = kubernetes.configmap_present(name='test')
|
|
self.assertDictEqual(
|
|
{
|
|
'comment': '',
|
|
'changes': {'data': {}},
|
|
'name': 'test',
|
|
'result': True,
|
|
},
|
|
actual,
|
|
)
|
|
|
|
def test_configmap_present__replace_test_true(self):
|
|
cm = self.make_configmap(
|
|
name='settings',
|
|
namespace='saltstack',
|
|
data={'foobar.conf': '# Example configuration'},
|
|
)
|
|
with self.mock_func('show_configmap', return_value=cm, test=True):
|
|
ret = kubernetes.configmap_present(
|
|
name='settings',
|
|
namespace='saltstack',
|
|
data={'foobar.conf': '# Example configuration'},
|
|
)
|
|
self.assertDictEqual(
|
|
{
|
|
'comment': 'The configmap is going to be replaced',
|
|
'changes': {},
|
|
'name': 'settings',
|
|
'result': None,
|
|
},
|
|
ret,
|
|
)
|
|
|
|
def test_configmap_present__replace(self):
|
|
cm = self.make_configmap(name='settings', data={'action': 'make=war'})
|
|
# Replace an existing configmap
|
|
with self.mock_func('show_configmap', return_value=cm):
|
|
new_cm = cm.copy()
|
|
new_cm.update({
|
|
'data': {'action': 'make=peace'},
|
|
})
|
|
with self.mock_func('replace_configmap', return_value=new_cm):
|
|
actual = kubernetes.configmap_present(
|
|
name='settings',
|
|
data={'action': 'make=peace'},
|
|
)
|
|
self.assertDictEqual(
|
|
{
|
|
'comment': 'The configmap is already present. Forcing recreation',
|
|
'changes': {
|
|
'data': {
|
|
'action': 'make=peace',
|
|
},
|
|
},
|
|
'name': 'settings',
|
|
'result': True,
|
|
},
|
|
actual,
|
|
)
|
|
|
|
def test_configmap_absent__noop_test_true(self):
|
|
# Nothing to delete with test=True
|
|
with self.mock_func('show_configmap', return_value=None, test=True):
|
|
actual = kubernetes.configmap_absent(name='NOT_FOUND')
|
|
self.assertDictEqual(
|
|
{
|
|
'comment': 'The configmap does not exist',
|
|
'changes': {},
|
|
'name': 'NOT_FOUND',
|
|
'result': None,
|
|
},
|
|
actual,
|
|
)
|
|
|
|
def test_configmap_absent__test_true(self):
|
|
# Configmap exists with test=True
|
|
cm = self.make_configmap(name='deleteme', namespace='default')
|
|
with self.mock_func('show_configmap', return_value=cm, test=True):
|
|
actual = kubernetes.configmap_absent(name='deleteme')
|
|
self.assertDictEqual(
|
|
{
|
|
'comment': 'The configmap is going to be deleted',
|
|
'changes': {},
|
|
'name': 'deleteme',
|
|
'result': None,
|
|
},
|
|
actual,
|
|
)
|
|
|
|
def test_configmap_absent__noop(self):
|
|
# Nothing to delete
|
|
with self.mock_func('show_configmap', return_value=None):
|
|
actual = kubernetes.configmap_absent(name='NOT_FOUND')
|
|
self.assertDictEqual(
|
|
{
|
|
'comment': 'The configmap does not exist',
|
|
'changes': {},
|
|
'name': 'NOT_FOUND',
|
|
'result': True,
|
|
},
|
|
actual,
|
|
)
|
|
|
|
def test_configmap_absent(self):
|
|
# Configmap exists, delete it!
|
|
cm = self.make_configmap(name='deleteme', namespace='default')
|
|
with self.mock_func('show_configmap', return_value=cm):
|
|
# The return from this module isn't used in the state
|
|
with self.mock_func('delete_configmap', return_value={}):
|
|
actual = kubernetes.configmap_absent(name='deleteme')
|
|
self.assertDictEqual(
|
|
{
|
|
'comment': 'ConfigMap deleted',
|
|
'changes': {
|
|
'kubernetes.configmap': {
|
|
'new': 'absent',
|
|
'old': 'present',
|
|
},
|
|
},
|
|
'name': 'deleteme',
|
|
'result': True,
|
|
},
|
|
actual,
|
|
)
|
|
|
|
def test_secret_present__fail(self):
|
|
actual = kubernetes.secret_present(
|
|
name='sekret',
|
|
data={'password': 'monk3y'},
|
|
source='salt://nope.jinja',
|
|
)
|
|
self.assertDictEqual(
|
|
{
|
|
'changes': {},
|
|
'result': False,
|
|
'name': 'sekret',
|
|
'comment': "'source' cannot be used in combination with 'data'",
|
|
},
|
|
actual,
|
|
)
|
|
|
|
def test_secret_present__exists_test_true(self):
|
|
secret = self.make_secret(name='sekret')
|
|
new_secret = secret.copy()
|
|
new_secret.update({
|
|
'data': {'password': 'uncle'},
|
|
})
|
|
# Secret exists already and needs replacing with test=True
|
|
with self.mock_func('show_secret', return_value=secret):
|
|
with self.mock_func('replace_secret', return_value=new_secret, test=True):
|
|
actual = kubernetes.secret_present(
|
|
name='sekret',
|
|
data={'password': 'uncle'},
|
|
)
|
|
self.assertDictEqual(
|
|
{
|
|
'changes': {},
|
|
'result': None,
|
|
'name': 'sekret',
|
|
'comment': 'The secret is going to be replaced',
|
|
},
|
|
actual,
|
|
)
|
|
|
|
def test_secret_present__exists(self):
|
|
# Secret exists and gets replaced
|
|
secret = self.make_secret(name='sekret', data={'password': 'booyah'})
|
|
with self.mock_func('show_secret', return_value=secret):
|
|
with self.mock_func('replace_secret', return_value=secret):
|
|
actual = kubernetes.secret_present(
|
|
name='sekret',
|
|
data={'password': 'booyah'},
|
|
)
|
|
self.assertDictEqual(
|
|
{
|
|
'changes': {'data': ['password']},
|
|
'result': True,
|
|
'name': 'sekret',
|
|
'comment': "The secret is already present. Forcing recreation",
|
|
},
|
|
actual,
|
|
)
|
|
|
|
def test_secret_present__create(self):
|
|
# Secret exists and gets replaced
|
|
secret = self.make_secret(name='sekret', data={'password': 'booyah'})
|
|
with self.mock_func('show_secret', return_value=None):
|
|
with self.mock_func('create_secret', return_value=secret):
|
|
actual = kubernetes.secret_present(
|
|
name='sekret',
|
|
data={'password': 'booyah'},
|
|
)
|
|
self.assertDictEqual(
|
|
{
|
|
'changes': {'data': ['password']},
|
|
'result': True,
|
|
'name': 'sekret',
|
|
'comment': '',
|
|
},
|
|
actual,
|
|
)
|
|
|
|
def test_secret_present__create_no_data(self):
|
|
# Secret exists and gets replaced
|
|
secret = self.make_secret(name='sekret')
|
|
with self.mock_func('show_secret', return_value=None):
|
|
with self.mock_func('create_secret', return_value=secret):
|
|
actual = kubernetes.secret_present(name='sekret')
|
|
self.assertDictEqual(
|
|
{
|
|
'changes': {'data': []},
|
|
'result': True,
|
|
'name': 'sekret',
|
|
'comment': '',
|
|
},
|
|
actual,
|
|
)
|
|
|
|
def test_secret_present__create_test_true(self):
|
|
# Secret exists and gets replaced with test=True
|
|
secret = self.make_secret(name='sekret')
|
|
with self.mock_func('show_secret', return_value=None):
|
|
with self.mock_func('create_secret', return_value=secret, test=True):
|
|
actual = kubernetes.secret_present(name='sekret')
|
|
self.assertDictEqual(
|
|
{
|
|
'changes': {},
|
|
'result': None,
|
|
'name': 'sekret',
|
|
'comment': 'The secret is going to be created',
|
|
},
|
|
actual,
|
|
)
|
|
|
|
def test_secret_absent__noop_test_true(self):
|
|
with self.mock_func('show_secret', return_value=None, test=True):
|
|
actual = kubernetes.secret_absent(name='sekret')
|
|
self.assertDictEqual(
|
|
{
|
|
'changes': {},
|
|
'result': None,
|
|
'name': 'sekret',
|
|
'comment': 'The secret does not exist',
|
|
},
|
|
actual,
|
|
)
|
|
|
|
def test_secret_absent__noop(self):
|
|
with self.mock_func('show_secret', return_value=None):
|
|
actual = kubernetes.secret_absent(name='passwords')
|
|
self.assertDictEqual(
|
|
{
|
|
'changes': {},
|
|
'result': True,
|
|
'name': 'passwords',
|
|
'comment': 'The secret does not exist',
|
|
},
|
|
actual,
|
|
)
|
|
|
|
def test_secret_absent__delete_test_true(self):
|
|
secret = self.make_secret(name='credentials', data={'redis': 'letmein'})
|
|
with self.mock_func('show_secret', return_value=secret):
|
|
with self.mock_func('delete_secret', return_value=secret, test=True):
|
|
actual = kubernetes.secret_absent(name='credentials')
|
|
self.assertDictEqual(
|
|
{
|
|
'changes': {},
|
|
'result': None,
|
|
'name': 'credentials',
|
|
'comment': 'The secret is going to be deleted',
|
|
},
|
|
actual,
|
|
)
|
|
|
|
def test_secret_absent__delete(self):
|
|
secret = self.make_secret(name='foobar', data={'redis': 'letmein'})
|
|
deleted = {
|
|
'status': None,
|
|
'kind': 'Secret',
|
|
'code': None,
|
|
'reason': None,
|
|
'details': None,
|
|
'message': None,
|
|
'api_version': 'v1',
|
|
'metadata': {
|
|
'self_link': '/api/v1/namespaces/default/secrets/foobar',
|
|
'resource_version': '30292',
|
|
},
|
|
}
|
|
with self.mock_func('show_secret', return_value=secret):
|
|
with self.mock_func('delete_secret', return_value=deleted):
|
|
actual = kubernetes.secret_absent(name='foobar')
|
|
self.assertDictEqual(
|
|
{
|
|
'changes': {
|
|
'kubernetes.secret': {
|
|
'new': 'absent',
|
|
'old': 'present',
|
|
},
|
|
},
|
|
'result': True,
|
|
'name': 'foobar',
|
|
'comment': 'Secret deleted',
|
|
},
|
|
actual,
|
|
)
|
|
|
|
def test_node_label_present__add_test_true(self):
|
|
labels = self.make_node_labels()
|
|
with self.mock_func('node_labels', return_value=labels, test=True):
|
|
actual = kubernetes.node_label_present(
|
|
name='com.zoo-animal',
|
|
node='minikube',
|
|
value='monkey',
|
|
)
|
|
self.assertDictEqual(
|
|
{
|
|
'changes': {},
|
|
'result': None,
|
|
'name': 'com.zoo-animal',
|
|
'comment': 'The label is going to be set',
|
|
},
|
|
actual,
|
|
)
|
|
|
|
def test_node_label_present__add(self):
|
|
node_data = self.make_node()
|
|
# Remove some of the defaults to make it simpler
|
|
node_data['metadata']['labels'] = {
|
|
'beta.kubernetes.io/os': 'linux',
|
|
}
|
|
labels = node_data['metadata']['labels']
|
|
|
|
with self.mock_func('node_labels', return_value=labels):
|
|
with self.mock_func('node_add_label', return_value=node_data):
|
|
actual = kubernetes.node_label_present(
|
|
name='failure-domain.beta.kubernetes.io/zone',
|
|
node='minikube',
|
|
value='us-central1-a',
|
|
)
|
|
self.assertDictEqual(
|
|
{
|
|
'comment': '',
|
|
'changes': {
|
|
'minikube.failure-domain.beta.kubernetes.io/zone': {
|
|
'new': {
|
|
'failure-domain.beta.kubernetes.io/zone': 'us-central1-a',
|
|
'beta.kubernetes.io/os': 'linux'
|
|
},
|
|
'old': {
|
|
'beta.kubernetes.io/os': 'linux',
|
|
},
|
|
},
|
|
},
|
|
'name': 'failure-domain.beta.kubernetes.io/zone',
|
|
'result': True,
|
|
},
|
|
actual,
|
|
)
|
|
|
|
def test_node_label_present__already_set(self):
|
|
node_data = self.make_node()
|
|
labels = node_data['metadata']['labels']
|
|
with self.mock_func('node_labels', return_value=labels):
|
|
with self.mock_func('node_add_label', return_value=node_data):
|
|
actual = kubernetes.node_label_present(
|
|
name='failure-domain.beta.kubernetes.io/region',
|
|
node='minikube',
|
|
value='us-west-1',
|
|
)
|
|
self.assertDictEqual(
|
|
{
|
|
'changes': {},
|
|
'result': True,
|
|
'name': 'failure-domain.beta.kubernetes.io/region',
|
|
'comment': 'The label is already set and has the specified value',
|
|
},
|
|
actual,
|
|
)
|
|
|
|
def test_node_label_present__update_test_true(self):
|
|
node_data = self.make_node()
|
|
labels = node_data['metadata']['labels']
|
|
with self.mock_func('node_labels', return_value=labels):
|
|
with self.mock_func('node_add_label', return_value=node_data, test=True):
|
|
actual = kubernetes.node_label_present(
|
|
name='failure-domain.beta.kubernetes.io/region',
|
|
node='minikube',
|
|
value='us-east-1',
|
|
)
|
|
self.assertDictEqual(
|
|
{
|
|
'changes': {},
|
|
'result': None,
|
|
'name': 'failure-domain.beta.kubernetes.io/region',
|
|
'comment': 'The label is going to be updated',
|
|
},
|
|
actual,
|
|
)
|
|
|
|
def test_node_label_present__update(self):
|
|
node_data = self.make_node()
|
|
# Remove some of the defaults to make it simpler
|
|
node_data['metadata']['labels'] = {
|
|
'failure-domain.beta.kubernetes.io/region': 'us-west-1',
|
|
}
|
|
labels = node_data['metadata']['labels']
|
|
with self.mock_func('node_labels', return_value=labels):
|
|
with self.mock_func('node_add_label', return_value=node_data):
|
|
actual = kubernetes.node_label_present(
|
|
name='failure-domain.beta.kubernetes.io/region',
|
|
node='minikube',
|
|
value='us-east-1',
|
|
)
|
|
self.assertDictEqual(
|
|
{
|
|
'changes': {
|
|
'minikube.failure-domain.beta.kubernetes.io/region': {
|
|
'new': {'failure-domain.beta.kubernetes.io/region': 'us-east-1'},
|
|
'old': {'failure-domain.beta.kubernetes.io/region': 'us-west-1'},
|
|
}
|
|
},
|
|
'result': True,
|
|
'name': 'failure-domain.beta.kubernetes.io/region',
|
|
'comment': 'The label is already set, changing the value',
|
|
},
|
|
actual,
|
|
)
|
|
|
|
def test_node_label_absent__noop_test_true(self):
|
|
labels = self.make_node_labels()
|
|
with self.mock_func('node_labels', return_value=labels, test=True):
|
|
actual = kubernetes.node_label_absent(
|
|
name='non-existent-label',
|
|
node='minikube',
|
|
)
|
|
self.assertDictEqual(
|
|
{
|
|
'changes': {},
|
|
'result': None,
|
|
'name': 'non-existent-label',
|
|
'comment': 'The label does not exist',
|
|
},
|
|
actual
|
|
)
|
|
|
|
def test_node_label_absent__noop(self):
|
|
labels = self.make_node_labels()
|
|
with self.mock_func('node_labels', return_value=labels):
|
|
actual = kubernetes.node_label_absent(
|
|
name='non-existent-label',
|
|
node='minikube',
|
|
)
|
|
self.assertDictEqual(
|
|
{
|
|
'changes': {},
|
|
'result': True,
|
|
'name': 'non-existent-label',
|
|
'comment': 'The label does not exist',
|
|
},
|
|
actual
|
|
)
|
|
|
|
def test_node_label_absent__delete_test_true(self):
|
|
labels = self.make_node_labels()
|
|
with self.mock_func('node_labels', return_value=labels, test=True):
|
|
actual = kubernetes.node_label_absent(
|
|
name='failure-domain.beta.kubernetes.io/region',
|
|
node='minikube',
|
|
)
|
|
self.assertDictEqual(
|
|
{
|
|
'changes': {},
|
|
'result': None,
|
|
'name': 'failure-domain.beta.kubernetes.io/region',
|
|
'comment': 'The label is going to be deleted',
|
|
},
|
|
actual
|
|
)
|
|
|
|
def test_node_label_absent__delete(self):
|
|
node_data = self.make_node()
|
|
labels = node_data['metadata']['labels'].copy()
|
|
|
|
del node_data['metadata']['labels']['failure-domain.beta.kubernetes.io/region']
|
|
|
|
with self.mock_func('node_labels', return_value=labels):
|
|
with self.mock_func('node_remove_label', return_value=node_data):
|
|
actual = kubernetes.node_label_absent(
|
|
name='failure-domain.beta.kubernetes.io/region',
|
|
node='minikube',
|
|
)
|
|
self.assertDictEqual(
|
|
{
|
|
'result': True,
|
|
'changes': {
|
|
'kubernetes.node_label': {
|
|
'new': 'absent',
|
|
'old': 'present',
|
|
}
|
|
},
|
|
'comment': 'Label removed from node',
|
|
'name': 'failure-domain.beta.kubernetes.io/region',
|
|
},
|
|
actual
|
|
)
|
|
|
|
def test_namespace_present__create_test_true(self):
|
|
with self.mock_func('show_namespace', return_value=None, test=True):
|
|
actual = kubernetes.namespace_present(name='saltstack')
|
|
self.assertDictEqual(
|
|
{
|
|
'changes': {},
|
|
'result': None,
|
|
'name': 'saltstack',
|
|
'comment': 'The namespace is going to be created',
|
|
},
|
|
actual
|
|
)
|
|
|
|
def test_namespace_present__create(self):
|
|
namespace_data = self.make_namespace(name='saltstack')
|
|
with self.mock_func('show_namespace', return_value=None):
|
|
with self.mock_func('create_namespace', return_value=namespace_data):
|
|
actual = kubernetes.namespace_present(name='saltstack')
|
|
self.assertDictEqual(
|
|
{
|
|
'changes': {
|
|
'namespace': {
|
|
'new': namespace_data,
|
|
'old': {},
|
|
},
|
|
},
|
|
'result': True,
|
|
'name': 'saltstack',
|
|
'comment': '',
|
|
},
|
|
actual
|
|
)
|
|
|
|
def test_namespace_present__noop_test_true(self):
|
|
namespace_data = self.make_namespace(name='saltstack')
|
|
with self.mock_func('show_namespace', return_value=namespace_data, test=True):
|
|
actual = kubernetes.namespace_present(name='saltstack')
|
|
self.assertDictEqual(
|
|
{
|
|
'changes': {},
|
|
'result': None,
|
|
'name': 'saltstack',
|
|
'comment': 'The namespace already exists',
|
|
},
|
|
actual
|
|
)
|
|
|
|
def test_namespace_present__noop(self):
|
|
namespace_data = self.make_namespace(name='saltstack')
|
|
with self.mock_func('show_namespace', return_value=namespace_data):
|
|
actual = kubernetes.namespace_present(name='saltstack')
|
|
self.assertDictEqual(
|
|
{
|
|
'changes': {},
|
|
'result': True,
|
|
'name': 'saltstack',
|
|
'comment': 'The namespace already exists',
|
|
},
|
|
actual
|
|
)
|
|
|
|
def test_namespace_absent__noop_test_true(self):
|
|
with self.mock_func('show_namespace', return_value=None, test=True):
|
|
actual = kubernetes.namespace_absent(name='salt')
|
|
self.assertDictEqual(
|
|
{
|
|
'changes': {},
|
|
'result': None,
|
|
'name': 'salt',
|
|
'comment': 'The namespace does not exist',
|
|
},
|
|
actual
|
|
)
|
|
|
|
def test_namespace_absent__noop(self):
|
|
with self.mock_func('show_namespace', return_value=None):
|
|
actual = kubernetes.namespace_absent(name='salt')
|
|
self.assertDictEqual(
|
|
{
|
|
'changes': {},
|
|
'result': True,
|
|
'name': 'salt',
|
|
'comment': 'The namespace does not exist',
|
|
},
|
|
actual
|
|
)
|
|
|
|
def test_namespace_absent__delete_test_true(self):
|
|
namespace_data = self.make_namespace(name='salt')
|
|
with self.mock_func('show_namespace', return_value=namespace_data, test=True):
|
|
actual = kubernetes.namespace_absent(name='salt')
|
|
self.assertDictEqual(
|
|
{
|
|
'changes': {},
|
|
'result': None,
|
|
'name': 'salt',
|
|
'comment': 'The namespace is going to be deleted',
|
|
},
|
|
actual
|
|
)
|
|
|
|
def test_namespace_absent__delete_code_200(self):
|
|
namespace_data = self.make_namespace(name='salt')
|
|
deleted = namespace_data.copy()
|
|
deleted['code'] = 200
|
|
deleted.update({
|
|
'code': 200,
|
|
'message': None,
|
|
})
|
|
with self.mock_func('show_namespace', return_value=namespace_data):
|
|
with self.mock_func('delete_namespace', return_value=deleted):
|
|
actual = kubernetes.namespace_absent(name='salt')
|
|
self.assertDictEqual(
|
|
{
|
|
'changes': {
|
|
'kubernetes.namespace': {
|
|
'new': 'absent',
|
|
'old': 'present',
|
|
}
|
|
},
|
|
'result': True,
|
|
'name': 'salt',
|
|
'comment': 'Terminating',
|
|
},
|
|
actual
|
|
)
|
|
|
|
def test_namespace_absent__delete_status_terminating(self):
|
|
namespace_data = self.make_namespace(name='salt')
|
|
deleted = namespace_data.copy()
|
|
deleted.update({
|
|
'code': None,
|
|
'status': 'Terminating namespace',
|
|
'message': 'Terminating this shizzzle yo',
|
|
})
|
|
with self.mock_func('show_namespace', return_value=namespace_data):
|
|
with self.mock_func('delete_namespace', return_value=deleted):
|
|
actual = kubernetes.namespace_absent(name='salt')
|
|
self.assertDictEqual(
|
|
{
|
|
'changes': {
|
|
'kubernetes.namespace': {
|
|
'new': 'absent',
|
|
'old': 'present',
|
|
}
|
|
},
|
|
'result': True,
|
|
'name': 'salt',
|
|
'comment': 'Terminating this shizzzle yo',
|
|
},
|
|
actual
|
|
)
|
|
|
|
def test_namespace_absent__delete_status_phase_terminating(self):
|
|
# This is what kubernetes 1.8.0 looks like when deleting namespaces
|
|
namespace_data = self.make_namespace(name='salt')
|
|
deleted = namespace_data.copy()
|
|
deleted.update({
|
|
'code': None,
|
|
'message': None,
|
|
'status': {'phase': 'Terminating'},
|
|
})
|
|
with self.mock_func('show_namespace', return_value=namespace_data):
|
|
with self.mock_func('delete_namespace', return_value=deleted):
|
|
actual = kubernetes.namespace_absent(name='salt')
|
|
self.assertDictEqual(
|
|
{
|
|
'changes': {
|
|
'kubernetes.namespace': {
|
|
'new': 'absent',
|
|
'old': 'present',
|
|
}
|
|
},
|
|
'result': True,
|
|
'name': 'salt',
|
|
'comment': 'Terminating',
|
|
},
|
|
actual
|
|
)
|
|
|
|
def test_namespace_absent__delete_error(self):
|
|
namespace_data = self.make_namespace(name='salt')
|
|
deleted = namespace_data.copy()
|
|
deleted.update({
|
|
'code': 418,
|
|
'message': 'I\' a teapot!',
|
|
'status': None,
|
|
})
|
|
with self.mock_func('show_namespace', return_value=namespace_data):
|
|
with self.mock_func('delete_namespace', return_value=deleted):
|
|
actual = kubernetes.namespace_absent(name='salt')
|
|
self.assertDictEqual(
|
|
{
|
|
'changes': {},
|
|
'result': False,
|
|
'name': 'salt',
|
|
'comment': 'Something went wrong, response: {0}'.format(
|
|
deleted,
|
|
),
|
|
},
|
|
actual
|
|
)
|