summaryrefslogtreecommitdiffstats
path: root/roles/lib_openshift/library/oc_adm_router.py
diff options
context:
space:
mode:
authorKenny Woodson <kwoodson@redhat.com>2017-02-17 15:11:51 -0500
committerKenny Woodson <kwoodson@redhat.com>2017-02-20 16:13:40 -0500
commit35583f57c71db5b181d0eaefc0bfc620c3790535 (patch)
treec86e81b33792c3322c49145923e0f82491e80052 /roles/lib_openshift/library/oc_adm_router.py
parent89ef5753535918a17a16c22c7bca56054229514f (diff)
downloadopenshift-35583f57c71db5b181d0eaefc0bfc620c3790535.tar.gz
openshift-35583f57c71db5b181d0eaefc0bfc620c3790535.tar.bz2
openshift-35583f57c71db5b181d0eaefc0bfc620c3790535.tar.xz
openshift-35583f57c71db5b181d0eaefc0bfc620c3790535.zip
Renamed modules, fixed docs, renamed variables, and cleaned up logic.
Diffstat (limited to 'roles/lib_openshift/library/oc_adm_router.py')
-rw-r--r--roles/lib_openshift/library/oc_adm_router.py190
1 files changed, 104 insertions, 86 deletions
diff --git a/roles/lib_openshift/library/oc_adm_router.py b/roles/lib_openshift/library/oc_adm_router.py
index 3f0fe5c46..1ee92fad5 100644
--- a/roles/lib_openshift/library/oc_adm_router.py
+++ b/roles/lib_openshift/library/oc_adm_router.py
@@ -54,7 +54,7 @@ from ansible.module_utils.basic import AnsibleModule
DOCUMENTATION = '''
---
-module: oadm_router
+module: oc_adm_router
short_description: Module to manage openshift router
description:
- Manage openshift router programmatically.
@@ -94,12 +94,6 @@ options:
required: false
default: default
aliases: []
- credentials:
- description:
- - Path to a .kubeconfig file that will contain the credentials the registry should use to contact the master.
- required: false
- default: None
- aliases: []
images:
description:
- The image to base this router on - ${component} will be replaced with --type
@@ -210,7 +204,31 @@ options:
aliases: []
author:
- "Kenny Woodson <kwoodson@redhat.com>"
-extends_documentation_fragment: []
+extends_documentation_fragment:
+- There are some exceptions to note when doing the idempotency in this module.
+- The strategy is to use the oc adm router command to generate a default
+- configuration when creating or updating a router. Often times there
+- differences from the generated template and what is in memory in openshift.
+- We make exceptions to not check these specific values when comparing objects.
+- Here are a list of exceptions:
+- - DeploymentConfig:
+ - dnsPolicy
+ - terminationGracePeriodSeconds
+ - restartPolicy
+ - timeoutSeconds
+ - livenessProbe
+ - readinessProbe
+ - terminationMessagePath
+ - hostPort
+ - defaultMode
+ - Service:
+ - portalIP
+ - clusterIP
+ - sessionAffinity
+ - type
+ - ServiceAccount:
+ - secrets
+ - imagePullSecrets
'''
EXAMPLES = '''
@@ -235,10 +253,10 @@ EXAMPLES = '''
action: put
- key: spec.template.spec.containers[0].resources.limits.memory
value: 2G
- action: update
+ action: put
- key: spec.template.spec.containers[0].resources.requests.memory
value: 1G
- action: update
+ action: put
- key: spec.template.spec.containers[0].env
value:
name: EXTENDED_VALIDATION
@@ -1067,7 +1085,7 @@ class OpenShiftCLI(object):
stdout, stderr = proc.communicate(input_data)
- return proc.returncode, stdout, stderr
+ return proc.returncode, stdout.decode(), stderr.decode()
# pylint: disable=too-many-arguments,too-many-branches
def openshift_cmd(self, cmd, oadm=False, output=False, output_type='json', input_data=None):
@@ -1552,7 +1570,7 @@ class Service(Yedit):
# pylint: disable=too-many-public-methods
class DeploymentConfig(Yedit):
- ''' Class to wrap the oc command line tools '''
+ ''' Class to model an openshift DeploymentConfig'''
default_deployment_config = '''
apiVersion: v1
kind: DeploymentConfig
@@ -1907,7 +1925,7 @@ class ServiceAccountConfig(object):
self.create_dict()
def create_dict(self):
- ''' return a properly structured volume '''
+ ''' instantiate a properly structured volume '''
self.data['apiVersion'] = 'v1'
self.data['kind'] = 'ServiceAccount'
self.data['metadata'] = {}
@@ -2040,7 +2058,7 @@ class SecretConfig(object):
self.create_dict()
def create_dict(self):
- ''' return a secret as a dict '''
+ ''' instantiate a secret as a dict '''
self.data['apiVersion'] = 'v1'
self.data['kind'] = 'Secret'
self.data['metadata'] = {}
@@ -2124,19 +2142,19 @@ class Secret(Yedit):
# pylint: disable=too-many-instance-attributes
class RoleBindingConfig(object):
- ''' Handle route options '''
+ ''' Handle rolebinding config '''
# pylint: disable=too-many-arguments
def __init__(self,
- sname,
+ name,
namespace,
kubeconfig,
group_names=None,
role_ref=None,
subjects=None,
usernames=None):
- ''' constructor for handling route options '''
+ ''' constructor for handling rolebinding options '''
self.kubeconfig = kubeconfig
- self.name = sname
+ self.name = name
self.namespace = namespace
self.group_names = group_names
self.role_ref = role_ref
@@ -2147,7 +2165,7 @@ class RoleBindingConfig(object):
self.create_dict()
def create_dict(self):
- ''' return a service as a dict '''
+ ''' create a default rolebinding as a dict '''
self.data['apiVersion'] = 'v1'
self.data['kind'] = 'RoleBinding'
self.data['groupNames'] = self.group_names
@@ -2161,7 +2179,7 @@ class RoleBindingConfig(object):
# pylint: disable=too-many-instance-attributes,too-many-public-methods
class RoleBinding(Yedit):
- ''' Class to wrap the oc command line tools '''
+ ''' Class to model a rolebinding openshift object'''
group_names_path = "groupNames"
role_ref_path = "roleRef"
subjects_path = "subjects"
@@ -2422,7 +2440,9 @@ class Router(OpenShiftCLI):
a router consists of 3 or more parts
- dc/router
- svc/router
- - endpoint/router
+ - sa/router
+ - secret/router-certs
+ - clusterrolebinding/router-router-role
'''
super(Router, self).__init__('default', router_config.kubeconfig, verbose)
self.config = router_config
@@ -2432,32 +2452,30 @@ class Router(OpenShiftCLI):
{'kind': 'sa', 'name': self.config.config_options['service_account']['value']},
{'kind': 'secret', 'name': self.config.name + '-certs'},
{'kind': 'clusterrolebinding', 'name': 'router-' + self.config.name + '-role'},
- #{'kind': 'endpoints', 'name': self.config.name},
]
- self.__router_prep = None
+ self.__prepared_router = None
self.dconfig = None
self.svc = None
self._secret = None
self._serviceaccount = None
self._rolebinding = None
- self.get()
@property
- def router_prep(self):
- ''' property deploymentconfig'''
- if self.__router_prep == None:
- results = self.prepare_router()
+ def prepared_router(self):
+ ''' property for the prepared router'''
+ if self.__prepared_router == None:
+ results = self._prepare_router()
if not results:
raise RouterException('Could not perform router preparation')
- self.__router_prep = results
+ self.__prepared_router = results
- return self.__router_prep
+ return self.__prepared_router
- @router_prep.setter
- def router_prep(self, obj):
- '''set the router prep property'''
- self.__router_prep = obj
+ @prepared_router.setter
+ def prepared_router(self, obj):
+ '''setter for the prepared_router'''
+ self.__prepared_router = obj
@property
def deploymentconfig(self):
@@ -2471,7 +2489,7 @@ class Router(OpenShiftCLI):
@property
def service(self):
- ''' property service '''
+ ''' property for service '''
return self.svc
@service.setter
@@ -2491,12 +2509,12 @@ class Router(OpenShiftCLI):
@property
def serviceaccount(self):
- ''' property secret '''
+ ''' property for serviceaccount '''
return self._serviceaccount
@serviceaccount.setter
def serviceaccount(self, config):
- ''' setter for property secret '''
+ ''' setter for property serviceaccount '''
self._serviceaccount = config
@property
@@ -2574,7 +2592,7 @@ class Router(OpenShiftCLI):
return deploymentconfig
- def prepare_router(self):
+ def _prepare_router(self):
'''prepare router for instantiation'''
# We need to create the pem file
router_pem = '/tmp/router.pem'
@@ -2600,11 +2618,11 @@ class Router(OpenShiftCLI):
if results['returncode'] != 0 and results['results'].has_key('items'):
return results
- oc_objects = {'DeploymentConfig': {'obj': None, 'path': None},
- 'Secret': {'obj': None, 'path': None},
- 'ServiceAccount': {'obj': None, 'path': None},
- 'ClusterRoleBinding': {'obj': None, 'path': None},
- 'Service': {'obj': None, 'path': None},
+ oc_objects = {'DeploymentConfig': {'obj': None, 'path': None, 'update': False},
+ 'Secret': {'obj': None, 'path': None, 'update': False},
+ 'ServiceAccount': {'obj': None, 'path': None, 'update': False},
+ 'ClusterRoleBinding': {'obj': None, 'path': None, 'update': False},
+ 'Service': {'obj': None, 'path': None, 'update': False},
}
# pylint: disable=invalid-sequence-index
for res in results['results']['items']:
@@ -2624,7 +2642,7 @@ class Router(OpenShiftCLI):
if not oc_objects['DeploymentConfig']['obj']:
return results
- # results will need to get parsed here and modifications added
+ # add modifications added
oc_objects['DeploymentConfig']['obj'] = self.add_modifications(oc_objects['DeploymentConfig']['obj'])
for oc_type in oc_objects.keys():
@@ -2634,11 +2652,8 @@ class Router(OpenShiftCLI):
def create(self):
'''Create a deploymentconfig '''
- # generate the objects and prepare for instantiation
- self.prepare_router()
-
results = []
- for _, oc_data in self.router_prep.items():
+ for _, oc_data in self.prepared_router.items():
results.append(self._create(oc_data['path']))
rval = 0
@@ -2649,21 +2664,18 @@ class Router(OpenShiftCLI):
return {'returncode': rval, 'results': results}
def update(self):
- '''run update for the router. This performs a delete and then create '''
- parts = self.delete()
- for part in parts:
- if part['returncode'] != 0:
- if part.has_key('stderr') and 'not found' in part['stderr']:
- # the object is not there, continue
- continue
-
- # something went wrong
- return parts
+ '''run update for the router. This performs a replace'''
+ results = []
+ for _, oc_data in self.prepared_router.items():
+ if oc_data['update']:
+ results.append(self._replace(oc_data['path']))
- # Ugly built in sleep here.
- time.sleep(15)
+ rval = 0
+ for result in results:
+ if result['returncode'] != 0:
+ rval = result['returncode']
- return self.create()
+ return {'returncode': rval, 'results': results}
# pylint: disable=too-many-return-statements,too-many-branches
def needs_update(self):
@@ -2671,64 +2683,58 @@ class Router(OpenShiftCLI):
if not self.deploymentconfig or not self.service or not self.serviceaccount or not self.secret:
return True
- oc_objects_prep = self.prepare_router()
-
- # Since the output from oadm_router is returned as raw
- # we need to parse it. The first line is the stats_password in 3.1
- # Inside of 3.2, it is just json
-
# ServiceAccount:
- # Need to determine the pregenerated ones from the original
+ # Need to determine changes from the pregenerated ones from the original
# Since these are auto generated, we can skip
skip = ['secrets', 'imagePullSecrets']
- if not Utils.check_def_equal(oc_objects_prep['ServiceAccount']['obj'].yaml_dict,
+ if not Utils.check_def_equal(self.prepared_router['ServiceAccount']['obj'].yaml_dict,
self.serviceaccount.yaml_dict,
skip_keys=skip,
debug=self.verbose):
- return True
+ self.prepared_router['ServiceAccount']['update'] = True
# Secret:
- # In 3.2 oadm router generates a secret volume for certificates
# See if one was generated from our dry-run and verify it if needed
- if oc_objects_prep['Secret']['obj']:
+ if self.prepared_router['Secret']['obj']:
if not self.secret:
- return True
- if not Utils.check_def_equal(oc_objects_prep['Secret']['obj'].yaml_dict,
+ self.prepared_router['Secret']['update'] = True
+
+ if not Utils.check_def_equal(self.prepared_router['Secret']['obj'].yaml_dict,
self.secret.yaml_dict,
skip_keys=skip,
debug=self.verbose):
- return True
+ self.prepared_router['Secret']['update'] = True
# Service:
# Fix the ports to have protocol=TCP
- for port in oc_objects_prep['Service']['obj'].get('spec.ports'):
+ for port in self.prepared_router['Service']['obj'].get('spec.ports'):
port['protocol'] = 'TCP'
skip = ['portalIP', 'clusterIP', 'sessionAffinity', 'type']
- if not Utils.check_def_equal(oc_objects_prep['Service']['obj'].yaml_dict,
+ if not Utils.check_def_equal(self.prepared_router['Service']['obj'].yaml_dict,
self.service.yaml_dict,
skip_keys=skip,
debug=self.verbose):
- return True
+ self.prepared_router['Service']['update'] = True
# DeploymentConfig:
# Router needs some exceptions.
# We do not want to check the autogenerated password for stats admin
if not self.config.config_options['stats_password']['value']:
- for idx, env_var in enumerate(oc_objects_prep['DeploymentConfig']['obj'].get(\
+ for idx, env_var in enumerate(self.prepared_router['DeploymentConfig']['obj'].get(\
'spec.template.spec.containers[0].env') or []):
if env_var['name'] == 'STATS_PASSWORD':
env_var['value'] = \
self.deploymentconfig.get('spec.template.spec.containers[0].env[%s].value' % idx)
break
- # dry-run doesn't add the protocol to the ports section. We will manually do that.
- for idx, port in enumerate(oc_objects_prep['DeploymentConfig']['obj'].get(\
+ # dry-run doesn't add the protocol to the ports section. We will manually do that.
+ for idx, port in enumerate(self.prepared_router['DeploymentConfig']['obj'].get(\
'spec.template.spec.containers[0].ports') or []):
if not port.has_key('protocol'):
port['protocol'] = 'TCP'
- # These are different when generating
+ # These are different when generating
skip = ['dnsPolicy',
'terminationGracePeriodSeconds',
'restartPolicy', 'timeoutSeconds',
@@ -2737,11 +2743,15 @@ class Router(OpenShiftCLI):
'defaultMode',
]
- return not Utils.check_def_equal(oc_objects_prep['DeploymentConfig']['obj'].yaml_dict,
+ if not Utils.check_def_equal(self.prepared_router['DeploymentConfig']['obj'].yaml_dict,
self.deploymentconfig.yaml_dict,
skip_keys=skip,
- debug=self.verbose)
+ debug=self.verbose):
+ self.prepared_router['DeploymentConfig']['update'] = True
+ # Check if any of the parts need updating, if so, return True
+ # else, no need to update
+ return any([self.prepared_router[oc_type]['update'] for oc_type in self.prepared_router.keys()])
@staticmethod
def run_ansible(params, check_mode):
@@ -2787,10 +2797,18 @@ class Router(OpenShiftCLI):
})
- ocrouter = Router(rconfig)
-
state = params['state']
+ ocrouter = Router(rconfig, verbose=params['debug'])
+
+ api_rval = ocrouter.get()
+
+ ########
+ # get
+ ########
+ if state == 'list':
+ return {'changed': False, 'results': api_rval, 'state': state}
+
########
# Delete
########