Example #1
0
def patch_rbac(rbac_v1: RbacAuthorizationV1Api,
               yaml_manifest) -> RBACAuthorization:
    """
    Patch a clusterrole and a binding.

    :param rbac_v1: RbacAuthorizationV1Api
    :param yaml_manifest: an absolute path to yaml manifest
    :return: RBACAuthorization
    """
    with open(yaml_manifest) as f:
        docs = yaml.safe_load_all(f)
        role_name = ""
        binding_name = ""
        for dep in docs:
            if dep["kind"] == "ClusterRole":
                print("Patch the cluster role")
                role_name = dep['metadata']['name']
                rbac_v1.patch_cluster_role(role_name, dep)
                print(f"Patched the role '{role_name}'")
            elif dep["kind"] == "ClusterRoleBinding":
                print("Patch the binding")
                binding_name = dep['metadata']['name']
                rbac_v1.patch_cluster_role_binding(binding_name, dep)
                print(f"Patched the binding '{binding_name}'")
        return RBACAuthorization(role_name, binding_name)
def create_role_binding(api: client.RbacAuthorizationV1Api,
                        configmap: Resource, cro_spec: ResourceChunk, ns: str,
                        name_suffix: str, logger: logging.Logger):
    role_bind_name = cro_spec.get("role", {}).get("bind")
    if not role_bind_name:
        tpl = yaml.safe_load(configmap.data['chaostoolkit-role-binding.yaml'])
        role_binding_name = tpl["metadata"]["name"]
        role_binding_name = f"{role_binding_name}-{name_suffix}"
        tpl["metadata"]["name"] = role_binding_name

        # change sa subject name
        sa_name = tpl["subjects"][0]["name"]
        sa_name = f"{sa_name}-{name_suffix}"
        tpl["subjects"][0]["name"] = sa_name

        # change role name
        role_name = tpl["roleRef"]["name"]
        role_name = f"{role_name}-{name_suffix}"
        tpl["roleRef"]["name"] = role_name

        set_ns(tpl, ns)
        try:
            api.create_namespaced_role_binding(body=tpl, namespace=ns)
            return tpl
        except ApiException as e:
            if e.status == 409:
                logger.info(
                    f"Role binding '{role_binding_name}' already exists.")
            else:
                raise kopf.PermanentError(
                    f"Failed to bind to role: {str(e)}")
Example #3
0
def create_role(api: client.RbacAuthorizationV1Api, configmap: Resource,
                cro_spec: ResourceChunk, ns: str, name_suffix: str,
                psp: client.PolicyV1beta1PodSecurityPolicy = None):
    logger = logging.getLogger('kopf.objects')
    role_name = cro_spec.get("role", {}).get("name")
    if not role_name:
        tpl = yaml.safe_load(configmap.data['chaostoolkit-role.yaml'])
        role_name = tpl["metadata"]["name"]
        role_name = f"{role_name}-{name_suffix}"
        tpl["metadata"]["name"] = role_name
        set_ns(tpl, ns)

        # when a PSP is defined, we add a rule to use that PSP
        if psp:
            logger.info(
                f"Adding pod security policy {psp.metadata.name} use to role")
            psp_rule = yaml.safe_load(
                configmap.data['chaostoolkit-role-psp-rule.yaml'])

            set_rule_psp_name(psp_rule, psp.metadata.name)
            tpl["rules"].append(psp_rule)

        logger.debug(f"Creating role with template:\n{tpl}")
        try:
            api.create_namespaced_role(body=tpl, namespace=ns)
            return tpl
        except ApiException as e:
            if e.status == 409:
                logger.info(f"Role '{role_name}' already exists.")
            else:
                raise kopf.PermanentError(
                    f"Failed to create role: {str(e)}")
def cleanup_rbac(rbac_v1: RbacAuthorizationV1Api, rbac: RBACAuthorization) -> None:
    """
    Delete binding and cluster role.

    :param rbac_v1: RbacAuthorizationV1Api
    :param rbac: RBACAuthorization
    :return:
    """
    print("Delete binding and cluster role")
    rbac_v1.delete_cluster_role_binding(rbac.binding)
    rbac_v1.delete_cluster_role(rbac.role)
Example #5
0
def create_role_binding(api: client.RbacAuthorizationV1Api,
                        configmap: Resource, cro_spec: ResourceChunk, ns: str,
                        name_suffix: str):
    logger = logging.getLogger('kopf.objects')
    role_bind_name = cro_spec.get("role", {}).get("bind")
    cluster_role_bind_namespaces = cro_spec.get("clusterRoleBindNamespaces",
                                                [])
    if not role_bind_name:
        tpl = yaml.safe_load(configmap.data['chaostoolkit-role-binding.yaml'])
        role_binding_name = tpl["metadata"]["name"]
        role_binding_name = f"{role_binding_name}-{name_suffix}"
        tpl["metadata"]["name"] = role_binding_name

        # change sa subject name
        sa_name = tpl["subjects"][0]["name"]
        sa_name = f"{sa_name}-{name_suffix}"
        tpl["subjects"][0]["name"] = sa_name

        # change sa subject namespace
        tpl["subjects"][0]["namespace"] = ns

        # change role name
        role_name = tpl["roleRef"]["name"]
        role_name = f"{role_name}-{name_suffix}"
        tpl["roleRef"]["name"] = role_name

        logger.debug(f"Creating role binding with template:\n{tpl}")

        if len(cluster_role_bind_namespaces) > 0:
            cluster_tpl = tpl
            for namespace in cluster_role_bind_namespaces:
                set_ns(cluster_tpl, namespace)
                try:
                    api.create_namespaced_role_binding(body=cluster_tpl,
                                                       namespace=namespace)
                except ApiException as e:
                    if e.status == 409:
                        logger.info(f"Role binding '{role_binding_name}' \
                                      already exists in {namespace}.")
                    else:
                        raise kopf.PermanentError(
                            f"Failed to bind to role: {str(e)}")

        set_ns(tpl, ns)
        try:
            api.create_namespaced_role_binding(body=tpl, namespace=ns)
            return tpl
        except ApiException as e:
            if e.status == 409:
                logger.info(
                    f"Role binding '{role_binding_name}' already exists.")
            else:
                raise kopf.PermanentError(f"Failed to bind to role: {str(e)}")
def cleanup_rbac(rbac_v1: RbacAuthorizationV1Api, rbac: RBACAuthorization) -> None:
    """
    Delete binding and cluster role.

    :param rbac_v1: RbacAuthorizationV1Api
    :param rbac: RBACAuthorization
    :return:
    """
    delete_options = client.V1DeleteOptions()
    print("Delete binding and cluster role")
    rbac_v1.delete_cluster_role_binding(rbac.binding, delete_options)
    rbac_v1.delete_cluster_role(rbac.role, delete_options)
Example #7
0
 def get_rbacauthorization_v1_api(self):
     """
     RbacAuthorizationV1Api
     :return:
     """
     client = self.get_api_client()
     rbacauthorization_v1_api = RbacAuthorizationV1Api(client)
     return rbacauthorization_v1_api
Example #8
0
def create_role(api: client.RbacAuthorizationV1Api, configmap: Resource,
                cro_spec: ResourceChunk, ns: str, name_suffix: str):
    logger = logging.getLogger('kopf.objects')
    role_name = cro_spec.get("role", {}).get("name")
    if not role_name:
        tpl = yaml.safe_load(configmap.data['chaostoolkit-role.yaml'])
        role_name = tpl["metadata"]["name"]
        role_name = f"{role_name}-{name_suffix}"
        tpl["metadata"]["name"] = role_name
        set_ns(tpl, ns)
        logger.debug(f"Creating role with template:\n{tpl}")
        try:
            api.create_namespaced_role(body=tpl, namespace=ns)
            return tpl
        except ApiException as e:
            if e.status == 409:
                logger.info(f"Role '{role_name}' already exists.")
            else:
                raise kopf.PermanentError(f"Failed to create role: {str(e)}")
 def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     load_k8s_config()
     rbac_api = kwargs.pop("rbac_api", None)
     if not rbac_api:
         rbac_api = RbacAuthorizationV1Api()
     self.rbac_api = rbac_api
     api = kwargs.pop("api", None)
     if not api:
         api = CoreV1Api()
     self.api = api
def configure_rbac_with_ap(rbac_v1: RbacAuthorizationV1Api) -> RBACAuthorization:
    """
    Create cluster and binding for AppProtect module.
    :param rbac_v1: RbacAuthorizationV1Api
    :return: RBACAuthorization
    """
    with open(f"{DEPLOYMENTS}/rbac/ap-rbac.yaml") as f:
        docs = yaml.safe_load_all(f)
        role_name = ""
        binding_name = ""
        for dep in docs:
            if dep["kind"] == "ClusterRole":
                print("Create cluster role for AppProtect")
                role_name = dep["metadata"]["name"]
                rbac_v1.create_cluster_role(dep)
                print(f"Created role '{role_name}'")
            elif dep["kind"] == "ClusterRoleBinding":
                print("Create binding for AppProtect")
                binding_name = dep["metadata"]["name"]
                rbac_v1.create_cluster_role_binding(dep)
                print(f"Created binding '{binding_name}'")
        return RBACAuthorization(role_name, binding_name)
Example #11
0
def configure_rbac(rbac_v1: RbacAuthorizationV1Api) -> RBACAuthorization:
    """
    Create cluster and binding.

    :param rbac_v1: RbacAuthorizationV1Api
    :return: RBACAuthorization
    """
    with open(f'{DEPLOYMENTS}/rbac/rbac.yaml') as f:
        docs = yaml.safe_load_all(f)
        role_name = ""
        binding_name = ""
        for dep in docs:
            if dep["kind"] == "ClusterRole":
                print("Create cluster role")
                role_name = dep['metadata']['name']
                rbac_v1.create_cluster_role(dep)
                print(f"Created role '{role_name}'")
            elif dep["kind"] == "ClusterRoleBinding":
                print("Create binding")
                binding_name = dep['metadata']['name']
                rbac_v1.create_cluster_role_binding(dep)
                print(f"Created binding '{binding_name}'")
        return RBACAuthorization(role_name, binding_name)
Example #12
0
def test_grb_crb_lifecycle(admin_mc, remove_resource):
    """Asserts that global role binding creation and deletion
    properly creates and deletes underlying cluster role binding"""
    admin_client = admin_mc.client

    # admin role is used because it requires an
    # additional cluster role bindig to be managed
    grb = admin_client.create_global_role_binding(groupPrincipalId="asd",
                                                  globalRoleId="admin")
    remove_resource

    cattle_grb = "cattle-globalrolebinding-" + grb.id
    admin_grb = "globaladmin-u-" + string_to_encoding("asd").lower()

    api_instance = RbacAuthorizationV1Api(admin_mc.k8s_client)

    def get_crb_by_id(id):
        def get_crb_from_k8s():
            try:
                return api_instance.read_cluster_role_binding(id)
            except ApiException as e:
                assert e.status == 404

        return get_crb_from_k8s

    k8s_grb = wait_for(get_crb_by_id(cattle_grb))
    assert k8s_grb.subjects[0].kind == "Group"
    assert k8s_grb.subjects[0].name == "asd"

    k8s_grb = wait_for(get_crb_by_id(admin_grb))
    assert k8s_grb.subjects[0].kind == "Group"
    assert k8s_grb.subjects[0].name == "asd"

    grb = admin_client.reload(grb)
    admin_client.delete(grb)

    def crb_deleted_by_id(id):
        def is_crb_deleted():
            try:
                api_instance.read_cluster_role_binding(id)
            except ApiException as e:
                return e.status == 404
            return False

        return is_crb_deleted

    wait_for(crb_deleted_by_id(cattle_grb))
    wait_for(crb_deleted_by_id(admin_grb))
Example #13
0
 def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     try:
         load_incluster_config()
     except ConfigException:
         self.log.warning("In-cluster config failed! Falling back.")
         try:
             load_kube_config()
         except ValueError as exc:
             self.log.error("Still errored: {}".format(exc))
     rbac_api = kwargs.pop('rbac_api', None)
     if not rbac_api:
         rbac_api = RbacAuthorizationV1Api()
     self.rbac_api = rbac_api
     api = kwargs.pop('api', None)
     if not api:
         api = CoreV1Api()
     self.api = api
Example #14
0
    def create_vnf(self, uuid, **params):

        v1 = CoreV1Api()
        namespaces = [ns.metadata.name for ns in v1.list_namespace().items]

        tenant = params["tenant"]
        if tenant not in namespaces:
            ns_file = open("/etc/lightmano/k8s/_internal/namespace.yaml")
            ns = ns_file.read()
            ns_file.close()
            ns = ns.replace("-NAME-", tenant)
            ns = yaml.safe_load(ns)
            v1.create_namespace(ns)

            rbac_api = RbacAuthorizationV1Api()

            role_file = open("/etc/lightmano/k8s/_internal/ns_role.yaml")
            role = role_file.read()
            role_file.close()
            role = yaml.safe_load(role)
            rbac_api.create_namespaced_role(namespace=tenant, body=role)

            rolebind_file = open(
                "/etc/lightmano/k8s/_internal/ns_role_binding.yaml")
            rolebinding = rolebind_file.read()
            rolebind_file.close()
            rolebinding = yaml.safe_load(rolebinding)
            rbac_api.create_namespaced_role_binding(namespace=tenant,
                                                    body=rolebinding)

        vnf = VNF(uuid, **params)

        handle_yaml(k8s_client=ApiClient(),
                    yaml_file=vnf.get_k8s_desc_file().name,
                    mode="create",
                    namespace=tenant)
        self.vnfs[uuid] = vnf
Example #15
0
lab_ui_label = f"{babylon_domain}/labUserInterface"
owner_annotation = f"{babylon_domain}/owner"
owner_uid_label = f"{babylon_domain}/owner-uid"
requester_annotation = f"{babylon_domain}/requester"
resource_claim_name_label = f"{poolboy_domain}/resource-claim-name"
resource_claim_namespace_label = f"{poolboy_domain}/resource-claim-namespace"

if os.path.exists('/run/secrets/kubernetes.io/serviceaccount'):
    kubernetes.config.load_incluster_config()
else:
    kubernetes.config.load_kube_config()

apps_v1_api = AppsV1Api()
core_v1_api = CoreV1Api()
custom_objects_api = CustomObjectsApi()
rbac_authorization_v1_api = RbacAuthorizationV1Api()

openshift_ingress_domain = custom_objects_api.get_cluster_custom_object(
    'config.openshift.io', 'v1', 'ingresses', 'cluster')['spec']['domain']


class BookbagBuild:
    def __init__(
        self,
        definition=None,
        name=None,
        namespace=None,
        spec=None,
        uid=None,
        **_,
    ):
Example #16
0
 def rbac_api(self) -> RbacAuthorizationV1Api:
     api_client = new_client_from_config(context=self.context())
     return RbacAuthorizationV1Api(api_client)