Task manager / scheduler Kubernetes integration

This commit is contained in:
Shane McDonald
2019-07-03 12:09:17 -04:00
parent a9059edc65
commit bd5003ca98
36 changed files with 1141 additions and 104 deletions

View File

@@ -203,6 +203,13 @@ def organization(instance):
return Organization.objects.create(name="test-org", description="test-org-desc")
@pytest.fixture
def credentialtype_kube():
kube = CredentialType.defaults['kubernetes_bearer_token']()
kube.save()
return kube
@pytest.fixture
def credentialtype_ssh():
ssh = CredentialType.defaults['ssh']()
@@ -336,6 +343,12 @@ def other_external_credential(credentialtype_external):
inputs={'url': 'http://testhost.com', 'token': 'secret2'})
@pytest.fixture
def kube_credential(credentialtype_kube):
return Credential.objects.create(credential_type=credentialtype_kube, name='kube-cred',
inputs={'host': 'my.cluster', 'bearer_token': 'my-token', 'verify_ssl': False})
@pytest.fixture
def inventory(organization):
return organization.inventories.create(name="test-inv")

View File

@@ -0,0 +1,56 @@
import subprocess
import yaml
import base64
from unittest import mock # noqa
import pytest
from awx.main.scheduler.kubernetes import PodManager
from awx.main.utils import (
create_temporary_fifo,
)
@pytest.fixture
def containerized_job(default_instance_group, kube_credential, job_template_factory):
default_instance_group.credential = kube_credential
default_instance_group.save()
objects = job_template_factory('jt', organization='org1', project='proj',
inventory='inv', credential='cred',
jobs=['my_job'])
jt = objects.job_template
jt.instance_groups.add(default_instance_group)
j1 = objects.jobs['my_job']
j1.instance_group = default_instance_group
j1.status = 'pending'
j1.save()
return j1
@pytest.mark.django_db
def test_containerized_job(containerized_job):
assert containerized_job.is_containerized
assert containerized_job.instance_group.is_containerized
assert containerized_job.instance_group.credential.kubernetes
@pytest.mark.django_db
def test_kubectl_ssl_verification(containerized_job):
cred = containerized_job.instance_group.credential
cred.inputs['verify_ssl'] = True
key_material = subprocess.run('openssl genrsa 2> /dev/null',
shell=True, check=True,
stdout=subprocess.PIPE)
key = create_temporary_fifo(key_material.stdout)
cmd = f"""
openssl req -x509 -sha256 -new -nodes \
-key {key} -subj '/C=US/ST=North Carolina/L=Durham/O=Ansible/OU=AWX Development/CN=awx.localhost'
"""
cert = subprocess.run(cmd.strip(), shell=True, check=True, stdout=subprocess.PIPE)
cred.inputs['ssl_ca_cert'] = cert.stdout
cred.save()
pm = PodManager(containerized_job)
config = yaml.load(open(pm.kube_config), Loader=yaml.FullLoader)
ca_data = config['clusters'][0]['cluster']['certificate-authority-data']
assert cert.stdout == base64.b64decode(ca_data.encode())

View File

@@ -87,6 +87,7 @@ def test_default_cred_types():
'hashivault_kv',
'hashivault_ssh',
'insights',
'kubernetes_bearer_token',
'net',
'openstack',
'rhv',

View File

@@ -0,0 +1,55 @@
import pytest
from unittest import mock
from django.conf import settings
from awx.main.models import (
InstanceGroup,
Job,
JobTemplate,
Project,
Inventory,
)
from awx.main.scheduler.kubernetes import PodManager
@pytest.fixture
def container_group():
instance_group = mock.Mock(InstanceGroup(name='container-group'))
return instance_group
@pytest.fixture
def job(container_group):
return Job(pk=1,
id=1,
project=Project(),
instance_group=container_group,
inventory=Inventory(),
job_template=JobTemplate(id=1, name='foo'))
def test_default_pod_spec(job):
default_image = PodManager(job).pod_definition['spec']['containers'][0]['image']
assert default_image == settings.AWX_CONTAINER_GROUP_DEFAULT_IMAGE
def test_custom_pod_spec(job):
job.instance_group.pod_spec_override = """
spec:
containers:
- image: my-custom-image
"""
custom_image = PodManager(job).pod_definition['spec']['containers'][0]['image']
assert custom_image == 'my-custom-image'
def test_pod_manager_namespace_property(job):
pm = PodManager(job)
assert pm.namespace == settings.AWX_CONTAINER_GROUP_DEFAULT_NAMESPACE
job.instance_group.pod_spec_override = """
metadata:
namespace: my-namespace
"""
assert PodManager(job).namespace == 'my-namespace'

View File

@@ -11,6 +11,7 @@ class FakeObject(object):
class Job(FakeObject):
task_impact = 43
is_containerized = False
def log_format(self):
return 'job 382 (fake)'