def main(): module = AnsibleModule(argument_spec=argspec(), supports_check_mode=True) if not HAS_K8S: module.fail_json(msg=missing_required_lib('kubernetes'), exception=K8S_IMP_EXC, error=to_native(K8S_IMP_ERR)) from ansible_collections.kubernetes.core.plugins.module_utils.common import get_api_client execute_module(module, client=get_api_client(module=module))
def main(): module = AnsibleModule(argument_spec=argspec()) if not HAS_EVICTION_API: module.fail_json( msg="The kubernetes Python library missing with V1Eviction API", exception=K8S_IMP_ERR, error=to_native(k8s_import_exception), ) k8s_drain = K8sDrainAnsible(module) k8s_drain.execute_module()
class OpenShiftRoute(K8sAnsibleMixin): def __init__(self): self.module = AnsibleModule( argument_spec=self.argspec, supports_check_mode=True, ) self.fail_json = self.module.fail_json if not HAS_KUBERNETES_COLLECTION: self.module.fail_json( msg="The kubernetes.core collection must be installed", exception=K8S_COLLECTION_ERROR, error=to_native(k8s_collection_import_exception)) super(OpenShiftRoute, self).__init__(self.module) self.params = self.module.params # TODO: should probably make it so that at least some of these aren't required for perform_action to work # Or at least explicitly pass them in self.append_hash = False self.apply = False self.check_mode = self.module.check_mode self.warnings = [] self.params['merge_type'] = None self.client = get_api_client(self.module) @property def argspec(self): spec = copy.deepcopy(AUTH_ARG_SPEC) spec.update(copy.deepcopy(WAIT_ARG_SPEC)) spec.update(copy.deepcopy(COMMON_ARG_SPEC)) spec['service'] = dict(type='str', aliases=['svc']) spec['namespace'] = dict(required=True, type='str') spec['labels'] = dict(type='dict') spec['name'] = dict(type='str') spec['hostname'] = dict(type='str') spec['path'] = dict(type='str') spec['wildcard_policy'] = dict(choices=['Subdomain'], type='str') spec['port'] = dict(type='str') spec['tls'] = dict(type='dict', options=dict( ca_certificate=dict(type='str'), certificate=dict(type='str'), destination_ca_certificate=dict(type='str'), key=dict(type='str', no_log=False), insecure_policy=dict( type='str', choices=['allow', 'redirect', 'disallow'], default='disallow'), )) spec['termination'] = dict( choices=['edge', 'passthrough', 'reencrypt', 'insecure'], default='insecure') spec['annotations'] = dict(type='dict') return spec def execute_module(self): v1_routes = self.find_resource('Route', 'route.openshift.io/v1', fail=True) service_name = self.params.get('service') namespace = self.params['namespace'] termination_type = self.params.get('termination') if termination_type == 'insecure': termination_type = None state = self.params.get('state') if state != 'absent' and not service_name: self.fail_json( "If 'state' is not 'absent' then 'service' must be provided") # We need to do something a little wonky to wait if the user doesn't supply a custom condition custom_wait = self.params.get('wait') and not self.params.get( 'wait_condition') and state != 'absent' if custom_wait: # Don't use default wait logic in perform_action self.params['wait'] = False route_name = self.params.get('name') or service_name labels = self.params.get('labels') hostname = self.params.get('hostname') path = self.params.get('path') wildcard_policy = self.params.get('wildcard_policy') port = self.params.get('port') annotations = self.params.get('annotations') if termination_type and self.params.get('tls'): tls_ca_cert = self.params['tls'].get('ca_certificate') tls_cert = self.params['tls'].get('certificate') tls_dest_ca_cert = self.params['tls'].get( 'destination_ca_certificate') tls_key = self.params['tls'].get('key') tls_insecure_policy = self.params['tls'].get('insecure_policy') if tls_insecure_policy == 'disallow': tls_insecure_policy = None else: tls_ca_cert = tls_cert = tls_dest_ca_cert = tls_key = tls_insecure_policy = None route = { 'apiVersion': 'route.openshift.io/v1', 'kind': 'Route', 'metadata': { 'name': route_name, 'namespace': namespace, 'labels': labels, }, 'spec': {} } if annotations: route['metadata']['annotations'] = annotations if state != 'absent': route['spec'] = self.build_route_spec( service_name, namespace, port=port, wildcard_policy=wildcard_policy, hostname=hostname, path=path, termination_type=termination_type, tls_insecure_policy=tls_insecure_policy, tls_ca_cert=tls_ca_cert, tls_cert=tls_cert, tls_key=tls_key, tls_dest_ca_cert=tls_dest_ca_cert, ) result = self.perform_action(v1_routes, route) timeout = self.params.get('wait_timeout') sleep = self.params.get('wait_sleep') if custom_wait: success, result['result'], result['duration'] = self._wait_for( v1_routes, route_name, namespace, wait_predicate, sleep, timeout, state) self.module.exit_json(**result) def build_route_spec(self, service_name, namespace, port=None, wildcard_policy=None, hostname=None, path=None, termination_type=None, tls_insecure_policy=None, tls_ca_cert=None, tls_cert=None, tls_key=None, tls_dest_ca_cert=None): v1_services = self.find_resource('Service', 'v1', fail=True) try: target_service = v1_services.get(name=service_name, namespace=namespace) except NotFoundError: if not port: self.module.fail_json( msg= "You need to provide the 'port' argument when exposing a non-existent service" ) target_service = None except DynamicApiError as exc: self.module.fail_json( msg='Failed to retrieve service to be exposed: {0}'.format( exc.body), error=exc.status, status=exc.status, reason=exc.reason) except Exception as exc: self.module.fail_json( msg='Failed to retrieve service to be exposed: {0}'.format( to_native(exc)), error='', status='', reason='') route_spec = { 'tls': {}, 'to': { 'kind': 'Service', 'name': service_name, }, 'port': { 'targetPort': self.set_port(target_service, port), }, 'wildcardPolicy': wildcard_policy } # Want to conditionally add these so we don't overwrite what is automically added when nothing is provided if termination_type: route_spec['tls'] = dict(termination=termination_type.capitalize()) if tls_insecure_policy: if termination_type == 'edge': route_spec['tls'][ 'insecureEdgeTerminationPolicy'] = tls_insecure_policy.capitalize( ) elif termination_type == 'passthrough': if tls_insecure_policy != 'redirect': self.module.fail_json( "'redirect' is the only supported insecureEdgeTerminationPolicy for passthrough routes" ) route_spec['tls'][ 'insecureEdgeTerminationPolicy'] = tls_insecure_policy.capitalize( ) elif termination_type == 'reencrypt': self.module.fail_json( "'tls.insecure_policy' is not supported with reencrypt routes" ) else: route_spec['tls']['insecureEdgeTerminationPolicy'] = None if tls_ca_cert: if termination_type == 'passthrough': self.module.fail_json( "'tls.ca_certificate' is not supported with passthrough routes" ) route_spec['tls']['caCertificate'] = tls_ca_cert if tls_cert: if termination_type == 'passthrough': self.module.fail_json( "'tls.certificate' is not supported with passthrough routes" ) route_spec['tls']['certificate'] = tls_cert if tls_key: if termination_type == 'passthrough': self.module.fail_json( "'tls.key' is not supported with passthrough routes") route_spec['tls']['key'] = tls_key if tls_dest_ca_cert: if termination_type != 'reencrypt': self.module.fail_json( "'destination_certificate' is only valid for reencrypt routes" ) route_spec['tls'][ 'destinationCACertificate'] = tls_dest_ca_cert else: route_spec['tls'] = None if hostname: route_spec['host'] = hostname if path: route_spec['path'] = path return route_spec def set_port(self, service, port_arg): if port_arg: return port_arg for p in service.spec.ports: if p.protocol == 'TCP': if p.name is not None: return p.name return p.targetPort return None