From 56c255275d95df6b6354a5f16a04a5f78dc18fc7 Mon Sep 17 00:00:00 2001 From: Hugo Shaka Date: Thu, 25 Jan 2024 15:13:00 -0500 Subject: [PATCH 1/2] Bakcport TeleportRoleV6 and V7 support --- .../resources.teleport.dev_accesslists.yaml | 1 + ...sources.teleport.dev_githubconnectors.yaml | 3 +- .../resources.teleport.dev_loginrules.yaml | 1 + ...resources.teleport.dev_oidcconnectors.yaml | 3 +- ...esources.teleport.dev_oktaimportrules.yaml | 1 + ...esources.teleport.dev_provisiontokens.yaml | 3 +- .../resources.teleport.dev_roles.yaml | 4 +- .../resources.teleport.dev_rolesv6.yaml | 1221 +++++++++++++++++ .../resources.teleport.dev_rolesv7.yaml | 1221 +++++++++++++++++ ...resources.teleport.dev_samlconnectors.yaml | 3 +- .../resources.teleport.dev_users.yaml | 2 +- .../teleport-operator/templates/role.yaml | 4 + .../{v6/groupversion_info.go => status.go} | 35 +- .../apis/resources/v1/accesslist_types.go | 12 +- .../apis/resources/v1/loginrule_types.go | 12 +- .../apis/resources/v1/okta_import_rule.go | 12 +- .../{v6/role_types.go => v1/rolev6_types.go} | 47 +- .../apis/resources/v1/rolev7_types.go | 95 ++ .../resources/v1/zz_generated.deepcopy.go | 175 ++- .../apis/resources/v2/provisiontoken_types.go | 13 +- .../apis/resources/v2/samlconnector_types.go | 13 +- .../operator/apis/resources/v2/user_types.go | 13 +- .../resources/v2/zz_generated.deepcopy.go | 67 - .../resources/v3/githubconnector_types.go | 13 +- .../apis/resources/v3/oidcconnector_types.go | 13 +- .../resources/v3/zz_generated.deepcopy.go | 45 - .../operator/apis/resources/v5/role_types.go | 13 +- .../resources/v5/zz_generated.deepcopy.go | 23 - .../resources/v6/zz_generated.deepcopy.go | 119 -- .../resources.teleport.dev_accesslists.yaml | 1 + ...sources.teleport.dev_githubconnectors.yaml | 3 +- .../resources.teleport.dev_loginrules.yaml | 1 + ...resources.teleport.dev_oidcconnectors.yaml | 3 +- ...esources.teleport.dev_oktaimportrules.yaml | 1 + ...esources.teleport.dev_provisiontokens.yaml | 3 +- .../bases/resources.teleport.dev_roles.yaml | 4 +- .../bases/resources.teleport.dev_rolesv6.yaml | 1221 +++++++++++++++++ .../bases/resources.teleport.dev_rolesv7.yaml | 1221 +++++++++++++++++ ...resources.teleport.dev_samlconnectors.yaml | 3 +- .../bases/resources.teleport.dev_users.yaml | 2 +- .../resources/accesslist_controller.go | 6 +- .../controllers/resources/base_reconciler.go | 41 +- .../resources/github_connector_controller.go | 6 +- .../operator/controllers/resources/global.go | 119 ++ .../resources/login_rule_controller.go | 6 +- .../resources/oidc_connector_controller.go | 6 +- .../resources/okta_import_rule_controller.go | 6 +- .../resources/provision_token_controller.go | 6 +- .../provision_token_controller_test.go | 3 +- .../controllers/resources/role_controller.go | 191 --- .../resources/role_controller_test.go | 65 +- .../resources/rolev6_controller_test.go | 146 ++ .../resources/rolev7_controller_test.go | 143 ++ .../resources/rolevX_controller.go | 104 ++ .../resources/saml_connector_controller.go | 6 +- .../resources/teleport_reconciler.go | 75 +- .../testlib/accesslist_controller_tests.go | 20 +- .../controllers/resources/testlib/env.go | 39 +- .../controllers/resources/user_controller.go | 6 +- .../resources/user_controller_test.go | 7 +- .../operator/controllers/resources/utils.go | 29 + .../controllers/resources/utils_test.go | 69 + integrations/operator/crdgen/handlerequest.go | 13 +- integrations/operator/crdgen/schemagen.go | 128 +- .../resources.teleport.dev_accesslists.yaml | 1 + ...sources.teleport.dev_githubconnectors.yaml | 3 +- .../resources.teleport.dev_loginrules.yaml | 1 + ...resources.teleport.dev_oidcconnectors.yaml | 3 +- ...esources.teleport.dev_oktaimportrules.yaml | 1 + ...esources.teleport.dev_provisiontokens.yaml | 3 +- .../golden/resources.teleport.dev_roles.yaml | 4 +- .../resources.teleport.dev_rolesv6.yaml | 1217 ++++++++++++++++ .../resources.teleport.dev_rolesv7.yaml | 1217 ++++++++++++++++ ...resources.teleport.dev_samlconnectors.yaml | 3 +- .../golden/resources.teleport.dev_users.yaml | 2 +- integrations/operator/main.go | 98 +- 76 files changed, 8513 insertions(+), 930 deletions(-) create mode 100644 examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_rolesv6.yaml create mode 100644 examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_rolesv7.yaml rename integrations/operator/apis/resources/{v6/groupversion_info.go => status.go} (50%) rename integrations/operator/apis/resources/{v6/role_types.go => v1/rolev6_types.go} (62%) create mode 100644 integrations/operator/apis/resources/v1/rolev7_types.go delete mode 100644 integrations/operator/apis/resources/v6/zz_generated.deepcopy.go create mode 100644 integrations/operator/config/crd/bases/resources.teleport.dev_rolesv6.yaml create mode 100644 integrations/operator/config/crd/bases/resources.teleport.dev_rolesv7.yaml create mode 100644 integrations/operator/controllers/resources/global.go delete mode 100644 integrations/operator/controllers/resources/role_controller.go create mode 100644 integrations/operator/controllers/resources/rolev6_controller_test.go create mode 100644 integrations/operator/controllers/resources/rolev7_controller_test.go create mode 100644 integrations/operator/controllers/resources/rolevX_controller.go create mode 100644 integrations/operator/crdgen/testdata/golden/resources.teleport.dev_rolesv6.yaml create mode 100644 integrations/operator/crdgen/testdata/golden/resources.teleport.dev_rolesv7.yaml diff --git a/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_accesslists.yaml b/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_accesslists.yaml index 6d10aac334e7e..2e6e599ceb9bb 100644 --- a/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_accesslists.yaml +++ b/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_accesslists.yaml @@ -201,6 +201,7 @@ spec: type: string type: object status: + description: Status defines the observed state of the Teleport resource properties: conditions: description: Conditions represent the latest available observations diff --git a/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_githubconnectors.yaml b/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_githubconnectors.yaml index a262e618b0154..b96d4eb6e8734 100644 --- a/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_githubconnectors.yaml +++ b/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_githubconnectors.yaml @@ -78,8 +78,7 @@ spec: type: array type: object status: - description: TeleportGithubConnectorStatus defines the observed state - of TeleportGithubConnector + description: Status defines the observed state of the Teleport resource properties: conditions: description: Conditions represent the latest available observations diff --git a/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_loginrules.yaml b/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_loginrules.yaml index cdb3a30050b51..7b5928ca4c255 100644 --- a/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_loginrules.yaml +++ b/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_loginrules.yaml @@ -57,6 +57,7 @@ spec: type: object type: object status: + description: Status defines the observed state of the Teleport resource properties: conditions: description: Conditions represent the latest available observations diff --git a/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_oidcconnectors.yaml b/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_oidcconnectors.yaml index edd8bf5e13623..087bdc7d4a4b1 100644 --- a/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_oidcconnectors.yaml +++ b/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_oidcconnectors.yaml @@ -123,8 +123,7 @@ spec: type: string type: object status: - description: TeleportOIDCConnectorStatus defines the observed state of - TeleportOIDCConnector + description: Status defines the observed state of the Teleport resource properties: conditions: description: Conditions represent the latest available observations diff --git a/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_oktaimportrules.yaml b/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_oktaimportrules.yaml index b16ac422df459..f6077e45c357f 100644 --- a/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_oktaimportrules.yaml +++ b/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_oktaimportrules.yaml @@ -95,6 +95,7 @@ spec: type: integer type: object status: + description: Status defines the observed state of the Teleport resource properties: conditions: description: Conditions represent the latest available observations diff --git a/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_provisiontokens.yaml b/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_provisiontokens.yaml index 25220e897f131..4aac7487fb0ef 100644 --- a/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_provisiontokens.yaml +++ b/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_provisiontokens.yaml @@ -330,8 +330,7 @@ spec: type: object type: object status: - description: TeleportProvisionTokenStatus defines the observed state of - TeleportProvisionToken + description: Status defines the observed state of the Teleport resource properties: conditions: description: Conditions represent the latest available observations diff --git a/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_roles.yaml b/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_roles.yaml index d80e41f657dc0..810caf4cd4861 100644 --- a/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_roles.yaml +++ b/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_roles.yaml @@ -1128,7 +1128,7 @@ spec: type: object type: object status: - description: TeleportRoleStatus defines the observed state of TeleportRole + description: Status defines the observed state of the Teleport resource properties: conditions: description: Conditions represent the latest available observations @@ -2326,7 +2326,7 @@ spec: type: object type: object status: - description: TeleportRoleStatus defines the observed state of TeleportRole + description: Status defines the observed state of the Teleport resource properties: conditions: description: Conditions represent the latest available observations diff --git a/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_rolesv6.yaml b/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_rolesv6.yaml new file mode 100644 index 0000000000000..ff98950361a89 --- /dev/null +++ b/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_rolesv6.yaml @@ -0,0 +1,1221 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + name: teleportrolesv6.resources.teleport.dev +spec: + group: resources.teleport.dev + names: + kind: TeleportRoleV6 + listKind: TeleportRoleV6List + plural: teleportrolesv6 + shortNames: + - rolev6 + - rolesv6 + singular: teleportrolev6 + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: RoleV6 is the Schema for the rolesv6 API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Role resource definition v6 from Teleport + properties: + allow: + description: Allow is the set of conditions evaluated to grant access. + properties: + app_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: AppLabels is a map of labels used as part of the + RBAC system. + type: object + app_labels_expression: + description: AppLabelsExpression is a predicate expression used + to allow/deny access to Apps. + type: string + aws_role_arns: + description: AWSRoleARNs is a list of AWS role ARNs this role + is allowed to assume. + items: + type: string + nullable: true + type: array + azure_identities: + description: AzureIdentities is a list of Azure identities this + role is allowed to assume. + items: + type: string + nullable: true + type: array + cluster_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: ClusterLabels is a map of node labels (used to dynamically + grant access to clusters). + type: object + cluster_labels_expression: + description: ClusterLabelsExpression is a predicate expression + used to allow/deny access to remote Teleport clusters. + type: string + db_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: DatabaseLabels are used in RBAC system to allow/deny + access to databases. + type: object + db_labels_expression: + description: DatabaseLabelsExpression is a predicate expression + used to allow/deny access to Databases. + type: string + db_names: + description: DatabaseNames is a list of database names this role + is allowed to connect to. + items: + type: string + nullable: true + type: array + db_roles: + description: DatabaseRoles is a list of databases roles for automatic + user creation. + items: + type: string + nullable: true + type: array + db_service_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: DatabaseServiceLabels are used in RBAC system to + allow/deny access to Database Services. + type: object + db_service_labels_expression: + description: DatabaseServiceLabelsExpression is a predicate expression + used to allow/deny access to Database Services. + type: string + db_users: + description: DatabaseUsers is a list of databases users this role + is allowed to connect as. + items: + type: string + nullable: true + type: array + desktop_groups: + description: DesktopGroups is a list of groups for created desktop + users to be added to + items: + type: string + nullable: true + type: array + gcp_service_accounts: + description: GCPServiceAccounts is a list of GCP service accounts + this role is allowed to assume. + items: + type: string + nullable: true + type: array + group_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: GroupLabels is a map of labels used as part of the + RBAC system. + type: object + group_labels_expression: + description: GroupLabelsExpression is a predicate expression used + to allow/deny access to user groups. + type: string + host_groups: + description: HostGroups is a list of groups for created users + to be added to + items: + type: string + nullable: true + type: array + host_sudoers: + description: HostSudoers is a list of entries to include in a + users sudoer file + items: + type: string + nullable: true + type: array + impersonate: + description: Impersonate specifies what users and roles this role + is allowed to impersonate by issuing certificates or other possible + means. + nullable: true + properties: + roles: + description: Roles is a list of resources this role is allowed + to impersonate + items: + type: string + nullable: true + type: array + users: + description: Users is a list of resources this role is allowed + to impersonate, could be an empty list or a Wildcard pattern + items: + type: string + nullable: true + type: array + where: + description: Where specifies optional advanced matcher + type: string + type: object + join_sessions: + description: JoinSessions specifies policies to allow users to + join other sessions. + items: + properties: + kinds: + description: Kinds are the session kinds this policy applies + to. + items: + type: string + nullable: true + type: array + modes: + description: Modes is a list of permitted participant modes + for this policy. + items: + type: string + nullable: true + type: array + name: + description: Name is the name of the policy. + type: string + roles: + description: Roles is a list of roles that you can join + the session of. + items: + type: string + nullable: true + type: array + type: object + nullable: true + type: array + kubernetes_groups: + description: KubeGroups is a list of kubernetes groups + items: + type: string + nullable: true + type: array + kubernetes_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: KubernetesLabels is a map of kubernetes cluster labels + used for RBAC. + type: object + kubernetes_labels_expression: + description: KubernetesLabelsExpression is a predicate expression + used to allow/deny access to kubernetes clusters. + type: string + kubernetes_resources: + description: KubernetesResources is the Kubernetes Resources this + Role grants access to. + items: + properties: + kind: + description: Kind specifies the Kubernetes Resource type. + At the moment only "pod" is supported. + type: string + name: + description: Name is the resource name. It supports wildcards. + type: string + namespace: + description: Namespace is the resource namespace. It supports + wildcards. + type: string + verbs: + description: Verbs are the allowed Kubernetes verbs for + the following resource. + items: + type: string + nullable: true + type: array + type: object + type: array + kubernetes_users: + description: KubeUsers is an optional kubernetes users to impersonate + items: + type: string + nullable: true + type: array + logins: + description: Logins is a list of *nix system logins. + items: + type: string + nullable: true + type: array + node_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: NodeLabels is a map of node labels (used to dynamically + grant access to nodes). + type: object + node_labels_expression: + description: NodeLabelsExpression is a predicate expression used + to allow/deny access to SSH nodes. + type: string + request: + nullable: true + properties: + annotations: + additionalProperties: + items: + type: string + type: array + description: Annotations is a collection of annotations to + be programmatically appended to pending access requests + at the time of their creation. These annotations serve as + a mechanism to propagate extra information to plugins. Since + these annotations support variable interpolation syntax, + they also offer a mechanism for forwarding claims from an + external identity provider, to a plugin via {{ `{{external.trait_name}}` }} + style substitutions. + type: object + claims_to_roles: + description: ClaimsToRoles specifies a mapping from claims + (traits) to teleport roles. + items: + properties: + claim: + description: Claim is a claim name. + type: string + roles: + description: Roles is a list of static teleport roles + to match. + items: + type: string + nullable: true + type: array + value: + description: Value is a claim value to match. + type: string + type: object + type: array + max_duration: + description: MaxDuration is the amount of time the access + will be granted for. If this is zero, the default duration + is used. + format: duration + type: string + roles: + description: Roles is the name of roles which will match the + request rule. + items: + type: string + nullable: true + type: array + search_as_roles: + description: SearchAsRoles is a list of extra roles which + should apply to a user while they are searching for resources + as part of a Resource Access Request, and defines the underlying + roles which will be requested as part of any Resource Access + Request. + items: + type: string + nullable: true + type: array + suggested_reviewers: + description: SuggestedReviewers is a list of reviewer suggestions. These + can be teleport usernames, but that is not a requirement. + items: + type: string + nullable: true + type: array + thresholds: + description: Thresholds is a list of thresholds, one of which + must be met in order for reviews to trigger a state-transition. If + no thresholds are provided, a default threshold of 1 for + approval and denial is used. + items: + properties: + approve: + description: Approve is the number of matching approvals + needed for state-transition. + format: int32 + type: integer + deny: + description: Deny is the number of denials needed for + state-transition. + format: int32 + type: integer + filter: + description: Filter is an optional predicate used to + determine which reviews count toward this threshold. + type: string + name: + description: Name is the optional human-readable name + of the threshold. + type: string + type: object + type: array + type: object + require_session_join: + description: RequireSessionJoin specifies policies for required + users to start a session. + items: + properties: + count: + description: Count is the amount of people that need to + be matched for this policy to be fulfilled. + format: int32 + type: integer + filter: + description: Filter is a predicate that determines what + users count towards this policy. + type: string + kinds: + description: Kinds are the session kinds this policy applies + to. + items: + type: string + nullable: true + type: array + modes: + description: Modes is the list of modes that may be used + to fulfill this policy. + items: + type: string + nullable: true + type: array + name: + description: Name is the name of the policy. + type: string + on_leave: + description: OnLeave is the behaviour that's used when the + policy is no longer fulfilled for a live session. + type: string + type: object + nullable: true + type: array + review_requests: + description: ReviewRequests defines conditions for submitting + access reviews. + nullable: true + properties: + claims_to_roles: + description: ClaimsToRoles specifies a mapping from claims + (traits) to teleport roles. + items: + properties: + claim: + description: Claim is a claim name. + type: string + roles: + description: Roles is a list of static teleport roles + to match. + items: + type: string + nullable: true + type: array + value: + description: Value is a claim value to match. + type: string + type: object + type: array + preview_as_roles: + description: PreviewAsRoles is a list of extra roles which + should apply to a reviewer while they are viewing a Resource + Access Request for the purposes of viewing details such + as the hostname and labels of requested resources. + items: + type: string + nullable: true + type: array + roles: + description: Roles is the name of roles which may be reviewed. + items: + type: string + nullable: true + type: array + where: + description: Where is an optional predicate which further + limits which requests are reviewable. + type: string + type: object + rules: + description: Rules is a list of rules and their access levels. + Rules are a high level construct used for access control. + items: + properties: + actions: + description: Actions specifies optional actions taken when + this rule matches + items: + type: string + nullable: true + type: array + resources: + description: Resources is a list of resources + items: + type: string + nullable: true + type: array + verbs: + description: Verbs is a list of verbs + items: + type: string + nullable: true + type: array + where: + description: Where specifies optional advanced matcher + type: string + type: object + type: array + windows_desktop_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: WindowsDesktopLabels are used in the RBAC system + to allow/deny access to Windows desktops. + type: object + windows_desktop_labels_expression: + description: WindowsDesktopLabelsExpression is a predicate expression + used to allow/deny access to Windows desktops. + type: string + windows_desktop_logins: + description: WindowsDesktopLogins is a list of desktop login names + allowed/denied for Windows desktops. + items: + type: string + nullable: true + type: array + type: object + deny: + description: Deny is the set of conditions evaluated to deny access. + Deny takes priority over allow. + properties: + app_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: AppLabels is a map of labels used as part of the + RBAC system. + type: object + app_labels_expression: + description: AppLabelsExpression is a predicate expression used + to allow/deny access to Apps. + type: string + aws_role_arns: + description: AWSRoleARNs is a list of AWS role ARNs this role + is allowed to assume. + items: + type: string + nullable: true + type: array + azure_identities: + description: AzureIdentities is a list of Azure identities this + role is allowed to assume. + items: + type: string + nullable: true + type: array + cluster_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: ClusterLabels is a map of node labels (used to dynamically + grant access to clusters). + type: object + cluster_labels_expression: + description: ClusterLabelsExpression is a predicate expression + used to allow/deny access to remote Teleport clusters. + type: string + db_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: DatabaseLabels are used in RBAC system to allow/deny + access to databases. + type: object + db_labels_expression: + description: DatabaseLabelsExpression is a predicate expression + used to allow/deny access to Databases. + type: string + db_names: + description: DatabaseNames is a list of database names this role + is allowed to connect to. + items: + type: string + nullable: true + type: array + db_roles: + description: DatabaseRoles is a list of databases roles for automatic + user creation. + items: + type: string + nullable: true + type: array + db_service_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: DatabaseServiceLabels are used in RBAC system to + allow/deny access to Database Services. + type: object + db_service_labels_expression: + description: DatabaseServiceLabelsExpression is a predicate expression + used to allow/deny access to Database Services. + type: string + db_users: + description: DatabaseUsers is a list of databases users this role + is allowed to connect as. + items: + type: string + nullable: true + type: array + desktop_groups: + description: DesktopGroups is a list of groups for created desktop + users to be added to + items: + type: string + nullable: true + type: array + gcp_service_accounts: + description: GCPServiceAccounts is a list of GCP service accounts + this role is allowed to assume. + items: + type: string + nullable: true + type: array + group_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: GroupLabels is a map of labels used as part of the + RBAC system. + type: object + group_labels_expression: + description: GroupLabelsExpression is a predicate expression used + to allow/deny access to user groups. + type: string + host_groups: + description: HostGroups is a list of groups for created users + to be added to + items: + type: string + nullable: true + type: array + host_sudoers: + description: HostSudoers is a list of entries to include in a + users sudoer file + items: + type: string + nullable: true + type: array + impersonate: + description: Impersonate specifies what users and roles this role + is allowed to impersonate by issuing certificates or other possible + means. + nullable: true + properties: + roles: + description: Roles is a list of resources this role is allowed + to impersonate + items: + type: string + nullable: true + type: array + users: + description: Users is a list of resources this role is allowed + to impersonate, could be an empty list or a Wildcard pattern + items: + type: string + nullable: true + type: array + where: + description: Where specifies optional advanced matcher + type: string + type: object + join_sessions: + description: JoinSessions specifies policies to allow users to + join other sessions. + items: + properties: + kinds: + description: Kinds are the session kinds this policy applies + to. + items: + type: string + nullable: true + type: array + modes: + description: Modes is a list of permitted participant modes + for this policy. + items: + type: string + nullable: true + type: array + name: + description: Name is the name of the policy. + type: string + roles: + description: Roles is a list of roles that you can join + the session of. + items: + type: string + nullable: true + type: array + type: object + nullable: true + type: array + kubernetes_groups: + description: KubeGroups is a list of kubernetes groups + items: + type: string + nullable: true + type: array + kubernetes_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: KubernetesLabels is a map of kubernetes cluster labels + used for RBAC. + type: object + kubernetes_labels_expression: + description: KubernetesLabelsExpression is a predicate expression + used to allow/deny access to kubernetes clusters. + type: string + kubernetes_resources: + description: KubernetesResources is the Kubernetes Resources this + Role grants access to. + items: + properties: + kind: + description: Kind specifies the Kubernetes Resource type. + At the moment only "pod" is supported. + type: string + name: + description: Name is the resource name. It supports wildcards. + type: string + namespace: + description: Namespace is the resource namespace. It supports + wildcards. + type: string + verbs: + description: Verbs are the allowed Kubernetes verbs for + the following resource. + items: + type: string + nullable: true + type: array + type: object + type: array + kubernetes_users: + description: KubeUsers is an optional kubernetes users to impersonate + items: + type: string + nullable: true + type: array + logins: + description: Logins is a list of *nix system logins. + items: + type: string + nullable: true + type: array + node_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: NodeLabels is a map of node labels (used to dynamically + grant access to nodes). + type: object + node_labels_expression: + description: NodeLabelsExpression is a predicate expression used + to allow/deny access to SSH nodes. + type: string + request: + nullable: true + properties: + annotations: + additionalProperties: + items: + type: string + type: array + description: Annotations is a collection of annotations to + be programmatically appended to pending access requests + at the time of their creation. These annotations serve as + a mechanism to propagate extra information to plugins. Since + these annotations support variable interpolation syntax, + they also offer a mechanism for forwarding claims from an + external identity provider, to a plugin via {{ `{{external.trait_name}}` }} + style substitutions. + type: object + claims_to_roles: + description: ClaimsToRoles specifies a mapping from claims + (traits) to teleport roles. + items: + properties: + claim: + description: Claim is a claim name. + type: string + roles: + description: Roles is a list of static teleport roles + to match. + items: + type: string + nullable: true + type: array + value: + description: Value is a claim value to match. + type: string + type: object + type: array + max_duration: + description: MaxDuration is the amount of time the access + will be granted for. If this is zero, the default duration + is used. + format: duration + type: string + roles: + description: Roles is the name of roles which will match the + request rule. + items: + type: string + nullable: true + type: array + search_as_roles: + description: SearchAsRoles is a list of extra roles which + should apply to a user while they are searching for resources + as part of a Resource Access Request, and defines the underlying + roles which will be requested as part of any Resource Access + Request. + items: + type: string + nullable: true + type: array + suggested_reviewers: + description: SuggestedReviewers is a list of reviewer suggestions. These + can be teleport usernames, but that is not a requirement. + items: + type: string + nullable: true + type: array + thresholds: + description: Thresholds is a list of thresholds, one of which + must be met in order for reviews to trigger a state-transition. If + no thresholds are provided, a default threshold of 1 for + approval and denial is used. + items: + properties: + approve: + description: Approve is the number of matching approvals + needed for state-transition. + format: int32 + type: integer + deny: + description: Deny is the number of denials needed for + state-transition. + format: int32 + type: integer + filter: + description: Filter is an optional predicate used to + determine which reviews count toward this threshold. + type: string + name: + description: Name is the optional human-readable name + of the threshold. + type: string + type: object + type: array + type: object + require_session_join: + description: RequireSessionJoin specifies policies for required + users to start a session. + items: + properties: + count: + description: Count is the amount of people that need to + be matched for this policy to be fulfilled. + format: int32 + type: integer + filter: + description: Filter is a predicate that determines what + users count towards this policy. + type: string + kinds: + description: Kinds are the session kinds this policy applies + to. + items: + type: string + nullable: true + type: array + modes: + description: Modes is the list of modes that may be used + to fulfill this policy. + items: + type: string + nullable: true + type: array + name: + description: Name is the name of the policy. + type: string + on_leave: + description: OnLeave is the behaviour that's used when the + policy is no longer fulfilled for a live session. + type: string + type: object + nullable: true + type: array + review_requests: + description: ReviewRequests defines conditions for submitting + access reviews. + nullable: true + properties: + claims_to_roles: + description: ClaimsToRoles specifies a mapping from claims + (traits) to teleport roles. + items: + properties: + claim: + description: Claim is a claim name. + type: string + roles: + description: Roles is a list of static teleport roles + to match. + items: + type: string + nullable: true + type: array + value: + description: Value is a claim value to match. + type: string + type: object + type: array + preview_as_roles: + description: PreviewAsRoles is a list of extra roles which + should apply to a reviewer while they are viewing a Resource + Access Request for the purposes of viewing details such + as the hostname and labels of requested resources. + items: + type: string + nullable: true + type: array + roles: + description: Roles is the name of roles which may be reviewed. + items: + type: string + nullable: true + type: array + where: + description: Where is an optional predicate which further + limits which requests are reviewable. + type: string + type: object + rules: + description: Rules is a list of rules and their access levels. + Rules are a high level construct used for access control. + items: + properties: + actions: + description: Actions specifies optional actions taken when + this rule matches + items: + type: string + nullable: true + type: array + resources: + description: Resources is a list of resources + items: + type: string + nullable: true + type: array + verbs: + description: Verbs is a list of verbs + items: + type: string + nullable: true + type: array + where: + description: Where specifies optional advanced matcher + type: string + type: object + type: array + windows_desktop_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: WindowsDesktopLabels are used in the RBAC system + to allow/deny access to Windows desktops. + type: object + windows_desktop_labels_expression: + description: WindowsDesktopLabelsExpression is a predicate expression + used to allow/deny access to Windows desktops. + type: string + windows_desktop_logins: + description: WindowsDesktopLogins is a list of desktop login names + allowed/denied for Windows desktops. + items: + type: string + nullable: true + type: array + type: object + options: + description: Options is for OpenSSH options like agent forwarding. + properties: + cert_extensions: + description: CertExtensions specifies the key/values + items: + properties: + mode: + description: Mode is the type of extension to be used -- + currently critical-option is not supported + x-kubernetes-int-or-string: true + name: + description: Name specifies the key to be used in the cert + extension. + type: string + type: + description: Type represents the certificate type being + extended, only ssh is supported at this time. + x-kubernetes-int-or-string: true + value: + description: Value specifies the value to be used in the + cert extension. + type: string + type: object + nullable: true + type: array + cert_format: + description: CertificateFormat defines the format of the user + certificate to allow compatibility with older versions of OpenSSH. + type: string + client_idle_timeout: + description: ClientIdleTimeout sets disconnect clients on idle + timeout behavior, if set to 0 means do not disconnect, otherwise + is set to the idle duration. + format: duration + type: string + create_db_user: + description: CreateDatabaseUser enabled automatic database user + creation. + type: boolean + create_db_user_mode: + description: CreateDatabaseUserMode allows users to be automatically + created on a database when not set to off. + x-kubernetes-int-or-string: true + create_desktop_user: + description: CreateDesktopUser allows users to be automatically + created on a Windows desktop + type: boolean + create_host_user: + description: CreateHostUser allows users to be automatically created + on a host + type: boolean + create_host_user_mode: + description: CreateHostUserMode allows users to be automatically + created on a host when not set to off + x-kubernetes-int-or-string: true + desktop_clipboard: + description: DesktopClipboard indicates whether clipboard sharing + is allowed between the user's workstation and the remote desktop. + It defaults to true unless explicitly set to false. + type: boolean + desktop_directory_sharing: + description: DesktopDirectorySharing indicates whether directory + sharing is allowed between the user's workstation and the remote + desktop. It defaults to false unless explicitly set to true. + type: boolean + device_trust_mode: + description: DeviceTrustMode is the device authorization mode + used for the resources associated with the role. See DeviceTrust.Mode. + Reserved for future use, not yet used by Teleport. + type: string + disconnect_expired_cert: + description: DisconnectExpiredCert sets disconnect clients on + expired certificates. + type: boolean + enhanced_recording: + description: BPF defines what events to record for the BPF-based + session recorder. + items: + type: string + nullable: true + type: array + forward_agent: + description: ForwardAgent is SSH agent forwarding. + type: boolean + idp: + description: IDP is a set of options related to accessing IdPs + within Teleport. Requires Teleport Enterprise. + nullable: true + properties: + saml: + description: SAML are options related to the Teleport SAML + IdP. + nullable: true + properties: + enabled: + description: Enabled is set to true if this option allows + access to the Teleport SAML IdP. + type: boolean + type: object + type: object + lock: + description: Lock specifies the locking mode (strict|best_effort) + to be applied with the role. + type: string + max_connections: + description: MaxConnections defines the maximum number of concurrent + connections a user may hold. + format: int64 + type: integer + max_kubernetes_connections: + description: MaxKubernetesConnections defines the maximum number + of concurrent Kubernetes sessions a user may hold. + format: int64 + type: integer + max_session_ttl: + description: MaxSessionTTL defines how long a SSH session can + last for. + format: duration + type: string + max_sessions: + description: MaxSessions defines the maximum number of concurrent + sessions per connection. + format: int64 + type: integer + permit_x11_forwarding: + description: PermitX11Forwarding authorizes use of X11 forwarding. + type: boolean + pin_source_ip: + description: PinSourceIP forces the same client IP for certificate + generation and usage + type: boolean + port_forwarding: + description: PortForwarding defines if the certificate will have + "permit-port-forwarding" in the certificate. PortForwarding + is "yes" if not set, that's why this is a pointer + type: boolean + record_session: + description: RecordDesktopSession indicates whether desktop access + sessions should be recorded. It defaults to true unless explicitly + set to false. + nullable: true + properties: + default: + description: Default indicates the default value for the services. + type: string + desktop: + description: Desktop indicates whether desktop sessions should + be recorded. It defaults to true unless explicitly set to + false. + type: boolean + ssh: + description: SSH indicates the session mode used on SSH sessions. + type: string + type: object + request_access: + description: RequestAccess defines the access request strategy + (optional|note|always) where optional is the default. + type: string + request_prompt: + description: RequestPrompt is an optional message which tells + users what they aught to request. + type: string + require_session_mfa: + description: RequireMFAType is the type of MFA requirement enforced + for this user. + x-kubernetes-int-or-string: true + ssh_file_copy: + description: SSHFileCopy indicates whether remote file operations + via SCP or SFTP are allowed over an SSH session. It defaults + to true unless explicitly set to false. + type: boolean + type: object + type: object + status: + description: Status defines the observed state of the Teleport resource + properties: + conditions: + description: Conditions represent the latest available observations + of an object's state + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + teleportResourceID: + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_rolesv7.yaml b/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_rolesv7.yaml new file mode 100644 index 0000000000000..aef922062327c --- /dev/null +++ b/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_rolesv7.yaml @@ -0,0 +1,1221 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + name: teleportrolesv7.resources.teleport.dev +spec: + group: resources.teleport.dev + names: + kind: TeleportRoleV7 + listKind: TeleportRoleV7List + plural: teleportrolesv7 + shortNames: + - rolev7 + - rolesv7 + singular: teleportrolev7 + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: RoleV7 is the Schema for the rolesv7 API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Role resource definition v7 from Teleport + properties: + allow: + description: Allow is the set of conditions evaluated to grant access. + properties: + app_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: AppLabels is a map of labels used as part of the + RBAC system. + type: object + app_labels_expression: + description: AppLabelsExpression is a predicate expression used + to allow/deny access to Apps. + type: string + aws_role_arns: + description: AWSRoleARNs is a list of AWS role ARNs this role + is allowed to assume. + items: + type: string + nullable: true + type: array + azure_identities: + description: AzureIdentities is a list of Azure identities this + role is allowed to assume. + items: + type: string + nullable: true + type: array + cluster_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: ClusterLabels is a map of node labels (used to dynamically + grant access to clusters). + type: object + cluster_labels_expression: + description: ClusterLabelsExpression is a predicate expression + used to allow/deny access to remote Teleport clusters. + type: string + db_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: DatabaseLabels are used in RBAC system to allow/deny + access to databases. + type: object + db_labels_expression: + description: DatabaseLabelsExpression is a predicate expression + used to allow/deny access to Databases. + type: string + db_names: + description: DatabaseNames is a list of database names this role + is allowed to connect to. + items: + type: string + nullable: true + type: array + db_roles: + description: DatabaseRoles is a list of databases roles for automatic + user creation. + items: + type: string + nullable: true + type: array + db_service_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: DatabaseServiceLabels are used in RBAC system to + allow/deny access to Database Services. + type: object + db_service_labels_expression: + description: DatabaseServiceLabelsExpression is a predicate expression + used to allow/deny access to Database Services. + type: string + db_users: + description: DatabaseUsers is a list of databases users this role + is allowed to connect as. + items: + type: string + nullable: true + type: array + desktop_groups: + description: DesktopGroups is a list of groups for created desktop + users to be added to + items: + type: string + nullable: true + type: array + gcp_service_accounts: + description: GCPServiceAccounts is a list of GCP service accounts + this role is allowed to assume. + items: + type: string + nullable: true + type: array + group_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: GroupLabels is a map of labels used as part of the + RBAC system. + type: object + group_labels_expression: + description: GroupLabelsExpression is a predicate expression used + to allow/deny access to user groups. + type: string + host_groups: + description: HostGroups is a list of groups for created users + to be added to + items: + type: string + nullable: true + type: array + host_sudoers: + description: HostSudoers is a list of entries to include in a + users sudoer file + items: + type: string + nullable: true + type: array + impersonate: + description: Impersonate specifies what users and roles this role + is allowed to impersonate by issuing certificates or other possible + means. + nullable: true + properties: + roles: + description: Roles is a list of resources this role is allowed + to impersonate + items: + type: string + nullable: true + type: array + users: + description: Users is a list of resources this role is allowed + to impersonate, could be an empty list or a Wildcard pattern + items: + type: string + nullable: true + type: array + where: + description: Where specifies optional advanced matcher + type: string + type: object + join_sessions: + description: JoinSessions specifies policies to allow users to + join other sessions. + items: + properties: + kinds: + description: Kinds are the session kinds this policy applies + to. + items: + type: string + nullable: true + type: array + modes: + description: Modes is a list of permitted participant modes + for this policy. + items: + type: string + nullable: true + type: array + name: + description: Name is the name of the policy. + type: string + roles: + description: Roles is a list of roles that you can join + the session of. + items: + type: string + nullable: true + type: array + type: object + nullable: true + type: array + kubernetes_groups: + description: KubeGroups is a list of kubernetes groups + items: + type: string + nullable: true + type: array + kubernetes_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: KubernetesLabels is a map of kubernetes cluster labels + used for RBAC. + type: object + kubernetes_labels_expression: + description: KubernetesLabelsExpression is a predicate expression + used to allow/deny access to kubernetes clusters. + type: string + kubernetes_resources: + description: KubernetesResources is the Kubernetes Resources this + Role grants access to. + items: + properties: + kind: + description: Kind specifies the Kubernetes Resource type. + At the moment only "pod" is supported. + type: string + name: + description: Name is the resource name. It supports wildcards. + type: string + namespace: + description: Namespace is the resource namespace. It supports + wildcards. + type: string + verbs: + description: Verbs are the allowed Kubernetes verbs for + the following resource. + items: + type: string + nullable: true + type: array + type: object + type: array + kubernetes_users: + description: KubeUsers is an optional kubernetes users to impersonate + items: + type: string + nullable: true + type: array + logins: + description: Logins is a list of *nix system logins. + items: + type: string + nullable: true + type: array + node_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: NodeLabels is a map of node labels (used to dynamically + grant access to nodes). + type: object + node_labels_expression: + description: NodeLabelsExpression is a predicate expression used + to allow/deny access to SSH nodes. + type: string + request: + nullable: true + properties: + annotations: + additionalProperties: + items: + type: string + type: array + description: Annotations is a collection of annotations to + be programmatically appended to pending access requests + at the time of their creation. These annotations serve as + a mechanism to propagate extra information to plugins. Since + these annotations support variable interpolation syntax, + they also offer a mechanism for forwarding claims from an + external identity provider, to a plugin via {{ `{{external.trait_name}}` }} + style substitutions. + type: object + claims_to_roles: + description: ClaimsToRoles specifies a mapping from claims + (traits) to teleport roles. + items: + properties: + claim: + description: Claim is a claim name. + type: string + roles: + description: Roles is a list of static teleport roles + to match. + items: + type: string + nullable: true + type: array + value: + description: Value is a claim value to match. + type: string + type: object + type: array + max_duration: + description: MaxDuration is the amount of time the access + will be granted for. If this is zero, the default duration + is used. + format: duration + type: string + roles: + description: Roles is the name of roles which will match the + request rule. + items: + type: string + nullable: true + type: array + search_as_roles: + description: SearchAsRoles is a list of extra roles which + should apply to a user while they are searching for resources + as part of a Resource Access Request, and defines the underlying + roles which will be requested as part of any Resource Access + Request. + items: + type: string + nullable: true + type: array + suggested_reviewers: + description: SuggestedReviewers is a list of reviewer suggestions. These + can be teleport usernames, but that is not a requirement. + items: + type: string + nullable: true + type: array + thresholds: + description: Thresholds is a list of thresholds, one of which + must be met in order for reviews to trigger a state-transition. If + no thresholds are provided, a default threshold of 1 for + approval and denial is used. + items: + properties: + approve: + description: Approve is the number of matching approvals + needed for state-transition. + format: int32 + type: integer + deny: + description: Deny is the number of denials needed for + state-transition. + format: int32 + type: integer + filter: + description: Filter is an optional predicate used to + determine which reviews count toward this threshold. + type: string + name: + description: Name is the optional human-readable name + of the threshold. + type: string + type: object + type: array + type: object + require_session_join: + description: RequireSessionJoin specifies policies for required + users to start a session. + items: + properties: + count: + description: Count is the amount of people that need to + be matched for this policy to be fulfilled. + format: int32 + type: integer + filter: + description: Filter is a predicate that determines what + users count towards this policy. + type: string + kinds: + description: Kinds are the session kinds this policy applies + to. + items: + type: string + nullable: true + type: array + modes: + description: Modes is the list of modes that may be used + to fulfill this policy. + items: + type: string + nullable: true + type: array + name: + description: Name is the name of the policy. + type: string + on_leave: + description: OnLeave is the behaviour that's used when the + policy is no longer fulfilled for a live session. + type: string + type: object + nullable: true + type: array + review_requests: + description: ReviewRequests defines conditions for submitting + access reviews. + nullable: true + properties: + claims_to_roles: + description: ClaimsToRoles specifies a mapping from claims + (traits) to teleport roles. + items: + properties: + claim: + description: Claim is a claim name. + type: string + roles: + description: Roles is a list of static teleport roles + to match. + items: + type: string + nullable: true + type: array + value: + description: Value is a claim value to match. + type: string + type: object + type: array + preview_as_roles: + description: PreviewAsRoles is a list of extra roles which + should apply to a reviewer while they are viewing a Resource + Access Request for the purposes of viewing details such + as the hostname and labels of requested resources. + items: + type: string + nullable: true + type: array + roles: + description: Roles is the name of roles which may be reviewed. + items: + type: string + nullable: true + type: array + where: + description: Where is an optional predicate which further + limits which requests are reviewable. + type: string + type: object + rules: + description: Rules is a list of rules and their access levels. + Rules are a high level construct used for access control. + items: + properties: + actions: + description: Actions specifies optional actions taken when + this rule matches + items: + type: string + nullable: true + type: array + resources: + description: Resources is a list of resources + items: + type: string + nullable: true + type: array + verbs: + description: Verbs is a list of verbs + items: + type: string + nullable: true + type: array + where: + description: Where specifies optional advanced matcher + type: string + type: object + type: array + windows_desktop_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: WindowsDesktopLabels are used in the RBAC system + to allow/deny access to Windows desktops. + type: object + windows_desktop_labels_expression: + description: WindowsDesktopLabelsExpression is a predicate expression + used to allow/deny access to Windows desktops. + type: string + windows_desktop_logins: + description: WindowsDesktopLogins is a list of desktop login names + allowed/denied for Windows desktops. + items: + type: string + nullable: true + type: array + type: object + deny: + description: Deny is the set of conditions evaluated to deny access. + Deny takes priority over allow. + properties: + app_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: AppLabels is a map of labels used as part of the + RBAC system. + type: object + app_labels_expression: + description: AppLabelsExpression is a predicate expression used + to allow/deny access to Apps. + type: string + aws_role_arns: + description: AWSRoleARNs is a list of AWS role ARNs this role + is allowed to assume. + items: + type: string + nullable: true + type: array + azure_identities: + description: AzureIdentities is a list of Azure identities this + role is allowed to assume. + items: + type: string + nullable: true + type: array + cluster_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: ClusterLabels is a map of node labels (used to dynamically + grant access to clusters). + type: object + cluster_labels_expression: + description: ClusterLabelsExpression is a predicate expression + used to allow/deny access to remote Teleport clusters. + type: string + db_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: DatabaseLabels are used in RBAC system to allow/deny + access to databases. + type: object + db_labels_expression: + description: DatabaseLabelsExpression is a predicate expression + used to allow/deny access to Databases. + type: string + db_names: + description: DatabaseNames is a list of database names this role + is allowed to connect to. + items: + type: string + nullable: true + type: array + db_roles: + description: DatabaseRoles is a list of databases roles for automatic + user creation. + items: + type: string + nullable: true + type: array + db_service_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: DatabaseServiceLabels are used in RBAC system to + allow/deny access to Database Services. + type: object + db_service_labels_expression: + description: DatabaseServiceLabelsExpression is a predicate expression + used to allow/deny access to Database Services. + type: string + db_users: + description: DatabaseUsers is a list of databases users this role + is allowed to connect as. + items: + type: string + nullable: true + type: array + desktop_groups: + description: DesktopGroups is a list of groups for created desktop + users to be added to + items: + type: string + nullable: true + type: array + gcp_service_accounts: + description: GCPServiceAccounts is a list of GCP service accounts + this role is allowed to assume. + items: + type: string + nullable: true + type: array + group_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: GroupLabels is a map of labels used as part of the + RBAC system. + type: object + group_labels_expression: + description: GroupLabelsExpression is a predicate expression used + to allow/deny access to user groups. + type: string + host_groups: + description: HostGroups is a list of groups for created users + to be added to + items: + type: string + nullable: true + type: array + host_sudoers: + description: HostSudoers is a list of entries to include in a + users sudoer file + items: + type: string + nullable: true + type: array + impersonate: + description: Impersonate specifies what users and roles this role + is allowed to impersonate by issuing certificates or other possible + means. + nullable: true + properties: + roles: + description: Roles is a list of resources this role is allowed + to impersonate + items: + type: string + nullable: true + type: array + users: + description: Users is a list of resources this role is allowed + to impersonate, could be an empty list or a Wildcard pattern + items: + type: string + nullable: true + type: array + where: + description: Where specifies optional advanced matcher + type: string + type: object + join_sessions: + description: JoinSessions specifies policies to allow users to + join other sessions. + items: + properties: + kinds: + description: Kinds are the session kinds this policy applies + to. + items: + type: string + nullable: true + type: array + modes: + description: Modes is a list of permitted participant modes + for this policy. + items: + type: string + nullable: true + type: array + name: + description: Name is the name of the policy. + type: string + roles: + description: Roles is a list of roles that you can join + the session of. + items: + type: string + nullable: true + type: array + type: object + nullable: true + type: array + kubernetes_groups: + description: KubeGroups is a list of kubernetes groups + items: + type: string + nullable: true + type: array + kubernetes_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: KubernetesLabels is a map of kubernetes cluster labels + used for RBAC. + type: object + kubernetes_labels_expression: + description: KubernetesLabelsExpression is a predicate expression + used to allow/deny access to kubernetes clusters. + type: string + kubernetes_resources: + description: KubernetesResources is the Kubernetes Resources this + Role grants access to. + items: + properties: + kind: + description: Kind specifies the Kubernetes Resource type. + At the moment only "pod" is supported. + type: string + name: + description: Name is the resource name. It supports wildcards. + type: string + namespace: + description: Namespace is the resource namespace. It supports + wildcards. + type: string + verbs: + description: Verbs are the allowed Kubernetes verbs for + the following resource. + items: + type: string + nullable: true + type: array + type: object + type: array + kubernetes_users: + description: KubeUsers is an optional kubernetes users to impersonate + items: + type: string + nullable: true + type: array + logins: + description: Logins is a list of *nix system logins. + items: + type: string + nullable: true + type: array + node_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: NodeLabels is a map of node labels (used to dynamically + grant access to nodes). + type: object + node_labels_expression: + description: NodeLabelsExpression is a predicate expression used + to allow/deny access to SSH nodes. + type: string + request: + nullable: true + properties: + annotations: + additionalProperties: + items: + type: string + type: array + description: Annotations is a collection of annotations to + be programmatically appended to pending access requests + at the time of their creation. These annotations serve as + a mechanism to propagate extra information to plugins. Since + these annotations support variable interpolation syntax, + they also offer a mechanism for forwarding claims from an + external identity provider, to a plugin via {{ `{{external.trait_name}}` }} + style substitutions. + type: object + claims_to_roles: + description: ClaimsToRoles specifies a mapping from claims + (traits) to teleport roles. + items: + properties: + claim: + description: Claim is a claim name. + type: string + roles: + description: Roles is a list of static teleport roles + to match. + items: + type: string + nullable: true + type: array + value: + description: Value is a claim value to match. + type: string + type: object + type: array + max_duration: + description: MaxDuration is the amount of time the access + will be granted for. If this is zero, the default duration + is used. + format: duration + type: string + roles: + description: Roles is the name of roles which will match the + request rule. + items: + type: string + nullable: true + type: array + search_as_roles: + description: SearchAsRoles is a list of extra roles which + should apply to a user while they are searching for resources + as part of a Resource Access Request, and defines the underlying + roles which will be requested as part of any Resource Access + Request. + items: + type: string + nullable: true + type: array + suggested_reviewers: + description: SuggestedReviewers is a list of reviewer suggestions. These + can be teleport usernames, but that is not a requirement. + items: + type: string + nullable: true + type: array + thresholds: + description: Thresholds is a list of thresholds, one of which + must be met in order for reviews to trigger a state-transition. If + no thresholds are provided, a default threshold of 1 for + approval and denial is used. + items: + properties: + approve: + description: Approve is the number of matching approvals + needed for state-transition. + format: int32 + type: integer + deny: + description: Deny is the number of denials needed for + state-transition. + format: int32 + type: integer + filter: + description: Filter is an optional predicate used to + determine which reviews count toward this threshold. + type: string + name: + description: Name is the optional human-readable name + of the threshold. + type: string + type: object + type: array + type: object + require_session_join: + description: RequireSessionJoin specifies policies for required + users to start a session. + items: + properties: + count: + description: Count is the amount of people that need to + be matched for this policy to be fulfilled. + format: int32 + type: integer + filter: + description: Filter is a predicate that determines what + users count towards this policy. + type: string + kinds: + description: Kinds are the session kinds this policy applies + to. + items: + type: string + nullable: true + type: array + modes: + description: Modes is the list of modes that may be used + to fulfill this policy. + items: + type: string + nullable: true + type: array + name: + description: Name is the name of the policy. + type: string + on_leave: + description: OnLeave is the behaviour that's used when the + policy is no longer fulfilled for a live session. + type: string + type: object + nullable: true + type: array + review_requests: + description: ReviewRequests defines conditions for submitting + access reviews. + nullable: true + properties: + claims_to_roles: + description: ClaimsToRoles specifies a mapping from claims + (traits) to teleport roles. + items: + properties: + claim: + description: Claim is a claim name. + type: string + roles: + description: Roles is a list of static teleport roles + to match. + items: + type: string + nullable: true + type: array + value: + description: Value is a claim value to match. + type: string + type: object + type: array + preview_as_roles: + description: PreviewAsRoles is a list of extra roles which + should apply to a reviewer while they are viewing a Resource + Access Request for the purposes of viewing details such + as the hostname and labels of requested resources. + items: + type: string + nullable: true + type: array + roles: + description: Roles is the name of roles which may be reviewed. + items: + type: string + nullable: true + type: array + where: + description: Where is an optional predicate which further + limits which requests are reviewable. + type: string + type: object + rules: + description: Rules is a list of rules and their access levels. + Rules are a high level construct used for access control. + items: + properties: + actions: + description: Actions specifies optional actions taken when + this rule matches + items: + type: string + nullable: true + type: array + resources: + description: Resources is a list of resources + items: + type: string + nullable: true + type: array + verbs: + description: Verbs is a list of verbs + items: + type: string + nullable: true + type: array + where: + description: Where specifies optional advanced matcher + type: string + type: object + type: array + windows_desktop_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: WindowsDesktopLabels are used in the RBAC system + to allow/deny access to Windows desktops. + type: object + windows_desktop_labels_expression: + description: WindowsDesktopLabelsExpression is a predicate expression + used to allow/deny access to Windows desktops. + type: string + windows_desktop_logins: + description: WindowsDesktopLogins is a list of desktop login names + allowed/denied for Windows desktops. + items: + type: string + nullable: true + type: array + type: object + options: + description: Options is for OpenSSH options like agent forwarding. + properties: + cert_extensions: + description: CertExtensions specifies the key/values + items: + properties: + mode: + description: Mode is the type of extension to be used -- + currently critical-option is not supported + x-kubernetes-int-or-string: true + name: + description: Name specifies the key to be used in the cert + extension. + type: string + type: + description: Type represents the certificate type being + extended, only ssh is supported at this time. + x-kubernetes-int-or-string: true + value: + description: Value specifies the value to be used in the + cert extension. + type: string + type: object + nullable: true + type: array + cert_format: + description: CertificateFormat defines the format of the user + certificate to allow compatibility with older versions of OpenSSH. + type: string + client_idle_timeout: + description: ClientIdleTimeout sets disconnect clients on idle + timeout behavior, if set to 0 means do not disconnect, otherwise + is set to the idle duration. + format: duration + type: string + create_db_user: + description: CreateDatabaseUser enabled automatic database user + creation. + type: boolean + create_db_user_mode: + description: CreateDatabaseUserMode allows users to be automatically + created on a database when not set to off. + x-kubernetes-int-or-string: true + create_desktop_user: + description: CreateDesktopUser allows users to be automatically + created on a Windows desktop + type: boolean + create_host_user: + description: CreateHostUser allows users to be automatically created + on a host + type: boolean + create_host_user_mode: + description: CreateHostUserMode allows users to be automatically + created on a host when not set to off + x-kubernetes-int-or-string: true + desktop_clipboard: + description: DesktopClipboard indicates whether clipboard sharing + is allowed between the user's workstation and the remote desktop. + It defaults to true unless explicitly set to false. + type: boolean + desktop_directory_sharing: + description: DesktopDirectorySharing indicates whether directory + sharing is allowed between the user's workstation and the remote + desktop. It defaults to false unless explicitly set to true. + type: boolean + device_trust_mode: + description: DeviceTrustMode is the device authorization mode + used for the resources associated with the role. See DeviceTrust.Mode. + Reserved for future use, not yet used by Teleport. + type: string + disconnect_expired_cert: + description: DisconnectExpiredCert sets disconnect clients on + expired certificates. + type: boolean + enhanced_recording: + description: BPF defines what events to record for the BPF-based + session recorder. + items: + type: string + nullable: true + type: array + forward_agent: + description: ForwardAgent is SSH agent forwarding. + type: boolean + idp: + description: IDP is a set of options related to accessing IdPs + within Teleport. Requires Teleport Enterprise. + nullable: true + properties: + saml: + description: SAML are options related to the Teleport SAML + IdP. + nullable: true + properties: + enabled: + description: Enabled is set to true if this option allows + access to the Teleport SAML IdP. + type: boolean + type: object + type: object + lock: + description: Lock specifies the locking mode (strict|best_effort) + to be applied with the role. + type: string + max_connections: + description: MaxConnections defines the maximum number of concurrent + connections a user may hold. + format: int64 + type: integer + max_kubernetes_connections: + description: MaxKubernetesConnections defines the maximum number + of concurrent Kubernetes sessions a user may hold. + format: int64 + type: integer + max_session_ttl: + description: MaxSessionTTL defines how long a SSH session can + last for. + format: duration + type: string + max_sessions: + description: MaxSessions defines the maximum number of concurrent + sessions per connection. + format: int64 + type: integer + permit_x11_forwarding: + description: PermitX11Forwarding authorizes use of X11 forwarding. + type: boolean + pin_source_ip: + description: PinSourceIP forces the same client IP for certificate + generation and usage + type: boolean + port_forwarding: + description: PortForwarding defines if the certificate will have + "permit-port-forwarding" in the certificate. PortForwarding + is "yes" if not set, that's why this is a pointer + type: boolean + record_session: + description: RecordDesktopSession indicates whether desktop access + sessions should be recorded. It defaults to true unless explicitly + set to false. + nullable: true + properties: + default: + description: Default indicates the default value for the services. + type: string + desktop: + description: Desktop indicates whether desktop sessions should + be recorded. It defaults to true unless explicitly set to + false. + type: boolean + ssh: + description: SSH indicates the session mode used on SSH sessions. + type: string + type: object + request_access: + description: RequestAccess defines the access request strategy + (optional|note|always) where optional is the default. + type: string + request_prompt: + description: RequestPrompt is an optional message which tells + users what they aught to request. + type: string + require_session_mfa: + description: RequireMFAType is the type of MFA requirement enforced + for this user. + x-kubernetes-int-or-string: true + ssh_file_copy: + description: SSHFileCopy indicates whether remote file operations + via SCP or SFTP are allowed over an SSH session. It defaults + to true unless explicitly set to false. + type: boolean + type: object + type: object + status: + description: Status defines the observed state of the Teleport resource + properties: + conditions: + description: Conditions represent the latest available observations + of an object's state + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + teleportResourceID: + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_samlconnectors.yaml b/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_samlconnectors.yaml index dc51a28419136..caaa7f3a5fb1e 100644 --- a/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_samlconnectors.yaml +++ b/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_samlconnectors.yaml @@ -120,8 +120,7 @@ spec: type: string type: object status: - description: TeleportSAMLConnectorStatus defines the observed state of - TeleportSAMLConnector + description: Status defines the observed state of the Teleport resource properties: conditions: description: Conditions represent the latest available observations diff --git a/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_users.yaml b/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_users.yaml index 01c405d0adeed..030a2b6f59bf8 100644 --- a/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_users.yaml +++ b/examples/chart/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_users.yaml @@ -106,7 +106,7 @@ spec: type: array type: object status: - description: TeleportUserStatus defines the observed state of TeleportUser + description: Status defines the observed state of the Teleport resource properties: conditions: description: Conditions represent the latest available observations diff --git a/examples/chart/teleport-cluster/charts/teleport-operator/templates/role.yaml b/examples/chart/teleport-cluster/charts/teleport-operator/templates/role.yaml index 0983c15f70020..4d4e0ebcfdc13 100644 --- a/examples/chart/teleport-cluster/charts/teleport-operator/templates/role.yaml +++ b/examples/chart/teleport-cluster/charts/teleport-operator/templates/role.yaml @@ -11,6 +11,10 @@ rules: resources: - teleportroles - teleportroles/status + - teleportrolesv6 + - teleportrolesv6/status + - teleportrolesv7 + - teleportrolesv7/status - teleportusers - teleportusers/status - teleportgithubconnectors diff --git a/integrations/operator/apis/resources/v6/groupversion_info.go b/integrations/operator/apis/resources/status.go similarity index 50% rename from integrations/operator/apis/resources/v6/groupversion_info.go rename to integrations/operator/apis/resources/status.go index 10a6ace370cb3..0569ba6f525e0 100644 --- a/integrations/operator/apis/resources/v6/groupversion_info.go +++ b/integrations/operator/apis/resources/status.go @@ -16,25 +16,26 @@ * along with this program. If not, see . */ -// Package v6 contains API Schema definitions for the resources v6 API group -// +kubebuilder:object:generate=true -// +groupName=resources.teleport.dev -package v6 +package resources import ( - "k8s.io/apimachinery/pkg/runtime/schema" - "sigs.k8s.io/controller-runtime/pkg/scheme" - - "github.com/gravitational/teleport/integrations/operator/apis/resources" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -var ( - // GroupVersion is group version used to register these objects - GroupVersion = schema.GroupVersion{Group: resources.GroupName, Version: "v6"} - - // SchemeBuilder is used to add go types to the GroupVersionKind scheme - SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} +// Status defines the observed state of the Teleport resource +type Status struct { + // Conditions represent the latest available observations of an object's state + // +optional + Conditions []metav1.Condition `json:"conditions"` + // +optional + TeleportResourceID int64 `json:"teleportResourceID"` +} - // AddToScheme adds the types in this group-version to the given scheme. - AddToScheme = SchemeBuilder.AddToScheme -) +// DeepCopyInto deep-copies one resource status into another. +// Required to satisfy runtime.Object interface. +func (status *Status) DeepCopyInto(out *Status) { + *out = Status{} + out.Conditions = make([]metav1.Condition, len(status.Conditions)) + copy(out.Conditions, status.Conditions) + out.TeleportResourceID = status.TeleportResourceID +} diff --git a/integrations/operator/apis/resources/v1/accesslist_types.go b/integrations/operator/apis/resources/v1/accesslist_types.go index c1901c52f2751..96e316f1b457e 100644 --- a/integrations/operator/apis/resources/v1/accesslist_types.go +++ b/integrations/operator/apis/resources/v1/accesslist_types.go @@ -37,21 +37,13 @@ type TeleportAccessList struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` - Spec TeleportAccessListSpec `json:"spec,omitempty"` - Status TeleportAccessListStatus `json:"status,omitempty"` + Spec TeleportAccessListSpec `json:"spec,omitempty"` + Status resources.Status `json:"status,omitempty"` } // TeleportAccessListSpec defines the desired state of TeleportProvisionToken type TeleportAccessListSpec accesslist.Spec -type TeleportAccessListStatus struct { - // Conditions represent the latest available observations of an object's state - // +optional - Conditions []metav1.Condition `json:"conditions,omitempty"` - // +optional - TeleportResourceID int64 `json:"teleportResourceID,omitempty"` -} - //+kubebuilder:object:root=true // TeleportAccessListList contains a list of TeleportAccessList diff --git a/integrations/operator/apis/resources/v1/loginrule_types.go b/integrations/operator/apis/resources/v1/loginrule_types.go index cdef6076d5184..0886e01632d2c 100644 --- a/integrations/operator/apis/resources/v1/loginrule_types.go +++ b/integrations/operator/apis/resources/v1/loginrule_types.go @@ -39,8 +39,8 @@ type TeleportLoginRule struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` - Spec TeleportLoginRuleSpec `json:"spec,omitempty"` - Status TeleportLoginRuleStatus `json:"status,omitempty"` + Spec TeleportLoginRuleSpec `json:"spec,omitempty"` + Status resources.Status `json:"status,omitempty"` } // TeleportLoginRuleSpec matches the JSON of generated CRD spec @@ -51,14 +51,6 @@ type TeleportLoginRuleSpec struct { TraitsMap map[string][]string `json:"traits_map,omitempty"` } -type TeleportLoginRuleStatus struct { - // Conditions represent the latest available observations of an object's state - // +optional - Conditions []metav1.Condition `json:"conditions,omitempty"` - // +optional - TeleportResourceID int64 `json:"teleportResourceID,omitempty"` -} - //+kubebuilder:object:root=true // TeleportLoginRuleList contains a list of TeleportLoginRule diff --git a/integrations/operator/apis/resources/v1/okta_import_rule.go b/integrations/operator/apis/resources/v1/okta_import_rule.go index 565758669f608..afb2d210de16f 100644 --- a/integrations/operator/apis/resources/v1/okta_import_rule.go +++ b/integrations/operator/apis/resources/v1/okta_import_rule.go @@ -38,8 +38,8 @@ type TeleportOktaImportRule struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` - Spec TeleportOktaImportRuleSpec `json:"spec,omitempty"` - Status TeleportOktaImportRuleStatus `json:"status,omitempty"` + Spec TeleportOktaImportRuleSpec `json:"spec,omitempty"` + Status resources.Status `json:"status,omitempty"` } // TeleportOktaImportRuleSpec matches the JSON of generated CRD spec @@ -71,14 +71,6 @@ type TeleportOktaImportRuleList struct { Items []TeleportOktaImportRule `json:"items"` } -type TeleportOktaImportRuleStatus struct { - // Conditions represent the latest available observations of an object's state - // +optional - Conditions []metav1.Condition `json:"conditions,omitempty"` - // +optional - TeleportResourceID int64 `json:"teleportResourceID,omitempty"` -} - // ToTeleport returns an OktaImportRule, which wraps the actual // [types.OktaImportRuleV1] and implements the necessary interface methods used // by the TeleportResourceReconciler. diff --git a/integrations/operator/apis/resources/v6/role_types.go b/integrations/operator/apis/resources/v1/rolev6_types.go similarity index 62% rename from integrations/operator/apis/resources/v6/role_types.go rename to integrations/operator/apis/resources/v1/rolev6_types.go index 7d74b29bf3be5..d55912fc9bd09 100644 --- a/integrations/operator/apis/resources/v6/role_types.go +++ b/integrations/operator/apis/resources/v1/rolev6_types.go @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package v6 +package v1 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -26,43 +26,34 @@ import ( ) func init() { - SchemeBuilder.Register(&TeleportRole{}, &TeleportRoleList{}) + SchemeBuilder.Register(&TeleportRoleV6{}, &TeleportRoleV6List{}) } -// TeleportRoleSpec defines the desired state of TeleportRole -type TeleportRoleSpec types.RoleSpecV6 - -// TeleportRoleStatus defines the observed state of TeleportRole -type TeleportRoleStatus struct { - // Conditions represent the latest available observations of an object's state - // +optional - Conditions []metav1.Condition `json:"conditions"` - // +optional - TeleportResourceID int64 `json:"teleportResourceID"` -} +// TeleportRoleV6Spec defines the desired state of TeleportRoleV6 +type TeleportRoleV6Spec types.RoleSpecV6 //+kubebuilder:object:root=true //+kubebuilder:subresource:status -// TeleportRole is the Schema for the roles API -type TeleportRole struct { +// TeleportRoleV6 is the Schema for the roles API +type TeleportRoleV6 struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` - Spec TeleportRoleSpec `json:"spec,omitempty"` - Status TeleportRoleStatus `json:"status,omitempty"` + Spec TeleportRoleV6Spec `json:"spec,omitempty"` + Status resources.Status `json:"status,omitempty"` } //+kubebuilder:object:root=true -// TeleportRoleList contains a list of TeleportRole -type TeleportRoleList struct { +// TeleportRoleV6List contains a list of TeleportRoleV6 +type TeleportRoleV6List struct { metav1.TypeMeta `json:",inline"` metav1.ListMeta `json:"metadata,omitempty"` - Items []TeleportRole `json:"items"` + Items []TeleportRoleV6 `json:"items"` } -func (r TeleportRole) ToTeleport() types.Role { +func (r TeleportRoleV6) ToTeleport() types.Role { return &types.RoleV6{ Kind: types.KindRole, Version: types.V6, @@ -75,34 +66,30 @@ func (r TeleportRole) ToTeleport() types.Role { } } -func init() { - SchemeBuilder.Register(&TeleportRole{}, &TeleportRoleList{}) -} - // Marshal serializes a spec into binary data. -func (spec *TeleportRoleSpec) Marshal() ([]byte, error) { +func (spec *TeleportRoleV6Spec) Marshal() ([]byte, error) { return (*types.RoleSpecV6)(spec).Marshal() } // Unmarshal deserializes a spec from binary data. -func (spec *TeleportRoleSpec) Unmarshal(data []byte) error { +func (spec *TeleportRoleV6Spec) Unmarshal(data []byte) error { return (*types.RoleSpecV6)(spec).Unmarshal(data) } // DeepCopyInto deep-copies one role spec into another. // Required to satisfy runtime.Object interface. -func (spec *TeleportRoleSpec) DeepCopyInto(out *TeleportRoleSpec) { +func (spec *TeleportRoleV6Spec) DeepCopyInto(out *TeleportRoleV6Spec) { data, err := spec.Marshal() if err != nil { panic(err) } - *out = TeleportRoleSpec{} + *out = TeleportRoleV6Spec{} if err = out.Unmarshal(data); err != nil { panic(err) } } // StatusConditions returns a pointer to Status.Conditions slice. -func (r *TeleportRole) StatusConditions() *[]metav1.Condition { +func (r *TeleportRoleV6) StatusConditions() *[]metav1.Condition { return &r.Status.Conditions } diff --git a/integrations/operator/apis/resources/v1/rolev7_types.go b/integrations/operator/apis/resources/v1/rolev7_types.go new file mode 100644 index 0000000000000..5651fda6f2044 --- /dev/null +++ b/integrations/operator/apis/resources/v1/rolev7_types.go @@ -0,0 +1,95 @@ +/* + * Teleport + * Copyright (C) 2023 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/integrations/operator/apis/resources" +) + +func init() { + SchemeBuilder.Register(&TeleportRoleV7{}, &TeleportRoleV7List{}) +} + +// TeleportRoleV7Spec defines the desired state of TeleportRoleV7 +type TeleportRoleV7Spec types.RoleSpecV6 + +//+kubebuilder:object:root=true +//+kubebuilder:subresource:status + +// TeleportRoleV7 is the Schema for the roles API +type TeleportRoleV7 struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec TeleportRoleV7Spec `json:"spec,omitempty"` + Status resources.Status `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// TeleportRoleV7List contains a list of TeleportRoleV7 +type TeleportRoleV7List struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []TeleportRoleV7 `json:"items"` +} + +func (r TeleportRoleV7) ToTeleport() types.Role { + return &types.RoleV6{ + Kind: types.KindRole, + Version: types.V7, + Metadata: types.Metadata{ + Name: r.Name, + Labels: r.Labels, + Description: r.Annotations[resources.DescriptionKey], + }, + Spec: types.RoleSpecV6(r.Spec), + } +} + +// Marshal serializes a spec into binary data. +func (spec *TeleportRoleV7Spec) Marshal() ([]byte, error) { + return (*types.RoleSpecV6)(spec).Marshal() +} + +// Unmarshal deserializes a spec from binary data. +func (spec *TeleportRoleV7Spec) Unmarshal(data []byte) error { + return (*types.RoleSpecV6)(spec).Unmarshal(data) +} + +// DeepCopyInto deep-copies one role spec into another. +// Required to satisfy runtime.Object interface. +func (spec *TeleportRoleV7Spec) DeepCopyInto(out *TeleportRoleV7Spec) { + data, err := spec.Marshal() + if err != nil { + panic(err) + } + *out = TeleportRoleV7Spec{} + if err = out.Unmarshal(data); err != nil { + panic(err) + } +} + +// StatusConditions returns a pointer to Status.Conditions slice. +func (r *TeleportRoleV7) StatusConditions() *[]metav1.Condition { + return &r.Status.Conditions +} diff --git a/integrations/operator/apis/resources/v1/zz_generated.deepcopy.go b/integrations/operator/apis/resources/v1/zz_generated.deepcopy.go index 65df96b7d764b..d72c199daf7b7 100644 --- a/integrations/operator/apis/resources/v1/zz_generated.deepcopy.go +++ b/integrations/operator/apis/resources/v1/zz_generated.deepcopy.go @@ -23,7 +23,6 @@ along with this program. If not, see . package v1 import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -96,28 +95,6 @@ func (in *TeleportAccessListSpec) DeepCopy() *TeleportAccessListSpec { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *TeleportAccessListStatus) DeepCopyInto(out *TeleportAccessListStatus) { - *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]metav1.Condition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TeleportAccessListStatus. -func (in *TeleportAccessListStatus) DeepCopy() *TeleportAccessListStatus { - if in == nil { - return nil - } - out := new(TeleportAccessListStatus) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TeleportLoginRule) DeepCopyInto(out *TeleportLoginRule) { *out = *in @@ -208,28 +185,6 @@ func (in *TeleportLoginRuleSpec) DeepCopy() *TeleportLoginRuleSpec { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *TeleportLoginRuleStatus) DeepCopyInto(out *TeleportLoginRuleStatus) { - *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]metav1.Condition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TeleportLoginRuleStatus. -func (in *TeleportLoginRuleStatus) DeepCopy() *TeleportLoginRuleStatus { - if in == nil { - return nil - } - out := new(TeleportLoginRuleStatus) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TeleportOktaImportRule) DeepCopyInto(out *TeleportOktaImportRule) { *out = *in @@ -376,23 +331,139 @@ func (in *TeleportOktaImportRuleSpec) DeepCopy() *TeleportOktaImportRuleSpec { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *TeleportOktaImportRuleStatus) DeepCopyInto(out *TeleportOktaImportRuleStatus) { +func (in *TeleportRoleV6) DeepCopyInto(out *TeleportRoleV6) { *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]metav1.Condition, len(*in)) + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TeleportRoleV6. +func (in *TeleportRoleV6) DeepCopy() *TeleportRoleV6 { + if in == nil { + return nil + } + out := new(TeleportRoleV6) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *TeleportRoleV6) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TeleportRoleV6List) DeepCopyInto(out *TeleportRoleV6List) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]TeleportRoleV6, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TeleportOktaImportRuleStatus. -func (in *TeleportOktaImportRuleStatus) DeepCopy() *TeleportOktaImportRuleStatus { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TeleportRoleV6List. +func (in *TeleportRoleV6List) DeepCopy() *TeleportRoleV6List { + if in == nil { + return nil + } + out := new(TeleportRoleV6List) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *TeleportRoleV6List) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TeleportRoleV6Spec. +func (in *TeleportRoleV6Spec) DeepCopy() *TeleportRoleV6Spec { + if in == nil { + return nil + } + out := new(TeleportRoleV6Spec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TeleportRoleV7) DeepCopyInto(out *TeleportRoleV7) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TeleportRoleV7. +func (in *TeleportRoleV7) DeepCopy() *TeleportRoleV7 { + if in == nil { + return nil + } + out := new(TeleportRoleV7) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *TeleportRoleV7) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TeleportRoleV7List) DeepCopyInto(out *TeleportRoleV7List) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]TeleportRoleV7, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TeleportRoleV7List. +func (in *TeleportRoleV7List) DeepCopy() *TeleportRoleV7List { + if in == nil { + return nil + } + out := new(TeleportRoleV7List) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *TeleportRoleV7List) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TeleportRoleV7Spec. +func (in *TeleportRoleV7Spec) DeepCopy() *TeleportRoleV7Spec { if in == nil { return nil } - out := new(TeleportOktaImportRuleStatus) + out := new(TeleportRoleV7Spec) in.DeepCopyInto(out) return out } diff --git a/integrations/operator/apis/resources/v2/provisiontoken_types.go b/integrations/operator/apis/resources/v2/provisiontoken_types.go index 63233b7fd035e..3a83abb98568b 100644 --- a/integrations/operator/apis/resources/v2/provisiontoken_types.go +++ b/integrations/operator/apis/resources/v2/provisiontoken_types.go @@ -32,15 +32,6 @@ func init() { // TeleportProvisionTokenSpec defines the desired state of TeleportProvisionToken type TeleportProvisionTokenSpec types.ProvisionTokenSpecV2 -// TeleportProvisionTokenStatus defines the observed state of TeleportProvisionToken -type TeleportProvisionTokenStatus struct { - // Conditions represent the latest available observations of an object's state - // +optional - Conditions []metav1.Condition `json:"conditions,omitempty"` - // +optional - TeleportResourceID int64 `json:"teleportResourceID,omitempty"` -} - //+kubebuilder:object:root=true //+kubebuilder:subresource:status @@ -49,8 +40,8 @@ type TeleportProvisionToken struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` - Spec TeleportProvisionTokenSpec `json:"spec,omitempty"` - Status TeleportProvisionTokenStatus `json:"status,omitempty"` + Spec TeleportProvisionTokenSpec `json:"spec,omitempty"` + Status resources.Status `json:"status,omitempty"` } //+kubebuilder:object:root=true diff --git a/integrations/operator/apis/resources/v2/samlconnector_types.go b/integrations/operator/apis/resources/v2/samlconnector_types.go index 5d8ba62eeb3e8..b7a31d78ed471 100644 --- a/integrations/operator/apis/resources/v2/samlconnector_types.go +++ b/integrations/operator/apis/resources/v2/samlconnector_types.go @@ -32,15 +32,6 @@ func init() { // TeleportSAMLConnectorSpec defines the desired state of TeleportSAMLConnector type TeleportSAMLConnectorSpec types.SAMLConnectorSpecV2 -// TeleportSAMLConnectorStatus defines the observed state of TeleportSAMLConnector -type TeleportSAMLConnectorStatus struct { - // Conditions represent the latest available observations of an object's state - // +optional - Conditions []metav1.Condition `json:"conditions,omitempty"` - // +optional - TeleportResourceID int64 `json:"teleportResourceID,omitempty"` -} - //+kubebuilder:object:root=true //+kubebuilder:subresource:status @@ -49,8 +40,8 @@ type TeleportSAMLConnector struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` - Spec TeleportSAMLConnectorSpec `json:"spec,omitempty"` - Status TeleportSAMLConnectorStatus `json:"status,omitempty"` + Spec TeleportSAMLConnectorSpec `json:"spec,omitempty"` + Status resources.Status `json:"status,omitempty"` } //+kubebuilder:object:root=true diff --git a/integrations/operator/apis/resources/v2/user_types.go b/integrations/operator/apis/resources/v2/user_types.go index e29d8e5148e4a..1043520d50a39 100644 --- a/integrations/operator/apis/resources/v2/user_types.go +++ b/integrations/operator/apis/resources/v2/user_types.go @@ -32,15 +32,6 @@ func init() { // TeleportUserSpec defines the desired state of TeleportUser type TeleportUserSpec types.UserSpecV2 -// TeleportUserStatus defines the observed state of TeleportUser -type TeleportUserStatus struct { - // Conditions represent the latest available observations of an object's state - // +optional - Conditions []metav1.Condition `json:"conditions,omitempty"` - // +optional - TeleportResourceID int64 `json:"teleportResourceID,omitempty"` -} - //+kubebuilder:object:root=true //+kubebuilder:subresource:status @@ -49,8 +40,8 @@ type TeleportUser struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` - Spec TeleportUserSpec `json:"spec,omitempty"` - Status TeleportUserStatus `json:"status,omitempty"` + Spec TeleportUserSpec `json:"spec,omitempty"` + Status resources.Status `json:"status,omitempty"` } //+kubebuilder:object:root=true diff --git a/integrations/operator/apis/resources/v2/zz_generated.deepcopy.go b/integrations/operator/apis/resources/v2/zz_generated.deepcopy.go index e08148579fd01..7310b23d61c62 100644 --- a/integrations/operator/apis/resources/v2/zz_generated.deepcopy.go +++ b/integrations/operator/apis/resources/v2/zz_generated.deepcopy.go @@ -23,7 +23,6 @@ along with this program. If not, see . package v2 import ( - "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -96,28 +95,6 @@ func (in *TeleportProvisionTokenSpec) DeepCopy() *TeleportProvisionTokenSpec { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *TeleportProvisionTokenStatus) DeepCopyInto(out *TeleportProvisionTokenStatus) { - *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]v1.Condition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TeleportProvisionTokenStatus. -func (in *TeleportProvisionTokenStatus) DeepCopy() *TeleportProvisionTokenStatus { - if in == nil { - return nil - } - out := new(TeleportProvisionTokenStatus) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TeleportSAMLConnector) DeepCopyInto(out *TeleportSAMLConnector) { *out = *in @@ -187,28 +164,6 @@ func (in *TeleportSAMLConnectorSpec) DeepCopy() *TeleportSAMLConnectorSpec { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *TeleportSAMLConnectorStatus) DeepCopyInto(out *TeleportSAMLConnectorStatus) { - *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]v1.Condition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TeleportSAMLConnectorStatus. -func (in *TeleportSAMLConnectorStatus) DeepCopy() *TeleportSAMLConnectorStatus { - if in == nil { - return nil - } - out := new(TeleportSAMLConnectorStatus) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TeleportUser) DeepCopyInto(out *TeleportUser) { *out = *in @@ -277,25 +232,3 @@ func (in *TeleportUserSpec) DeepCopy() *TeleportUserSpec { in.DeepCopyInto(out) return out } - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *TeleportUserStatus) DeepCopyInto(out *TeleportUserStatus) { - *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]v1.Condition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TeleportUserStatus. -func (in *TeleportUserStatus) DeepCopy() *TeleportUserStatus { - if in == nil { - return nil - } - out := new(TeleportUserStatus) - in.DeepCopyInto(out) - return out -} diff --git a/integrations/operator/apis/resources/v3/githubconnector_types.go b/integrations/operator/apis/resources/v3/githubconnector_types.go index 6f8c6ade74253..6de2c59209207 100644 --- a/integrations/operator/apis/resources/v3/githubconnector_types.go +++ b/integrations/operator/apis/resources/v3/githubconnector_types.go @@ -32,15 +32,6 @@ func init() { // TeleportGithubConnectorSpec defines the desired state of TeleportGithubConnector type TeleportGithubConnectorSpec types.GithubConnectorSpecV3 -// TeleportGithubConnectorStatus defines the observed state of TeleportGithubConnector -type TeleportGithubConnectorStatus struct { - // Conditions represent the latest available observations of an object's state - // +optional - Conditions []metav1.Condition `json:"conditions,omitempty"` - // +optional - TeleportResourceID int64 `json:"teleportResourceID,omitempty"` -} - //+kubebuilder:object:root=true //+kubebuilder:subresource:status @@ -49,8 +40,8 @@ type TeleportGithubConnector struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` - Spec TeleportGithubConnectorSpec `json:"spec,omitempty"` - Status TeleportGithubConnectorStatus `json:"status,omitempty"` + Spec TeleportGithubConnectorSpec `json:"spec,omitempty"` + Status resources.Status `json:"status,omitempty"` } //+kubebuilder:object:root=true diff --git a/integrations/operator/apis/resources/v3/oidcconnector_types.go b/integrations/operator/apis/resources/v3/oidcconnector_types.go index 02a8c8482068e..3eedf1d9b5264 100644 --- a/integrations/operator/apis/resources/v3/oidcconnector_types.go +++ b/integrations/operator/apis/resources/v3/oidcconnector_types.go @@ -34,15 +34,6 @@ func init() { // TeleportOIDCConnectorSpec defines the desired state of TeleportOIDCConnector type TeleportOIDCConnectorSpec types.OIDCConnectorSpecV3 -// TeleportOIDCConnectorStatus defines the observed state of TeleportOIDCConnector -type TeleportOIDCConnectorStatus struct { - // Conditions represent the latest available observations of an object's state - // +optional - Conditions []metav1.Condition `json:"conditions,omitempty"` - // +optional - TeleportResourceID int64 `json:"teleportResourceID,omitempty"` -} - //+kubebuilder:object:root=true //+kubebuilder:subresource:status @@ -51,8 +42,8 @@ type TeleportOIDCConnector struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` - Spec TeleportOIDCConnectorSpec `json:"spec,omitempty"` - Status TeleportOIDCConnectorStatus `json:"status,omitempty"` + Spec TeleportOIDCConnectorSpec `json:"spec,omitempty"` + Status resources.Status `json:"status,omitempty"` } //+kubebuilder:object:root=true diff --git a/integrations/operator/apis/resources/v3/zz_generated.deepcopy.go b/integrations/operator/apis/resources/v3/zz_generated.deepcopy.go index 3b06f2e539bd9..c46eb7ee65078 100644 --- a/integrations/operator/apis/resources/v3/zz_generated.deepcopy.go +++ b/integrations/operator/apis/resources/v3/zz_generated.deepcopy.go @@ -23,7 +23,6 @@ along with this program. If not, see . package v3 import ( - "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -96,28 +95,6 @@ func (in *TeleportGithubConnectorSpec) DeepCopy() *TeleportGithubConnectorSpec { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *TeleportGithubConnectorStatus) DeepCopyInto(out *TeleportGithubConnectorStatus) { - *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]v1.Condition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TeleportGithubConnectorStatus. -func (in *TeleportGithubConnectorStatus) DeepCopy() *TeleportGithubConnectorStatus { - if in == nil { - return nil - } - out := new(TeleportGithubConnectorStatus) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TeleportOIDCConnector) DeepCopyInto(out *TeleportOIDCConnector) { *out = *in @@ -186,25 +163,3 @@ func (in *TeleportOIDCConnectorSpec) DeepCopy() *TeleportOIDCConnectorSpec { in.DeepCopyInto(out) return out } - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *TeleportOIDCConnectorStatus) DeepCopyInto(out *TeleportOIDCConnectorStatus) { - *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]v1.Condition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TeleportOIDCConnectorStatus. -func (in *TeleportOIDCConnectorStatus) DeepCopy() *TeleportOIDCConnectorStatus { - if in == nil { - return nil - } - out := new(TeleportOIDCConnectorStatus) - in.DeepCopyInto(out) - return out -} diff --git a/integrations/operator/apis/resources/v5/role_types.go b/integrations/operator/apis/resources/v5/role_types.go index eccf839f567dd..64d11c7b274c9 100644 --- a/integrations/operator/apis/resources/v5/role_types.go +++ b/integrations/operator/apis/resources/v5/role_types.go @@ -32,15 +32,6 @@ func init() { // TeleportRoleSpec defines the desired state of TeleportRole type TeleportRoleSpec types.RoleSpecV6 -// TeleportRoleStatus defines the observed state of TeleportRole -type TeleportRoleStatus struct { - // Conditions represent the latest available observations of an object's state - // +optional - Conditions []metav1.Condition `json:"conditions"` - // +optional - TeleportResourceID int64 `json:"teleportResourceID"` -} - //+kubebuilder:object:root=true //+kubebuilder:subresource:status @@ -49,8 +40,8 @@ type TeleportRole struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` - Spec TeleportRoleSpec `json:"spec,omitempty"` - Status TeleportRoleStatus `json:"status,omitempty"` + Spec TeleportRoleSpec `json:"spec,omitempty"` + Status resources.Status `json:"status,omitempty"` } //+kubebuilder:object:root=true diff --git a/integrations/operator/apis/resources/v5/zz_generated.deepcopy.go b/integrations/operator/apis/resources/v5/zz_generated.deepcopy.go index 58d67381aacb5..e78d327215bfb 100644 --- a/integrations/operator/apis/resources/v5/zz_generated.deepcopy.go +++ b/integrations/operator/apis/resources/v5/zz_generated.deepcopy.go @@ -23,7 +23,6 @@ along with this program. If not, see . package v5 import ( - "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -95,25 +94,3 @@ func (in *TeleportRoleSpec) DeepCopy() *TeleportRoleSpec { in.DeepCopyInto(out) return out } - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *TeleportRoleStatus) DeepCopyInto(out *TeleportRoleStatus) { - *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]v1.Condition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TeleportRoleStatus. -func (in *TeleportRoleStatus) DeepCopy() *TeleportRoleStatus { - if in == nil { - return nil - } - out := new(TeleportRoleStatus) - in.DeepCopyInto(out) - return out -} diff --git a/integrations/operator/apis/resources/v6/zz_generated.deepcopy.go b/integrations/operator/apis/resources/v6/zz_generated.deepcopy.go deleted file mode 100644 index a600ce7541d51..0000000000000 --- a/integrations/operator/apis/resources/v6/zz_generated.deepcopy.go +++ /dev/null @@ -1,119 +0,0 @@ -//go:build !ignore_autogenerated - -/* -Teleport -Copyright (C) 2023 Gravitational, Inc. - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . -*/ - -// Code generated by controller-gen. DO NOT EDIT. - -package v6 - -import ( - "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" -) - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *TeleportRole) DeepCopyInto(out *TeleportRole) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TeleportRole. -func (in *TeleportRole) DeepCopy() *TeleportRole { - if in == nil { - return nil - } - out := new(TeleportRole) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *TeleportRole) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *TeleportRoleList) DeepCopyInto(out *TeleportRoleList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]TeleportRole, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TeleportRoleList. -func (in *TeleportRoleList) DeepCopy() *TeleportRoleList { - if in == nil { - return nil - } - out := new(TeleportRoleList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *TeleportRoleList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TeleportRoleSpec. -func (in *TeleportRoleSpec) DeepCopy() *TeleportRoleSpec { - if in == nil { - return nil - } - out := new(TeleportRoleSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *TeleportRoleStatus) DeepCopyInto(out *TeleportRoleStatus) { - *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]v1.Condition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TeleportRoleStatus. -func (in *TeleportRoleStatus) DeepCopy() *TeleportRoleStatus { - if in == nil { - return nil - } - out := new(TeleportRoleStatus) - in.DeepCopyInto(out) - return out -} diff --git a/integrations/operator/config/crd/bases/resources.teleport.dev_accesslists.yaml b/integrations/operator/config/crd/bases/resources.teleport.dev_accesslists.yaml index 6d10aac334e7e..2e6e599ceb9bb 100644 --- a/integrations/operator/config/crd/bases/resources.teleport.dev_accesslists.yaml +++ b/integrations/operator/config/crd/bases/resources.teleport.dev_accesslists.yaml @@ -201,6 +201,7 @@ spec: type: string type: object status: + description: Status defines the observed state of the Teleport resource properties: conditions: description: Conditions represent the latest available observations diff --git a/integrations/operator/config/crd/bases/resources.teleport.dev_githubconnectors.yaml b/integrations/operator/config/crd/bases/resources.teleport.dev_githubconnectors.yaml index a262e618b0154..b96d4eb6e8734 100644 --- a/integrations/operator/config/crd/bases/resources.teleport.dev_githubconnectors.yaml +++ b/integrations/operator/config/crd/bases/resources.teleport.dev_githubconnectors.yaml @@ -78,8 +78,7 @@ spec: type: array type: object status: - description: TeleportGithubConnectorStatus defines the observed state - of TeleportGithubConnector + description: Status defines the observed state of the Teleport resource properties: conditions: description: Conditions represent the latest available observations diff --git a/integrations/operator/config/crd/bases/resources.teleport.dev_loginrules.yaml b/integrations/operator/config/crd/bases/resources.teleport.dev_loginrules.yaml index cdb3a30050b51..7b5928ca4c255 100644 --- a/integrations/operator/config/crd/bases/resources.teleport.dev_loginrules.yaml +++ b/integrations/operator/config/crd/bases/resources.teleport.dev_loginrules.yaml @@ -57,6 +57,7 @@ spec: type: object type: object status: + description: Status defines the observed state of the Teleport resource properties: conditions: description: Conditions represent the latest available observations diff --git a/integrations/operator/config/crd/bases/resources.teleport.dev_oidcconnectors.yaml b/integrations/operator/config/crd/bases/resources.teleport.dev_oidcconnectors.yaml index edd8bf5e13623..087bdc7d4a4b1 100644 --- a/integrations/operator/config/crd/bases/resources.teleport.dev_oidcconnectors.yaml +++ b/integrations/operator/config/crd/bases/resources.teleport.dev_oidcconnectors.yaml @@ -123,8 +123,7 @@ spec: type: string type: object status: - description: TeleportOIDCConnectorStatus defines the observed state of - TeleportOIDCConnector + description: Status defines the observed state of the Teleport resource properties: conditions: description: Conditions represent the latest available observations diff --git a/integrations/operator/config/crd/bases/resources.teleport.dev_oktaimportrules.yaml b/integrations/operator/config/crd/bases/resources.teleport.dev_oktaimportrules.yaml index b16ac422df459..f6077e45c357f 100644 --- a/integrations/operator/config/crd/bases/resources.teleport.dev_oktaimportrules.yaml +++ b/integrations/operator/config/crd/bases/resources.teleport.dev_oktaimportrules.yaml @@ -95,6 +95,7 @@ spec: type: integer type: object status: + description: Status defines the observed state of the Teleport resource properties: conditions: description: Conditions represent the latest available observations diff --git a/integrations/operator/config/crd/bases/resources.teleport.dev_provisiontokens.yaml b/integrations/operator/config/crd/bases/resources.teleport.dev_provisiontokens.yaml index 25220e897f131..4aac7487fb0ef 100644 --- a/integrations/operator/config/crd/bases/resources.teleport.dev_provisiontokens.yaml +++ b/integrations/operator/config/crd/bases/resources.teleport.dev_provisiontokens.yaml @@ -330,8 +330,7 @@ spec: type: object type: object status: - description: TeleportProvisionTokenStatus defines the observed state of - TeleportProvisionToken + description: Status defines the observed state of the Teleport resource properties: conditions: description: Conditions represent the latest available observations diff --git a/integrations/operator/config/crd/bases/resources.teleport.dev_roles.yaml b/integrations/operator/config/crd/bases/resources.teleport.dev_roles.yaml index 0864c45169eee..63847d593f9a8 100644 --- a/integrations/operator/config/crd/bases/resources.teleport.dev_roles.yaml +++ b/integrations/operator/config/crd/bases/resources.teleport.dev_roles.yaml @@ -1128,7 +1128,7 @@ spec: type: object type: object status: - description: TeleportRoleStatus defines the observed state of TeleportRole + description: Status defines the observed state of the Teleport resource properties: conditions: description: Conditions represent the latest available observations @@ -2326,7 +2326,7 @@ spec: type: object type: object status: - description: TeleportRoleStatus defines the observed state of TeleportRole + description: Status defines the observed state of the Teleport resource properties: conditions: description: Conditions represent the latest available observations diff --git a/integrations/operator/config/crd/bases/resources.teleport.dev_rolesv6.yaml b/integrations/operator/config/crd/bases/resources.teleport.dev_rolesv6.yaml new file mode 100644 index 0000000000000..709643feec3a1 --- /dev/null +++ b/integrations/operator/config/crd/bases/resources.teleport.dev_rolesv6.yaml @@ -0,0 +1,1221 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + name: teleportrolesv6.resources.teleport.dev +spec: + group: resources.teleport.dev + names: + kind: TeleportRoleV6 + listKind: TeleportRoleV6List + plural: teleportrolesv6 + shortNames: + - rolev6 + - rolesv6 + singular: teleportrolev6 + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: RoleV6 is the Schema for the rolesv6 API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Role resource definition v6 from Teleport + properties: + allow: + description: Allow is the set of conditions evaluated to grant access. + properties: + app_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: AppLabels is a map of labels used as part of the + RBAC system. + type: object + app_labels_expression: + description: AppLabelsExpression is a predicate expression used + to allow/deny access to Apps. + type: string + aws_role_arns: + description: AWSRoleARNs is a list of AWS role ARNs this role + is allowed to assume. + items: + type: string + nullable: true + type: array + azure_identities: + description: AzureIdentities is a list of Azure identities this + role is allowed to assume. + items: + type: string + nullable: true + type: array + cluster_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: ClusterLabels is a map of node labels (used to dynamically + grant access to clusters). + type: object + cluster_labels_expression: + description: ClusterLabelsExpression is a predicate expression + used to allow/deny access to remote Teleport clusters. + type: string + db_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: DatabaseLabels are used in RBAC system to allow/deny + access to databases. + type: object + db_labels_expression: + description: DatabaseLabelsExpression is a predicate expression + used to allow/deny access to Databases. + type: string + db_names: + description: DatabaseNames is a list of database names this role + is allowed to connect to. + items: + type: string + nullable: true + type: array + db_roles: + description: DatabaseRoles is a list of databases roles for automatic + user creation. + items: + type: string + nullable: true + type: array + db_service_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: DatabaseServiceLabels are used in RBAC system to + allow/deny access to Database Services. + type: object + db_service_labels_expression: + description: DatabaseServiceLabelsExpression is a predicate expression + used to allow/deny access to Database Services. + type: string + db_users: + description: DatabaseUsers is a list of databases users this role + is allowed to connect as. + items: + type: string + nullable: true + type: array + desktop_groups: + description: DesktopGroups is a list of groups for created desktop + users to be added to + items: + type: string + nullable: true + type: array + gcp_service_accounts: + description: GCPServiceAccounts is a list of GCP service accounts + this role is allowed to assume. + items: + type: string + nullable: true + type: array + group_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: GroupLabels is a map of labels used as part of the + RBAC system. + type: object + group_labels_expression: + description: GroupLabelsExpression is a predicate expression used + to allow/deny access to user groups. + type: string + host_groups: + description: HostGroups is a list of groups for created users + to be added to + items: + type: string + nullable: true + type: array + host_sudoers: + description: HostSudoers is a list of entries to include in a + users sudoer file + items: + type: string + nullable: true + type: array + impersonate: + description: Impersonate specifies what users and roles this role + is allowed to impersonate by issuing certificates or other possible + means. + nullable: true + properties: + roles: + description: Roles is a list of resources this role is allowed + to impersonate + items: + type: string + nullable: true + type: array + users: + description: Users is a list of resources this role is allowed + to impersonate, could be an empty list or a Wildcard pattern + items: + type: string + nullable: true + type: array + where: + description: Where specifies optional advanced matcher + type: string + type: object + join_sessions: + description: JoinSessions specifies policies to allow users to + join other sessions. + items: + properties: + kinds: + description: Kinds are the session kinds this policy applies + to. + items: + type: string + nullable: true + type: array + modes: + description: Modes is a list of permitted participant modes + for this policy. + items: + type: string + nullable: true + type: array + name: + description: Name is the name of the policy. + type: string + roles: + description: Roles is a list of roles that you can join + the session of. + items: + type: string + nullable: true + type: array + type: object + nullable: true + type: array + kubernetes_groups: + description: KubeGroups is a list of kubernetes groups + items: + type: string + nullable: true + type: array + kubernetes_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: KubernetesLabels is a map of kubernetes cluster labels + used for RBAC. + type: object + kubernetes_labels_expression: + description: KubernetesLabelsExpression is a predicate expression + used to allow/deny access to kubernetes clusters. + type: string + kubernetes_resources: + description: KubernetesResources is the Kubernetes Resources this + Role grants access to. + items: + properties: + kind: + description: Kind specifies the Kubernetes Resource type. + At the moment only "pod" is supported. + type: string + name: + description: Name is the resource name. It supports wildcards. + type: string + namespace: + description: Namespace is the resource namespace. It supports + wildcards. + type: string + verbs: + description: Verbs are the allowed Kubernetes verbs for + the following resource. + items: + type: string + nullable: true + type: array + type: object + type: array + kubernetes_users: + description: KubeUsers is an optional kubernetes users to impersonate + items: + type: string + nullable: true + type: array + logins: + description: Logins is a list of *nix system logins. + items: + type: string + nullable: true + type: array + node_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: NodeLabels is a map of node labels (used to dynamically + grant access to nodes). + type: object + node_labels_expression: + description: NodeLabelsExpression is a predicate expression used + to allow/deny access to SSH nodes. + type: string + request: + nullable: true + properties: + annotations: + additionalProperties: + items: + type: string + type: array + description: Annotations is a collection of annotations to + be programmatically appended to pending access requests + at the time of their creation. These annotations serve as + a mechanism to propagate extra information to plugins. Since + these annotations support variable interpolation syntax, + they also offer a mechanism for forwarding claims from an + external identity provider, to a plugin via `{{external.trait_name}}` + style substitutions. + type: object + claims_to_roles: + description: ClaimsToRoles specifies a mapping from claims + (traits) to teleport roles. + items: + properties: + claim: + description: Claim is a claim name. + type: string + roles: + description: Roles is a list of static teleport roles + to match. + items: + type: string + nullable: true + type: array + value: + description: Value is a claim value to match. + type: string + type: object + type: array + max_duration: + description: MaxDuration is the amount of time the access + will be granted for. If this is zero, the default duration + is used. + format: duration + type: string + roles: + description: Roles is the name of roles which will match the + request rule. + items: + type: string + nullable: true + type: array + search_as_roles: + description: SearchAsRoles is a list of extra roles which + should apply to a user while they are searching for resources + as part of a Resource Access Request, and defines the underlying + roles which will be requested as part of any Resource Access + Request. + items: + type: string + nullable: true + type: array + suggested_reviewers: + description: SuggestedReviewers is a list of reviewer suggestions. These + can be teleport usernames, but that is not a requirement. + items: + type: string + nullable: true + type: array + thresholds: + description: Thresholds is a list of thresholds, one of which + must be met in order for reviews to trigger a state-transition. If + no thresholds are provided, a default threshold of 1 for + approval and denial is used. + items: + properties: + approve: + description: Approve is the number of matching approvals + needed for state-transition. + format: int32 + type: integer + deny: + description: Deny is the number of denials needed for + state-transition. + format: int32 + type: integer + filter: + description: Filter is an optional predicate used to + determine which reviews count toward this threshold. + type: string + name: + description: Name is the optional human-readable name + of the threshold. + type: string + type: object + type: array + type: object + require_session_join: + description: RequireSessionJoin specifies policies for required + users to start a session. + items: + properties: + count: + description: Count is the amount of people that need to + be matched for this policy to be fulfilled. + format: int32 + type: integer + filter: + description: Filter is a predicate that determines what + users count towards this policy. + type: string + kinds: + description: Kinds are the session kinds this policy applies + to. + items: + type: string + nullable: true + type: array + modes: + description: Modes is the list of modes that may be used + to fulfill this policy. + items: + type: string + nullable: true + type: array + name: + description: Name is the name of the policy. + type: string + on_leave: + description: OnLeave is the behaviour that's used when the + policy is no longer fulfilled for a live session. + type: string + type: object + nullable: true + type: array + review_requests: + description: ReviewRequests defines conditions for submitting + access reviews. + nullable: true + properties: + claims_to_roles: + description: ClaimsToRoles specifies a mapping from claims + (traits) to teleport roles. + items: + properties: + claim: + description: Claim is a claim name. + type: string + roles: + description: Roles is a list of static teleport roles + to match. + items: + type: string + nullable: true + type: array + value: + description: Value is a claim value to match. + type: string + type: object + type: array + preview_as_roles: + description: PreviewAsRoles is a list of extra roles which + should apply to a reviewer while they are viewing a Resource + Access Request for the purposes of viewing details such + as the hostname and labels of requested resources. + items: + type: string + nullable: true + type: array + roles: + description: Roles is the name of roles which may be reviewed. + items: + type: string + nullable: true + type: array + where: + description: Where is an optional predicate which further + limits which requests are reviewable. + type: string + type: object + rules: + description: Rules is a list of rules and their access levels. + Rules are a high level construct used for access control. + items: + properties: + actions: + description: Actions specifies optional actions taken when + this rule matches + items: + type: string + nullable: true + type: array + resources: + description: Resources is a list of resources + items: + type: string + nullable: true + type: array + verbs: + description: Verbs is a list of verbs + items: + type: string + nullable: true + type: array + where: + description: Where specifies optional advanced matcher + type: string + type: object + type: array + windows_desktop_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: WindowsDesktopLabels are used in the RBAC system + to allow/deny access to Windows desktops. + type: object + windows_desktop_labels_expression: + description: WindowsDesktopLabelsExpression is a predicate expression + used to allow/deny access to Windows desktops. + type: string + windows_desktop_logins: + description: WindowsDesktopLogins is a list of desktop login names + allowed/denied for Windows desktops. + items: + type: string + nullable: true + type: array + type: object + deny: + description: Deny is the set of conditions evaluated to deny access. + Deny takes priority over allow. + properties: + app_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: AppLabels is a map of labels used as part of the + RBAC system. + type: object + app_labels_expression: + description: AppLabelsExpression is a predicate expression used + to allow/deny access to Apps. + type: string + aws_role_arns: + description: AWSRoleARNs is a list of AWS role ARNs this role + is allowed to assume. + items: + type: string + nullable: true + type: array + azure_identities: + description: AzureIdentities is a list of Azure identities this + role is allowed to assume. + items: + type: string + nullable: true + type: array + cluster_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: ClusterLabels is a map of node labels (used to dynamically + grant access to clusters). + type: object + cluster_labels_expression: + description: ClusterLabelsExpression is a predicate expression + used to allow/deny access to remote Teleport clusters. + type: string + db_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: DatabaseLabels are used in RBAC system to allow/deny + access to databases. + type: object + db_labels_expression: + description: DatabaseLabelsExpression is a predicate expression + used to allow/deny access to Databases. + type: string + db_names: + description: DatabaseNames is a list of database names this role + is allowed to connect to. + items: + type: string + nullable: true + type: array + db_roles: + description: DatabaseRoles is a list of databases roles for automatic + user creation. + items: + type: string + nullable: true + type: array + db_service_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: DatabaseServiceLabels are used in RBAC system to + allow/deny access to Database Services. + type: object + db_service_labels_expression: + description: DatabaseServiceLabelsExpression is a predicate expression + used to allow/deny access to Database Services. + type: string + db_users: + description: DatabaseUsers is a list of databases users this role + is allowed to connect as. + items: + type: string + nullable: true + type: array + desktop_groups: + description: DesktopGroups is a list of groups for created desktop + users to be added to + items: + type: string + nullable: true + type: array + gcp_service_accounts: + description: GCPServiceAccounts is a list of GCP service accounts + this role is allowed to assume. + items: + type: string + nullable: true + type: array + group_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: GroupLabels is a map of labels used as part of the + RBAC system. + type: object + group_labels_expression: + description: GroupLabelsExpression is a predicate expression used + to allow/deny access to user groups. + type: string + host_groups: + description: HostGroups is a list of groups for created users + to be added to + items: + type: string + nullable: true + type: array + host_sudoers: + description: HostSudoers is a list of entries to include in a + users sudoer file + items: + type: string + nullable: true + type: array + impersonate: + description: Impersonate specifies what users and roles this role + is allowed to impersonate by issuing certificates or other possible + means. + nullable: true + properties: + roles: + description: Roles is a list of resources this role is allowed + to impersonate + items: + type: string + nullable: true + type: array + users: + description: Users is a list of resources this role is allowed + to impersonate, could be an empty list or a Wildcard pattern + items: + type: string + nullable: true + type: array + where: + description: Where specifies optional advanced matcher + type: string + type: object + join_sessions: + description: JoinSessions specifies policies to allow users to + join other sessions. + items: + properties: + kinds: + description: Kinds are the session kinds this policy applies + to. + items: + type: string + nullable: true + type: array + modes: + description: Modes is a list of permitted participant modes + for this policy. + items: + type: string + nullable: true + type: array + name: + description: Name is the name of the policy. + type: string + roles: + description: Roles is a list of roles that you can join + the session of. + items: + type: string + nullable: true + type: array + type: object + nullable: true + type: array + kubernetes_groups: + description: KubeGroups is a list of kubernetes groups + items: + type: string + nullable: true + type: array + kubernetes_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: KubernetesLabels is a map of kubernetes cluster labels + used for RBAC. + type: object + kubernetes_labels_expression: + description: KubernetesLabelsExpression is a predicate expression + used to allow/deny access to kubernetes clusters. + type: string + kubernetes_resources: + description: KubernetesResources is the Kubernetes Resources this + Role grants access to. + items: + properties: + kind: + description: Kind specifies the Kubernetes Resource type. + At the moment only "pod" is supported. + type: string + name: + description: Name is the resource name. It supports wildcards. + type: string + namespace: + description: Namespace is the resource namespace. It supports + wildcards. + type: string + verbs: + description: Verbs are the allowed Kubernetes verbs for + the following resource. + items: + type: string + nullable: true + type: array + type: object + type: array + kubernetes_users: + description: KubeUsers is an optional kubernetes users to impersonate + items: + type: string + nullable: true + type: array + logins: + description: Logins is a list of *nix system logins. + items: + type: string + nullable: true + type: array + node_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: NodeLabels is a map of node labels (used to dynamically + grant access to nodes). + type: object + node_labels_expression: + description: NodeLabelsExpression is a predicate expression used + to allow/deny access to SSH nodes. + type: string + request: + nullable: true + properties: + annotations: + additionalProperties: + items: + type: string + type: array + description: Annotations is a collection of annotations to + be programmatically appended to pending access requests + at the time of their creation. These annotations serve as + a mechanism to propagate extra information to plugins. Since + these annotations support variable interpolation syntax, + they also offer a mechanism for forwarding claims from an + external identity provider, to a plugin via `{{external.trait_name}}` + style substitutions. + type: object + claims_to_roles: + description: ClaimsToRoles specifies a mapping from claims + (traits) to teleport roles. + items: + properties: + claim: + description: Claim is a claim name. + type: string + roles: + description: Roles is a list of static teleport roles + to match. + items: + type: string + nullable: true + type: array + value: + description: Value is a claim value to match. + type: string + type: object + type: array + max_duration: + description: MaxDuration is the amount of time the access + will be granted for. If this is zero, the default duration + is used. + format: duration + type: string + roles: + description: Roles is the name of roles which will match the + request rule. + items: + type: string + nullable: true + type: array + search_as_roles: + description: SearchAsRoles is a list of extra roles which + should apply to a user while they are searching for resources + as part of a Resource Access Request, and defines the underlying + roles which will be requested as part of any Resource Access + Request. + items: + type: string + nullable: true + type: array + suggested_reviewers: + description: SuggestedReviewers is a list of reviewer suggestions. These + can be teleport usernames, but that is not a requirement. + items: + type: string + nullable: true + type: array + thresholds: + description: Thresholds is a list of thresholds, one of which + must be met in order for reviews to trigger a state-transition. If + no thresholds are provided, a default threshold of 1 for + approval and denial is used. + items: + properties: + approve: + description: Approve is the number of matching approvals + needed for state-transition. + format: int32 + type: integer + deny: + description: Deny is the number of denials needed for + state-transition. + format: int32 + type: integer + filter: + description: Filter is an optional predicate used to + determine which reviews count toward this threshold. + type: string + name: + description: Name is the optional human-readable name + of the threshold. + type: string + type: object + type: array + type: object + require_session_join: + description: RequireSessionJoin specifies policies for required + users to start a session. + items: + properties: + count: + description: Count is the amount of people that need to + be matched for this policy to be fulfilled. + format: int32 + type: integer + filter: + description: Filter is a predicate that determines what + users count towards this policy. + type: string + kinds: + description: Kinds are the session kinds this policy applies + to. + items: + type: string + nullable: true + type: array + modes: + description: Modes is the list of modes that may be used + to fulfill this policy. + items: + type: string + nullable: true + type: array + name: + description: Name is the name of the policy. + type: string + on_leave: + description: OnLeave is the behaviour that's used when the + policy is no longer fulfilled for a live session. + type: string + type: object + nullable: true + type: array + review_requests: + description: ReviewRequests defines conditions for submitting + access reviews. + nullable: true + properties: + claims_to_roles: + description: ClaimsToRoles specifies a mapping from claims + (traits) to teleport roles. + items: + properties: + claim: + description: Claim is a claim name. + type: string + roles: + description: Roles is a list of static teleport roles + to match. + items: + type: string + nullable: true + type: array + value: + description: Value is a claim value to match. + type: string + type: object + type: array + preview_as_roles: + description: PreviewAsRoles is a list of extra roles which + should apply to a reviewer while they are viewing a Resource + Access Request for the purposes of viewing details such + as the hostname and labels of requested resources. + items: + type: string + nullable: true + type: array + roles: + description: Roles is the name of roles which may be reviewed. + items: + type: string + nullable: true + type: array + where: + description: Where is an optional predicate which further + limits which requests are reviewable. + type: string + type: object + rules: + description: Rules is a list of rules and their access levels. + Rules are a high level construct used for access control. + items: + properties: + actions: + description: Actions specifies optional actions taken when + this rule matches + items: + type: string + nullable: true + type: array + resources: + description: Resources is a list of resources + items: + type: string + nullable: true + type: array + verbs: + description: Verbs is a list of verbs + items: + type: string + nullable: true + type: array + where: + description: Where specifies optional advanced matcher + type: string + type: object + type: array + windows_desktop_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: WindowsDesktopLabels are used in the RBAC system + to allow/deny access to Windows desktops. + type: object + windows_desktop_labels_expression: + description: WindowsDesktopLabelsExpression is a predicate expression + used to allow/deny access to Windows desktops. + type: string + windows_desktop_logins: + description: WindowsDesktopLogins is a list of desktop login names + allowed/denied for Windows desktops. + items: + type: string + nullable: true + type: array + type: object + options: + description: Options is for OpenSSH options like agent forwarding. + properties: + cert_extensions: + description: CertExtensions specifies the key/values + items: + properties: + mode: + description: Mode is the type of extension to be used -- + currently critical-option is not supported + x-kubernetes-int-or-string: true + name: + description: Name specifies the key to be used in the cert + extension. + type: string + type: + description: Type represents the certificate type being + extended, only ssh is supported at this time. + x-kubernetes-int-or-string: true + value: + description: Value specifies the value to be used in the + cert extension. + type: string + type: object + nullable: true + type: array + cert_format: + description: CertificateFormat defines the format of the user + certificate to allow compatibility with older versions of OpenSSH. + type: string + client_idle_timeout: + description: ClientIdleTimeout sets disconnect clients on idle + timeout behavior, if set to 0 means do not disconnect, otherwise + is set to the idle duration. + format: duration + type: string + create_db_user: + description: CreateDatabaseUser enabled automatic database user + creation. + type: boolean + create_db_user_mode: + description: CreateDatabaseUserMode allows users to be automatically + created on a database when not set to off. + x-kubernetes-int-or-string: true + create_desktop_user: + description: CreateDesktopUser allows users to be automatically + created on a Windows desktop + type: boolean + create_host_user: + description: CreateHostUser allows users to be automatically created + on a host + type: boolean + create_host_user_mode: + description: CreateHostUserMode allows users to be automatically + created on a host when not set to off + x-kubernetes-int-or-string: true + desktop_clipboard: + description: DesktopClipboard indicates whether clipboard sharing + is allowed between the user's workstation and the remote desktop. + It defaults to true unless explicitly set to false. + type: boolean + desktop_directory_sharing: + description: DesktopDirectorySharing indicates whether directory + sharing is allowed between the user's workstation and the remote + desktop. It defaults to false unless explicitly set to true. + type: boolean + device_trust_mode: + description: DeviceTrustMode is the device authorization mode + used for the resources associated with the role. See DeviceTrust.Mode. + Reserved for future use, not yet used by Teleport. + type: string + disconnect_expired_cert: + description: DisconnectExpiredCert sets disconnect clients on + expired certificates. + type: boolean + enhanced_recording: + description: BPF defines what events to record for the BPF-based + session recorder. + items: + type: string + nullable: true + type: array + forward_agent: + description: ForwardAgent is SSH agent forwarding. + type: boolean + idp: + description: IDP is a set of options related to accessing IdPs + within Teleport. Requires Teleport Enterprise. + nullable: true + properties: + saml: + description: SAML are options related to the Teleport SAML + IdP. + nullable: true + properties: + enabled: + description: Enabled is set to true if this option allows + access to the Teleport SAML IdP. + type: boolean + type: object + type: object + lock: + description: Lock specifies the locking mode (strict|best_effort) + to be applied with the role. + type: string + max_connections: + description: MaxConnections defines the maximum number of concurrent + connections a user may hold. + format: int64 + type: integer + max_kubernetes_connections: + description: MaxKubernetesConnections defines the maximum number + of concurrent Kubernetes sessions a user may hold. + format: int64 + type: integer + max_session_ttl: + description: MaxSessionTTL defines how long a SSH session can + last for. + format: duration + type: string + max_sessions: + description: MaxSessions defines the maximum number of concurrent + sessions per connection. + format: int64 + type: integer + permit_x11_forwarding: + description: PermitX11Forwarding authorizes use of X11 forwarding. + type: boolean + pin_source_ip: + description: PinSourceIP forces the same client IP for certificate + generation and usage + type: boolean + port_forwarding: + description: PortForwarding defines if the certificate will have + "permit-port-forwarding" in the certificate. PortForwarding + is "yes" if not set, that's why this is a pointer + type: boolean + record_session: + description: RecordDesktopSession indicates whether desktop access + sessions should be recorded. It defaults to true unless explicitly + set to false. + nullable: true + properties: + default: + description: Default indicates the default value for the services. + type: string + desktop: + description: Desktop indicates whether desktop sessions should + be recorded. It defaults to true unless explicitly set to + false. + type: boolean + ssh: + description: SSH indicates the session mode used on SSH sessions. + type: string + type: object + request_access: + description: RequestAccess defines the access request strategy + (optional|note|always) where optional is the default. + type: string + request_prompt: + description: RequestPrompt is an optional message which tells + users what they aught to request. + type: string + require_session_mfa: + description: RequireMFAType is the type of MFA requirement enforced + for this user. + x-kubernetes-int-or-string: true + ssh_file_copy: + description: SSHFileCopy indicates whether remote file operations + via SCP or SFTP are allowed over an SSH session. It defaults + to true unless explicitly set to false. + type: boolean + type: object + type: object + status: + description: Status defines the observed state of the Teleport resource + properties: + conditions: + description: Conditions represent the latest available observations + of an object's state + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + teleportResourceID: + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/integrations/operator/config/crd/bases/resources.teleport.dev_rolesv7.yaml b/integrations/operator/config/crd/bases/resources.teleport.dev_rolesv7.yaml new file mode 100644 index 0000000000000..75363e092b2e8 --- /dev/null +++ b/integrations/operator/config/crd/bases/resources.teleport.dev_rolesv7.yaml @@ -0,0 +1,1221 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + name: teleportrolesv7.resources.teleport.dev +spec: + group: resources.teleport.dev + names: + kind: TeleportRoleV7 + listKind: TeleportRoleV7List + plural: teleportrolesv7 + shortNames: + - rolev7 + - rolesv7 + singular: teleportrolev7 + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: RoleV7 is the Schema for the rolesv7 API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Role resource definition v7 from Teleport + properties: + allow: + description: Allow is the set of conditions evaluated to grant access. + properties: + app_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: AppLabels is a map of labels used as part of the + RBAC system. + type: object + app_labels_expression: + description: AppLabelsExpression is a predicate expression used + to allow/deny access to Apps. + type: string + aws_role_arns: + description: AWSRoleARNs is a list of AWS role ARNs this role + is allowed to assume. + items: + type: string + nullable: true + type: array + azure_identities: + description: AzureIdentities is a list of Azure identities this + role is allowed to assume. + items: + type: string + nullable: true + type: array + cluster_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: ClusterLabels is a map of node labels (used to dynamically + grant access to clusters). + type: object + cluster_labels_expression: + description: ClusterLabelsExpression is a predicate expression + used to allow/deny access to remote Teleport clusters. + type: string + db_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: DatabaseLabels are used in RBAC system to allow/deny + access to databases. + type: object + db_labels_expression: + description: DatabaseLabelsExpression is a predicate expression + used to allow/deny access to Databases. + type: string + db_names: + description: DatabaseNames is a list of database names this role + is allowed to connect to. + items: + type: string + nullable: true + type: array + db_roles: + description: DatabaseRoles is a list of databases roles for automatic + user creation. + items: + type: string + nullable: true + type: array + db_service_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: DatabaseServiceLabels are used in RBAC system to + allow/deny access to Database Services. + type: object + db_service_labels_expression: + description: DatabaseServiceLabelsExpression is a predicate expression + used to allow/deny access to Database Services. + type: string + db_users: + description: DatabaseUsers is a list of databases users this role + is allowed to connect as. + items: + type: string + nullable: true + type: array + desktop_groups: + description: DesktopGroups is a list of groups for created desktop + users to be added to + items: + type: string + nullable: true + type: array + gcp_service_accounts: + description: GCPServiceAccounts is a list of GCP service accounts + this role is allowed to assume. + items: + type: string + nullable: true + type: array + group_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: GroupLabels is a map of labels used as part of the + RBAC system. + type: object + group_labels_expression: + description: GroupLabelsExpression is a predicate expression used + to allow/deny access to user groups. + type: string + host_groups: + description: HostGroups is a list of groups for created users + to be added to + items: + type: string + nullable: true + type: array + host_sudoers: + description: HostSudoers is a list of entries to include in a + users sudoer file + items: + type: string + nullable: true + type: array + impersonate: + description: Impersonate specifies what users and roles this role + is allowed to impersonate by issuing certificates or other possible + means. + nullable: true + properties: + roles: + description: Roles is a list of resources this role is allowed + to impersonate + items: + type: string + nullable: true + type: array + users: + description: Users is a list of resources this role is allowed + to impersonate, could be an empty list or a Wildcard pattern + items: + type: string + nullable: true + type: array + where: + description: Where specifies optional advanced matcher + type: string + type: object + join_sessions: + description: JoinSessions specifies policies to allow users to + join other sessions. + items: + properties: + kinds: + description: Kinds are the session kinds this policy applies + to. + items: + type: string + nullable: true + type: array + modes: + description: Modes is a list of permitted participant modes + for this policy. + items: + type: string + nullable: true + type: array + name: + description: Name is the name of the policy. + type: string + roles: + description: Roles is a list of roles that you can join + the session of. + items: + type: string + nullable: true + type: array + type: object + nullable: true + type: array + kubernetes_groups: + description: KubeGroups is a list of kubernetes groups + items: + type: string + nullable: true + type: array + kubernetes_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: KubernetesLabels is a map of kubernetes cluster labels + used for RBAC. + type: object + kubernetes_labels_expression: + description: KubernetesLabelsExpression is a predicate expression + used to allow/deny access to kubernetes clusters. + type: string + kubernetes_resources: + description: KubernetesResources is the Kubernetes Resources this + Role grants access to. + items: + properties: + kind: + description: Kind specifies the Kubernetes Resource type. + At the moment only "pod" is supported. + type: string + name: + description: Name is the resource name. It supports wildcards. + type: string + namespace: + description: Namespace is the resource namespace. It supports + wildcards. + type: string + verbs: + description: Verbs are the allowed Kubernetes verbs for + the following resource. + items: + type: string + nullable: true + type: array + type: object + type: array + kubernetes_users: + description: KubeUsers is an optional kubernetes users to impersonate + items: + type: string + nullable: true + type: array + logins: + description: Logins is a list of *nix system logins. + items: + type: string + nullable: true + type: array + node_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: NodeLabels is a map of node labels (used to dynamically + grant access to nodes). + type: object + node_labels_expression: + description: NodeLabelsExpression is a predicate expression used + to allow/deny access to SSH nodes. + type: string + request: + nullable: true + properties: + annotations: + additionalProperties: + items: + type: string + type: array + description: Annotations is a collection of annotations to + be programmatically appended to pending access requests + at the time of their creation. These annotations serve as + a mechanism to propagate extra information to plugins. Since + these annotations support variable interpolation syntax, + they also offer a mechanism for forwarding claims from an + external identity provider, to a plugin via `{{external.trait_name}}` + style substitutions. + type: object + claims_to_roles: + description: ClaimsToRoles specifies a mapping from claims + (traits) to teleport roles. + items: + properties: + claim: + description: Claim is a claim name. + type: string + roles: + description: Roles is a list of static teleport roles + to match. + items: + type: string + nullable: true + type: array + value: + description: Value is a claim value to match. + type: string + type: object + type: array + max_duration: + description: MaxDuration is the amount of time the access + will be granted for. If this is zero, the default duration + is used. + format: duration + type: string + roles: + description: Roles is the name of roles which will match the + request rule. + items: + type: string + nullable: true + type: array + search_as_roles: + description: SearchAsRoles is a list of extra roles which + should apply to a user while they are searching for resources + as part of a Resource Access Request, and defines the underlying + roles which will be requested as part of any Resource Access + Request. + items: + type: string + nullable: true + type: array + suggested_reviewers: + description: SuggestedReviewers is a list of reviewer suggestions. These + can be teleport usernames, but that is not a requirement. + items: + type: string + nullable: true + type: array + thresholds: + description: Thresholds is a list of thresholds, one of which + must be met in order for reviews to trigger a state-transition. If + no thresholds are provided, a default threshold of 1 for + approval and denial is used. + items: + properties: + approve: + description: Approve is the number of matching approvals + needed for state-transition. + format: int32 + type: integer + deny: + description: Deny is the number of denials needed for + state-transition. + format: int32 + type: integer + filter: + description: Filter is an optional predicate used to + determine which reviews count toward this threshold. + type: string + name: + description: Name is the optional human-readable name + of the threshold. + type: string + type: object + type: array + type: object + require_session_join: + description: RequireSessionJoin specifies policies for required + users to start a session. + items: + properties: + count: + description: Count is the amount of people that need to + be matched for this policy to be fulfilled. + format: int32 + type: integer + filter: + description: Filter is a predicate that determines what + users count towards this policy. + type: string + kinds: + description: Kinds are the session kinds this policy applies + to. + items: + type: string + nullable: true + type: array + modes: + description: Modes is the list of modes that may be used + to fulfill this policy. + items: + type: string + nullable: true + type: array + name: + description: Name is the name of the policy. + type: string + on_leave: + description: OnLeave is the behaviour that's used when the + policy is no longer fulfilled for a live session. + type: string + type: object + nullable: true + type: array + review_requests: + description: ReviewRequests defines conditions for submitting + access reviews. + nullable: true + properties: + claims_to_roles: + description: ClaimsToRoles specifies a mapping from claims + (traits) to teleport roles. + items: + properties: + claim: + description: Claim is a claim name. + type: string + roles: + description: Roles is a list of static teleport roles + to match. + items: + type: string + nullable: true + type: array + value: + description: Value is a claim value to match. + type: string + type: object + type: array + preview_as_roles: + description: PreviewAsRoles is a list of extra roles which + should apply to a reviewer while they are viewing a Resource + Access Request for the purposes of viewing details such + as the hostname and labels of requested resources. + items: + type: string + nullable: true + type: array + roles: + description: Roles is the name of roles which may be reviewed. + items: + type: string + nullable: true + type: array + where: + description: Where is an optional predicate which further + limits which requests are reviewable. + type: string + type: object + rules: + description: Rules is a list of rules and their access levels. + Rules are a high level construct used for access control. + items: + properties: + actions: + description: Actions specifies optional actions taken when + this rule matches + items: + type: string + nullable: true + type: array + resources: + description: Resources is a list of resources + items: + type: string + nullable: true + type: array + verbs: + description: Verbs is a list of verbs + items: + type: string + nullable: true + type: array + where: + description: Where specifies optional advanced matcher + type: string + type: object + type: array + windows_desktop_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: WindowsDesktopLabels are used in the RBAC system + to allow/deny access to Windows desktops. + type: object + windows_desktop_labels_expression: + description: WindowsDesktopLabelsExpression is a predicate expression + used to allow/deny access to Windows desktops. + type: string + windows_desktop_logins: + description: WindowsDesktopLogins is a list of desktop login names + allowed/denied for Windows desktops. + items: + type: string + nullable: true + type: array + type: object + deny: + description: Deny is the set of conditions evaluated to deny access. + Deny takes priority over allow. + properties: + app_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: AppLabels is a map of labels used as part of the + RBAC system. + type: object + app_labels_expression: + description: AppLabelsExpression is a predicate expression used + to allow/deny access to Apps. + type: string + aws_role_arns: + description: AWSRoleARNs is a list of AWS role ARNs this role + is allowed to assume. + items: + type: string + nullable: true + type: array + azure_identities: + description: AzureIdentities is a list of Azure identities this + role is allowed to assume. + items: + type: string + nullable: true + type: array + cluster_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: ClusterLabels is a map of node labels (used to dynamically + grant access to clusters). + type: object + cluster_labels_expression: + description: ClusterLabelsExpression is a predicate expression + used to allow/deny access to remote Teleport clusters. + type: string + db_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: DatabaseLabels are used in RBAC system to allow/deny + access to databases. + type: object + db_labels_expression: + description: DatabaseLabelsExpression is a predicate expression + used to allow/deny access to Databases. + type: string + db_names: + description: DatabaseNames is a list of database names this role + is allowed to connect to. + items: + type: string + nullable: true + type: array + db_roles: + description: DatabaseRoles is a list of databases roles for automatic + user creation. + items: + type: string + nullable: true + type: array + db_service_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: DatabaseServiceLabels are used in RBAC system to + allow/deny access to Database Services. + type: object + db_service_labels_expression: + description: DatabaseServiceLabelsExpression is a predicate expression + used to allow/deny access to Database Services. + type: string + db_users: + description: DatabaseUsers is a list of databases users this role + is allowed to connect as. + items: + type: string + nullable: true + type: array + desktop_groups: + description: DesktopGroups is a list of groups for created desktop + users to be added to + items: + type: string + nullable: true + type: array + gcp_service_accounts: + description: GCPServiceAccounts is a list of GCP service accounts + this role is allowed to assume. + items: + type: string + nullable: true + type: array + group_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: GroupLabels is a map of labels used as part of the + RBAC system. + type: object + group_labels_expression: + description: GroupLabelsExpression is a predicate expression used + to allow/deny access to user groups. + type: string + host_groups: + description: HostGroups is a list of groups for created users + to be added to + items: + type: string + nullable: true + type: array + host_sudoers: + description: HostSudoers is a list of entries to include in a + users sudoer file + items: + type: string + nullable: true + type: array + impersonate: + description: Impersonate specifies what users and roles this role + is allowed to impersonate by issuing certificates or other possible + means. + nullable: true + properties: + roles: + description: Roles is a list of resources this role is allowed + to impersonate + items: + type: string + nullable: true + type: array + users: + description: Users is a list of resources this role is allowed + to impersonate, could be an empty list or a Wildcard pattern + items: + type: string + nullable: true + type: array + where: + description: Where specifies optional advanced matcher + type: string + type: object + join_sessions: + description: JoinSessions specifies policies to allow users to + join other sessions. + items: + properties: + kinds: + description: Kinds are the session kinds this policy applies + to. + items: + type: string + nullable: true + type: array + modes: + description: Modes is a list of permitted participant modes + for this policy. + items: + type: string + nullable: true + type: array + name: + description: Name is the name of the policy. + type: string + roles: + description: Roles is a list of roles that you can join + the session of. + items: + type: string + nullable: true + type: array + type: object + nullable: true + type: array + kubernetes_groups: + description: KubeGroups is a list of kubernetes groups + items: + type: string + nullable: true + type: array + kubernetes_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: KubernetesLabels is a map of kubernetes cluster labels + used for RBAC. + type: object + kubernetes_labels_expression: + description: KubernetesLabelsExpression is a predicate expression + used to allow/deny access to kubernetes clusters. + type: string + kubernetes_resources: + description: KubernetesResources is the Kubernetes Resources this + Role grants access to. + items: + properties: + kind: + description: Kind specifies the Kubernetes Resource type. + At the moment only "pod" is supported. + type: string + name: + description: Name is the resource name. It supports wildcards. + type: string + namespace: + description: Namespace is the resource namespace. It supports + wildcards. + type: string + verbs: + description: Verbs are the allowed Kubernetes verbs for + the following resource. + items: + type: string + nullable: true + type: array + type: object + type: array + kubernetes_users: + description: KubeUsers is an optional kubernetes users to impersonate + items: + type: string + nullable: true + type: array + logins: + description: Logins is a list of *nix system logins. + items: + type: string + nullable: true + type: array + node_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: NodeLabels is a map of node labels (used to dynamically + grant access to nodes). + type: object + node_labels_expression: + description: NodeLabelsExpression is a predicate expression used + to allow/deny access to SSH nodes. + type: string + request: + nullable: true + properties: + annotations: + additionalProperties: + items: + type: string + type: array + description: Annotations is a collection of annotations to + be programmatically appended to pending access requests + at the time of their creation. These annotations serve as + a mechanism to propagate extra information to plugins. Since + these annotations support variable interpolation syntax, + they also offer a mechanism for forwarding claims from an + external identity provider, to a plugin via `{{external.trait_name}}` + style substitutions. + type: object + claims_to_roles: + description: ClaimsToRoles specifies a mapping from claims + (traits) to teleport roles. + items: + properties: + claim: + description: Claim is a claim name. + type: string + roles: + description: Roles is a list of static teleport roles + to match. + items: + type: string + nullable: true + type: array + value: + description: Value is a claim value to match. + type: string + type: object + type: array + max_duration: + description: MaxDuration is the amount of time the access + will be granted for. If this is zero, the default duration + is used. + format: duration + type: string + roles: + description: Roles is the name of roles which will match the + request rule. + items: + type: string + nullable: true + type: array + search_as_roles: + description: SearchAsRoles is a list of extra roles which + should apply to a user while they are searching for resources + as part of a Resource Access Request, and defines the underlying + roles which will be requested as part of any Resource Access + Request. + items: + type: string + nullable: true + type: array + suggested_reviewers: + description: SuggestedReviewers is a list of reviewer suggestions. These + can be teleport usernames, but that is not a requirement. + items: + type: string + nullable: true + type: array + thresholds: + description: Thresholds is a list of thresholds, one of which + must be met in order for reviews to trigger a state-transition. If + no thresholds are provided, a default threshold of 1 for + approval and denial is used. + items: + properties: + approve: + description: Approve is the number of matching approvals + needed for state-transition. + format: int32 + type: integer + deny: + description: Deny is the number of denials needed for + state-transition. + format: int32 + type: integer + filter: + description: Filter is an optional predicate used to + determine which reviews count toward this threshold. + type: string + name: + description: Name is the optional human-readable name + of the threshold. + type: string + type: object + type: array + type: object + require_session_join: + description: RequireSessionJoin specifies policies for required + users to start a session. + items: + properties: + count: + description: Count is the amount of people that need to + be matched for this policy to be fulfilled. + format: int32 + type: integer + filter: + description: Filter is a predicate that determines what + users count towards this policy. + type: string + kinds: + description: Kinds are the session kinds this policy applies + to. + items: + type: string + nullable: true + type: array + modes: + description: Modes is the list of modes that may be used + to fulfill this policy. + items: + type: string + nullable: true + type: array + name: + description: Name is the name of the policy. + type: string + on_leave: + description: OnLeave is the behaviour that's used when the + policy is no longer fulfilled for a live session. + type: string + type: object + nullable: true + type: array + review_requests: + description: ReviewRequests defines conditions for submitting + access reviews. + nullable: true + properties: + claims_to_roles: + description: ClaimsToRoles specifies a mapping from claims + (traits) to teleport roles. + items: + properties: + claim: + description: Claim is a claim name. + type: string + roles: + description: Roles is a list of static teleport roles + to match. + items: + type: string + nullable: true + type: array + value: + description: Value is a claim value to match. + type: string + type: object + type: array + preview_as_roles: + description: PreviewAsRoles is a list of extra roles which + should apply to a reviewer while they are viewing a Resource + Access Request for the purposes of viewing details such + as the hostname and labels of requested resources. + items: + type: string + nullable: true + type: array + roles: + description: Roles is the name of roles which may be reviewed. + items: + type: string + nullable: true + type: array + where: + description: Where is an optional predicate which further + limits which requests are reviewable. + type: string + type: object + rules: + description: Rules is a list of rules and their access levels. + Rules are a high level construct used for access control. + items: + properties: + actions: + description: Actions specifies optional actions taken when + this rule matches + items: + type: string + nullable: true + type: array + resources: + description: Resources is a list of resources + items: + type: string + nullable: true + type: array + verbs: + description: Verbs is a list of verbs + items: + type: string + nullable: true + type: array + where: + description: Where specifies optional advanced matcher + type: string + type: object + type: array + windows_desktop_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: WindowsDesktopLabels are used in the RBAC system + to allow/deny access to Windows desktops. + type: object + windows_desktop_labels_expression: + description: WindowsDesktopLabelsExpression is a predicate expression + used to allow/deny access to Windows desktops. + type: string + windows_desktop_logins: + description: WindowsDesktopLogins is a list of desktop login names + allowed/denied for Windows desktops. + items: + type: string + nullable: true + type: array + type: object + options: + description: Options is for OpenSSH options like agent forwarding. + properties: + cert_extensions: + description: CertExtensions specifies the key/values + items: + properties: + mode: + description: Mode is the type of extension to be used -- + currently critical-option is not supported + x-kubernetes-int-or-string: true + name: + description: Name specifies the key to be used in the cert + extension. + type: string + type: + description: Type represents the certificate type being + extended, only ssh is supported at this time. + x-kubernetes-int-or-string: true + value: + description: Value specifies the value to be used in the + cert extension. + type: string + type: object + nullable: true + type: array + cert_format: + description: CertificateFormat defines the format of the user + certificate to allow compatibility with older versions of OpenSSH. + type: string + client_idle_timeout: + description: ClientIdleTimeout sets disconnect clients on idle + timeout behavior, if set to 0 means do not disconnect, otherwise + is set to the idle duration. + format: duration + type: string + create_db_user: + description: CreateDatabaseUser enabled automatic database user + creation. + type: boolean + create_db_user_mode: + description: CreateDatabaseUserMode allows users to be automatically + created on a database when not set to off. + x-kubernetes-int-or-string: true + create_desktop_user: + description: CreateDesktopUser allows users to be automatically + created on a Windows desktop + type: boolean + create_host_user: + description: CreateHostUser allows users to be automatically created + on a host + type: boolean + create_host_user_mode: + description: CreateHostUserMode allows users to be automatically + created on a host when not set to off + x-kubernetes-int-or-string: true + desktop_clipboard: + description: DesktopClipboard indicates whether clipboard sharing + is allowed between the user's workstation and the remote desktop. + It defaults to true unless explicitly set to false. + type: boolean + desktop_directory_sharing: + description: DesktopDirectorySharing indicates whether directory + sharing is allowed between the user's workstation and the remote + desktop. It defaults to false unless explicitly set to true. + type: boolean + device_trust_mode: + description: DeviceTrustMode is the device authorization mode + used for the resources associated with the role. See DeviceTrust.Mode. + Reserved for future use, not yet used by Teleport. + type: string + disconnect_expired_cert: + description: DisconnectExpiredCert sets disconnect clients on + expired certificates. + type: boolean + enhanced_recording: + description: BPF defines what events to record for the BPF-based + session recorder. + items: + type: string + nullable: true + type: array + forward_agent: + description: ForwardAgent is SSH agent forwarding. + type: boolean + idp: + description: IDP is a set of options related to accessing IdPs + within Teleport. Requires Teleport Enterprise. + nullable: true + properties: + saml: + description: SAML are options related to the Teleport SAML + IdP. + nullable: true + properties: + enabled: + description: Enabled is set to true if this option allows + access to the Teleport SAML IdP. + type: boolean + type: object + type: object + lock: + description: Lock specifies the locking mode (strict|best_effort) + to be applied with the role. + type: string + max_connections: + description: MaxConnections defines the maximum number of concurrent + connections a user may hold. + format: int64 + type: integer + max_kubernetes_connections: + description: MaxKubernetesConnections defines the maximum number + of concurrent Kubernetes sessions a user may hold. + format: int64 + type: integer + max_session_ttl: + description: MaxSessionTTL defines how long a SSH session can + last for. + format: duration + type: string + max_sessions: + description: MaxSessions defines the maximum number of concurrent + sessions per connection. + format: int64 + type: integer + permit_x11_forwarding: + description: PermitX11Forwarding authorizes use of X11 forwarding. + type: boolean + pin_source_ip: + description: PinSourceIP forces the same client IP for certificate + generation and usage + type: boolean + port_forwarding: + description: PortForwarding defines if the certificate will have + "permit-port-forwarding" in the certificate. PortForwarding + is "yes" if not set, that's why this is a pointer + type: boolean + record_session: + description: RecordDesktopSession indicates whether desktop access + sessions should be recorded. It defaults to true unless explicitly + set to false. + nullable: true + properties: + default: + description: Default indicates the default value for the services. + type: string + desktop: + description: Desktop indicates whether desktop sessions should + be recorded. It defaults to true unless explicitly set to + false. + type: boolean + ssh: + description: SSH indicates the session mode used on SSH sessions. + type: string + type: object + request_access: + description: RequestAccess defines the access request strategy + (optional|note|always) where optional is the default. + type: string + request_prompt: + description: RequestPrompt is an optional message which tells + users what they aught to request. + type: string + require_session_mfa: + description: RequireMFAType is the type of MFA requirement enforced + for this user. + x-kubernetes-int-or-string: true + ssh_file_copy: + description: SSHFileCopy indicates whether remote file operations + via SCP or SFTP are allowed over an SSH session. It defaults + to true unless explicitly set to false. + type: boolean + type: object + type: object + status: + description: Status defines the observed state of the Teleport resource + properties: + conditions: + description: Conditions represent the latest available observations + of an object's state + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + teleportResourceID: + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/integrations/operator/config/crd/bases/resources.teleport.dev_samlconnectors.yaml b/integrations/operator/config/crd/bases/resources.teleport.dev_samlconnectors.yaml index dc51a28419136..caaa7f3a5fb1e 100644 --- a/integrations/operator/config/crd/bases/resources.teleport.dev_samlconnectors.yaml +++ b/integrations/operator/config/crd/bases/resources.teleport.dev_samlconnectors.yaml @@ -120,8 +120,7 @@ spec: type: string type: object status: - description: TeleportSAMLConnectorStatus defines the observed state of - TeleportSAMLConnector + description: Status defines the observed state of the Teleport resource properties: conditions: description: Conditions represent the latest available observations diff --git a/integrations/operator/config/crd/bases/resources.teleport.dev_users.yaml b/integrations/operator/config/crd/bases/resources.teleport.dev_users.yaml index 01c405d0adeed..030a2b6f59bf8 100644 --- a/integrations/operator/config/crd/bases/resources.teleport.dev_users.yaml +++ b/integrations/operator/config/crd/bases/resources.teleport.dev_users.yaml @@ -106,7 +106,7 @@ spec: type: array type: object status: - description: TeleportUserStatus defines the observed state of TeleportUser + description: Status defines the observed state of the Teleport resource properties: conditions: description: Conditions represent the latest available observations diff --git a/integrations/operator/controllers/resources/accesslist_controller.go b/integrations/operator/controllers/resources/accesslist_controller.go index bfa359e5828a9..4321d904aa197 100644 --- a/integrations/operator/controllers/resources/accesslist_controller.go +++ b/integrations/operator/controllers/resources/accesslist_controller.go @@ -63,15 +63,15 @@ func (r accessListClient) MutateExisting(new, existing *accesslist.AccessList) { } // NewAccessListReconciler instantiates a new Kubernetes controller reconciling access_list resources -func NewAccessListReconciler(client kclient.Client, tClient *client.Client) *TeleportResourceReconciler[*accesslist.AccessList, *resourcesv1.TeleportAccessList] { +func NewAccessListReconciler(client kclient.Client, tClient *client.Client) (Reconciler, error) { accessListClient := &accessListClient{ teleportClient: tClient, } - resourceReconciler := NewTeleportResourceReconciler[*accesslist.AccessList, *resourcesv1.TeleportAccessList]( + resourceReconciler, err := NewTeleportResourceReconciler[*accesslist.AccessList, *resourcesv1.TeleportAccessList]( client, accessListClient, ) - return resourceReconciler + return resourceReconciler, trace.Wrap(err, "building teleport resource reconciler") } diff --git a/integrations/operator/controllers/resources/base_reconciler.go b/integrations/operator/controllers/resources/base_reconciler.go index d0515141f5002..bbf199841d9c2 100644 --- a/integrations/operator/controllers/resources/base_reconciler.go +++ b/integrations/operator/controllers/resources/base_reconciler.go @@ -20,6 +20,7 @@ package resources import ( "context" + "fmt" "github.com/gravitational/trace" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -29,9 +30,18 @@ import ( ctrllog "sigs.k8s.io/controller-runtime/pkg/log" ) -// DeletionFinalizer is a name of finalizer added to resource's 'finalizers' field -// for tracking deletion events. -const DeletionFinalizer = "resources.teleport.dev/deletion" +const ( + // DeletionFinalizer is a name of finalizer added to resource's 'finalizers' field + // for tracking deletion events. + DeletionFinalizer = "resources.teleport.dev/deletion" + // AnnotationFlagIgnore is the Kubernetes annotation containing the "ignore" flag. + // When set to true, the operator will not reconcile the CR. + AnnotationFlagIgnore = "teleport.dev/ignore" + // AnnotationFlagKeep is the Kubernetes annotation containing the "keep" flag. + // When set to true, the operator will not delete the Teleport resource if the + // CR is deleted. + AnnotationFlagKeep = "teleport.dev/keep" +) type DeleteExternal func(context.Context, kclient.Object) error type UpsertExternal func(context.Context, kclient.Object) error @@ -79,15 +89,24 @@ func (r ResourceBaseReconciler) Do(ctx context.Context, req ctrl.Request, obj kc return ctrl.Result{}, trace.Wrap(err) } + if isIgnored(obj) { + log.Info(fmt.Sprintf("Resource is flagged with annotation %q, it will not be reconciled.", AnnotationFlagIgnore)) + return ctrl.Result{}, nil + } + hasDeletionFinalizer := controllerutil.ContainsFinalizer(obj, DeletionFinalizer) isMarkedToBeDeleted := !obj.GetDeletionTimestamp().IsZero() // Delete if isMarkedToBeDeleted { if hasDeletionFinalizer { - log.Info("deleting object in Teleport") - if err := r.DeleteExternal(ctx, obj); err != nil && !trace.IsNotFound(err) { - return ctrl.Result{}, trace.Wrap(err) + if isKept(obj) { + log.Info(fmt.Sprintf("Resource is flagged with annotation %q, it will not be deleted in Teleport.", AnnotationFlagKeep)) + } else { + log.Info("deleting object in Teleport") + if err := r.DeleteExternal(ctx, obj); err != nil && !trace.IsNotFound(err) { + return ctrl.Result{}, trace.Wrap(err) + } } log.Info("removing finalizer") @@ -115,3 +134,13 @@ func (r ResourceBaseReconciler) Do(ctx context.Context, req ctrl.Request, obj kc err := r.UpsertExternal(ctx, obj) return ctrl.Result{}, trace.Wrap(err) } + +// isIgnored checks if the CR should be ignored +func isIgnored(obj kclient.Object) bool { + return checkAnnotationFlag(obj, AnnotationFlagIgnore, false /* defaults to false */) +} + +// isKept checks if the Teleport resource should be kept if the CR is deleted +func isKept(obj kclient.Object) bool { + return checkAnnotationFlag(obj, AnnotationFlagKeep, false /* defaults to false */) +} diff --git a/integrations/operator/controllers/resources/github_connector_controller.go b/integrations/operator/controllers/resources/github_connector_controller.go index d72501908b354..699beb8fb89e1 100644 --- a/integrations/operator/controllers/resources/github_connector_controller.go +++ b/integrations/operator/controllers/resources/github_connector_controller.go @@ -58,15 +58,15 @@ func (r githubConnectorClient) Delete(ctx context.Context, name string) error { } // NewGithubConnectorReconciler instantiates a new Kubernetes controller reconciling github_connector resources -func NewGithubConnectorReconciler(client kclient.Client, tClient *client.Client) *TeleportResourceReconciler[types.GithubConnector, *resourcesv3.TeleportGithubConnector] { +func NewGithubConnectorReconciler(client kclient.Client, tClient *client.Client) (Reconciler, error) { githubClient := &githubConnectorClient{ teleportClient: tClient, } - resourceReconciler := NewTeleportResourceReconciler[types.GithubConnector, *resourcesv3.TeleportGithubConnector]( + resourceReconciler, err := NewTeleportResourceReconciler[types.GithubConnector, *resourcesv3.TeleportGithubConnector]( client, githubClient, ) - return resourceReconciler + return resourceReconciler, trace.Wrap(err, "building teleport resource reconciler") } diff --git a/integrations/operator/controllers/resources/global.go b/integrations/operator/controllers/resources/global.go new file mode 100644 index 0000000000000..edc8ec3f992f8 --- /dev/null +++ b/integrations/operator/controllers/resources/global.go @@ -0,0 +1,119 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package resources + +import ( + "github.com/go-logr/logr" + "github.com/gravitational/trace" + apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + "k8s.io/apimachinery/pkg/runtime" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + clientgoscheme "k8s.io/client-go/kubernetes/scheme" + kclient "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + + "github.com/gravitational/teleport/api/client" + "github.com/gravitational/teleport/api/client/proto" + resourcesv1 "github.com/gravitational/teleport/integrations/operator/apis/resources/v1" + resourcesv2 "github.com/gravitational/teleport/integrations/operator/apis/resources/v2" + resourcesv3 "github.com/gravitational/teleport/integrations/operator/apis/resources/v3" + resourcesv5 "github.com/gravitational/teleport/integrations/operator/apis/resources/v5" +) + +// Scheme is a singleton scheme for all controllers +var Scheme = runtime.NewScheme() + +func init() { + utilruntime.Must(resourcesv5.AddToScheme(Scheme)) + utilruntime.Must(resourcesv3.AddToScheme(Scheme)) + utilruntime.Must(resourcesv2.AddToScheme(Scheme)) + utilruntime.Must(resourcesv1.AddToScheme(Scheme)) + + // Not needed to reconcile the teleport CRs, but needed for the controller manager. + // We are not doing something very kubernetes friendly, but it's easier to have a single + // scheme rather than having to build and propagate schemes in multiple places, which + // is error-prone and can lead to inconsistencies. + utilruntime.Must(clientgoscheme.AddToScheme(Scheme)) + utilruntime.Must(apiextv1.AddToScheme(Scheme)) +} + +type reconcilerFactory struct { + cr string + factory func(kclient.Client, *client.Client) (Reconciler, error) +} + +// Reconciler extends the reconcile.Reconciler interface by adding a +// SetupWithManager function that creates a controller in the given manager. +type Reconciler interface { + reconcile.Reconciler + SetupWithManager(mgr manager.Manager) error +} + +func SetupAllControllers(log logr.Logger, mgr manager.Manager, teleportClient *client.Client, features *proto.Features) error { + reconcilers := []reconcilerFactory{ + {"TeleportRole", NewRoleReconciler}, + {"TeleportRoleV6", NewRoleV6Reconciler}, + {"TeleportRoleV7", NewRoleV7Reconciler}, + {"TeleportUser", NewUserReconciler}, + {"TeleportGithubConnector", NewGithubConnectorReconciler}, + {"TeleportProvisionToken", NewProvisionTokenReconciler}, + {"TeleportOktaImportRule", NewOktaImportRuleReconciler}, + } + + if features.GetOIDC() { + reconcilers = append(reconcilers, reconcilerFactory{"TeleportOIDCConnector", NewOIDCConnectorReconciler}) + } else { + log.Info("OIDC connectors are only available in Teleport Enterprise edition. TeleportOIDCConnector resources won't be reconciled") + } + + if features.GetSAML() { + reconcilers = append(reconcilers, reconcilerFactory{"TeleportSAMLConnector", NewSAMLConnectorReconciler}) + } else { + log.Info("SAML connectors are only available in Teleport Enterprise edition. TeleportSAMLConnector resources won't be reconciled") + } + + // Login Rules are enterprise-only but there is no specific feature flag for them. + if features.GetOIDC() || features.GetSAML() { + reconcilers = append(reconcilers, reconcilerFactory{"TeleportLoginRule", NewLoginRuleReconciler}) + } else { + log.Info("Login Rules are only available in Teleport Enterprise edition. TeleportLoginRule resources won't be reconciled") + } + + // AccessLists are enterprise-only but there is no specific feature-flag for them. + if features.GetAdvancedAccessWorkflows() { + reconcilers = append(reconcilers, reconcilerFactory{"TeleportAccessList", NewAccessListReconciler}) + } else { + log.Info("The cluster license does not contain advanced workflows. TeleportAccessList resources won't be reconciled") + } + + kubeClient := mgr.GetClient() + for _, reconciler := range reconcilers { + r, err := reconciler.factory(kubeClient, teleportClient) + if err != nil { + return trace.Wrap(err, "failed to create controller for %s", reconciler.cr) + } + err = r.SetupWithManager(mgr) + if err != nil { + return trace.Wrap(err, "failed to setup controller for: %s", reconciler.cr) + } + } + + return nil +} diff --git a/integrations/operator/controllers/resources/login_rule_controller.go b/integrations/operator/controllers/resources/login_rule_controller.go index c37bbce67cb60..4b78d4d971828 100644 --- a/integrations/operator/controllers/resources/login_rule_controller.go +++ b/integrations/operator/controllers/resources/login_rule_controller.go @@ -61,15 +61,15 @@ func (l loginRuleClient) Delete(ctx context.Context, name string) error { } // NewLoginRuleReconciler instantiates a new Kubernetes controller reconciling login_rule resources -func NewLoginRuleReconciler(client kclient.Client, tClient *client.Client) *TeleportResourceReconciler[*resourcesv1.LoginRuleResource, *resourcesv1.TeleportLoginRule] { +func NewLoginRuleReconciler(client kclient.Client, tClient *client.Client) (Reconciler, error) { loginRuleClient := &loginRuleClient{ teleportClient: tClient, } - resourceReconciler := NewTeleportResourceReconciler[*resourcesv1.LoginRuleResource, *resourcesv1.TeleportLoginRule]( + resourceReconciler, err := NewTeleportResourceReconciler[*resourcesv1.LoginRuleResource, *resourcesv1.TeleportLoginRule]( client, loginRuleClient, ) - return resourceReconciler + return resourceReconciler, trace.Wrap(err, "building teleport resource reconciler") } diff --git a/integrations/operator/controllers/resources/oidc_connector_controller.go b/integrations/operator/controllers/resources/oidc_connector_controller.go index 6badfba0663d5..fcdcaf797e248 100644 --- a/integrations/operator/controllers/resources/oidc_connector_controller.go +++ b/integrations/operator/controllers/resources/oidc_connector_controller.go @@ -58,15 +58,15 @@ func (r oidcConnectorClient) Delete(ctx context.Context, name string) error { } // NewOIDCConnectorReconciler instantiates a new Kubernetes controller reconciling oidc_connector resources -func NewOIDCConnectorReconciler(client kclient.Client, tClient *client.Client) *TeleportResourceReconciler[types.OIDCConnector, *resourcesv3.TeleportOIDCConnector] { +func NewOIDCConnectorReconciler(client kclient.Client, tClient *client.Client) (Reconciler, error) { oidcClient := &oidcConnectorClient{ teleportClient: tClient, } - resourceReconciler := NewTeleportResourceReconciler[types.OIDCConnector, *resourcesv3.TeleportOIDCConnector]( + resourceReconciler, err := NewTeleportResourceReconciler[types.OIDCConnector, *resourcesv3.TeleportOIDCConnector]( client, oidcClient, ) - return resourceReconciler + return resourceReconciler, trace.Wrap(err, "building teleport resource reconciler") } diff --git a/integrations/operator/controllers/resources/okta_import_rule_controller.go b/integrations/operator/controllers/resources/okta_import_rule_controller.go index 3519328986093..10beeca093374 100644 --- a/integrations/operator/controllers/resources/okta_import_rule_controller.go +++ b/integrations/operator/controllers/resources/okta_import_rule_controller.go @@ -58,15 +58,15 @@ func (r oktaImportRuleClient) Delete(ctx context.Context, name string) error { } // NewOktaImportRuleReconciler instantiates a new Kubernetes controller reconciling okta_import_rule resources -func NewOktaImportRuleReconciler(client kclient.Client, tClient *client.Client) *TeleportResourceReconciler[types.OktaImportRule, *resourcesv1.TeleportOktaImportRule] { +func NewOktaImportRuleReconciler(client kclient.Client, tClient *client.Client) (Reconciler, error) { oktaImportRuleClient := &oktaImportRuleClient{ teleportClient: tClient, } - resourceReconciler := NewTeleportResourceReconciler[types.OktaImportRule, *resourcesv1.TeleportOktaImportRule]( + resourceReconciler, err := NewTeleportResourceReconciler[types.OktaImportRule, *resourcesv1.TeleportOktaImportRule]( client, oktaImportRuleClient, ) - return resourceReconciler + return resourceReconciler, trace.Wrap(err, "building teleport resource reconciler") } diff --git a/integrations/operator/controllers/resources/provision_token_controller.go b/integrations/operator/controllers/resources/provision_token_controller.go index 4859f653733a5..3067dc50e74aa 100644 --- a/integrations/operator/controllers/resources/provision_token_controller.go +++ b/integrations/operator/controllers/resources/provision_token_controller.go @@ -56,15 +56,15 @@ func (r provisionTokenClient) Delete(ctx context.Context, name string) error { } // NewProvisionTokenReconciler instantiates a new Kubernetes controller reconciling provision token resources -func NewProvisionTokenReconciler(client kclient.Client, tClient *client.Client) *TeleportResourceReconciler[types.ProvisionToken, *resourcesv2.TeleportProvisionToken] { +func NewProvisionTokenReconciler(client kclient.Client, tClient *client.Client) (Reconciler, error) { tokenClient := &provisionTokenClient{ teleportClient: tClient, } - resourceReconciler := NewTeleportResourceReconciler[types.ProvisionToken, *resourcesv2.TeleportProvisionToken]( + resourceReconciler, err := NewTeleportResourceReconciler[types.ProvisionToken, *resourcesv2.TeleportProvisionToken]( client, tokenClient, ) - return resourceReconciler + return resourceReconciler, trace.Wrap(err, "building teleport resource reconciler") } diff --git a/integrations/operator/controllers/resources/provision_token_controller_test.go b/integrations/operator/controllers/resources/provision_token_controller_test.go index 65a4773c370e4..9f5f781e6c40e 100644 --- a/integrations/operator/controllers/resources/provision_token_controller_test.go +++ b/integrations/operator/controllers/resources/provision_token_controller_test.go @@ -197,7 +197,8 @@ github: tokenName := validRandomResourceName("token-") - obj := resources.GetUnstructuredObjectFromGVK(teleportTokenGVK) + obj, err := resources.GetUnstructuredObjectFromGVK(teleportTokenGVK) + require.NoError(t, err) obj.Object["spec"] = tokenManifest obj.SetName(tokenName) obj.SetNamespace(setup.Namespace.Name) diff --git a/integrations/operator/controllers/resources/role_controller.go b/integrations/operator/controllers/resources/role_controller.go deleted file mode 100644 index 6442b2943f153..0000000000000 --- a/integrations/operator/controllers/resources/role_controller.go +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Teleport - * Copyright (C) 2023 Gravitational, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package resources - -import ( - "context" - "fmt" - - "github.com/gravitational/trace" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - ctrl "sigs.k8s.io/controller-runtime" - kclient "sigs.k8s.io/controller-runtime/pkg/client" - - "github.com/gravitational/teleport/api/client" - "github.com/gravitational/teleport/api/types" - v5 "github.com/gravitational/teleport/integrations/operator/apis/resources/v5" -) - -const teleportRoleKind = "TeleportRole" - -// TODO(for v12): Have the Role controller to use the generic Teleport reconciler -// This means we'll have to move back to a statically typed client. -// This will require removing the crdgen hack, fixing TeleportRole JSON serialization - -var TeleportRoleGVKV5 = schema.GroupVersionKind{ - Group: v5.GroupVersion.Group, - Version: v5.GroupVersion.Version, - Kind: teleportRoleKind, -} - -// RoleReconciler reconciles a TeleportRole object -type RoleReconciler struct { - kclient.Client - Scheme *runtime.Scheme - TeleportClient *client.Client -} - -//+kubebuilder:rbac:groups=resources.teleport.dev,resources=roles,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=resources.teleport.dev,resources=roles/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=resources.teleport.dev,resources=roles/finalizers,verbs=update - -// Reconcile is part of the main kubernetes reconciliation loop which aims to -// move the current state of the cluster closer to the desired state. -// -// For more details, check Reconcile and its Result here: -// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.11.0/pkg/reconcile -func (r *RoleReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - // The TeleportRole OpenAPI spec does not validate typing of Label fields like `node_labels`. - // This means we can receive invalid data, by default it won't be unmarshalled properly and will crash the operator. - // To handle this more gracefully we unmarshall first in an unstructured object. - // The unstructured object will be converted later to a typed one, in r.UpsertExternal. - // See `/operator/crdgen/schemagen.go` and https://github.com/gravitational/teleport/issues/15204 for context. - // TODO: (Check how to handle multiple versions) - obj := GetUnstructuredObjectFromGVK(TeleportRoleGVKV5) - return ResourceBaseReconciler{ - Client: r.Client, - DeleteExternal: r.Delete, - UpsertExternal: r.Upsert, - }.Do(ctx, req, obj) -} - -// SetupWithManager sets up the controller with the Manager. -func (r *RoleReconciler) SetupWithManager(mgr ctrl.Manager) error { - // The TeleportRole OpenAPI spec does not validate typing of Label fields like `node_labels`. - // This means we can receive invalid data, by default it won't be unmarshalled properly and will crash the operator - // To handle this more gracefully we unmarshall first in an unstructured object. - // The unstructured object will be converted later to a typed one, in r.UpsertExternal. - // See `/operator/crdgen/schemagen.go` and https://github.com/gravitational/teleport/issues/15204 for context - // TODO: (Check how to handle multiple versions) - obj := GetUnstructuredObjectFromGVK(TeleportRoleGVKV5) - return ctrl.NewControllerManagedBy(mgr). - For(obj). - WithEventFilter(buildPredicate()). - Complete(r) -} - -func (r *RoleReconciler) Delete(ctx context.Context, obj kclient.Object) error { - return r.TeleportClient.DeleteRole(ctx, obj.GetName()) -} - -func (r *RoleReconciler) Upsert(ctx context.Context, obj kclient.Object) error { - // We receive an unstructured object. We convert it to a typed TeleportRole object and gracefully handle errors. - u, ok := obj.(*unstructured.Unstructured) - if !ok { - return fmt.Errorf("failed to convert Object into resource object: %T", obj) - } - k8sResource := &v5.TeleportRole{} - - // If an error happens we want to put it in status.conditions before returning. - err := runtime.DefaultUnstructuredConverter.FromUnstructuredWithValidation( - u.Object, - k8sResource, true, /* returnUnknownFields */ - ) - updateErr := updateStatus(updateStatusConfig{ - ctx: ctx, - client: r.Client, - k8sResource: k8sResource, - condition: getStructureConditionFromError(err), - }) - if err != nil || updateErr != nil { - return trace.NewAggregate(err, updateErr) - } - - // Converting the Kubernetes resource into a Teleport one, checking potential ownership issues. - teleportResource := k8sResource.ToTeleport() - existingResource, err := r.TeleportClient.GetRole(ctx, teleportResource.GetName()) - updateErr = updateStatus(updateStatusConfig{ - ctx: ctx, - client: r.Client, - k8sResource: k8sResource, - condition: getReconciliationConditionFromError(err, true /* ignoreNotFound */), - }) - if err != nil && !trace.IsNotFound(err) || updateErr != nil { - return trace.NewAggregate(err, updateErr) - } - - if err == nil { - // The resource already exists - newOwnershipCondition, isOwned := checkOwnership(existingResource) - if updateErr = updateStatus(updateStatusConfig{ - ctx: ctx, - client: r.Client, - k8sResource: k8sResource, - condition: newOwnershipCondition, - }); updateErr != nil { - return trace.Wrap(updateErr) - } - if !isOwned { - return trace.AlreadyExists("unowned resource '%s' already exists", existingResource.GetName()) - } - } else { - // The resource does not yet exist - if updateErr = updateStatus(updateStatusConfig{ - ctx: ctx, - client: r.Client, - k8sResource: k8sResource, - condition: newResourceCondition, - }); updateErr != nil { - return trace.Wrap(updateErr) - } - } - - if existingResource != nil { - teleportResource.SetRevision(existingResource.GetRevision()) - } - r.AddTeleportResourceOrigin(teleportResource) - - // If an error happens we want to put it in status.conditions before returning. - _, err = r.TeleportClient.UpsertRole(ctx, teleportResource) - updateErr = updateStatus(updateStatusConfig{ - ctx: ctx, - client: r.Client, - k8sResource: k8sResource, - condition: getReconciliationConditionFromError(err, false /* ignoreNotFound */), - }) - // We update the status conditions on exit - return trace.NewAggregate(err, updateErr) -} - -func (r *RoleReconciler) AddTeleportResourceOrigin(resource types.Role) { - metadata := resource.GetMetadata() - if metadata.Labels == nil { - metadata.Labels = make(map[string]string) - } - metadata.Labels[types.OriginLabel] = types.OriginKubernetes - resource.SetMetadata(metadata) -} - -func GetUnstructuredObjectFromGVK(gvk schema.GroupVersionKind) *unstructured.Unstructured { - obj := unstructured.Unstructured{} - obj.SetGroupVersionKind(gvk) - return &obj -} diff --git a/integrations/operator/controllers/resources/role_controller_test.go b/integrations/operator/controllers/resources/role_controller_test.go index 01448460fa9a6..ce8f247f3d8ec 100644 --- a/integrations/operator/controllers/resources/role_controller_test.go +++ b/integrations/operator/controllers/resources/role_controller_test.go @@ -29,16 +29,24 @@ import ( "github.com/stretchr/testify/require" kerrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/yaml" "k8s.io/client-go/util/retry" kclient "sigs.k8s.io/controller-runtime/pkg/client" "github.com/gravitational/teleport/api/types" apiutils "github.com/gravitational/teleport/api/utils" + apiresources "github.com/gravitational/teleport/integrations/operator/apis/resources" resourcesv5 "github.com/gravitational/teleport/integrations/operator/apis/resources/v5" "github.com/gravitational/teleport/integrations/operator/controllers/resources" ) +var TeleportRoleGVKV5 = schema.GroupVersionKind{ + Group: resourcesv5.GroupVersion.Group, + Version: resourcesv5.GroupVersion.Version, + Kind: "TeleportRole", +} + // When I create or delete a TeleportRole CR in Kubernetes, // the corresponding TeleportRole must be created/deleted in Teleport. func TestRoleCreation(t *testing.T) { @@ -190,7 +198,8 @@ allow: roleName := validRandomResourceName("role-") - obj := resources.GetUnstructuredObjectFromGVK(resources.TeleportRoleGVKV5) + obj, err := resources.GetUnstructuredObjectFromGVK(TeleportRoleGVKV5) + require.NoError(t, err) obj.Object["spec"] = roleManifest obj.SetName(roleName) obj.SetNamespace(setup.Namespace.Name) @@ -399,61 +408,9 @@ func k8sCreateRole(ctx context.Context, t *testing.T, kc kclient.Client, role *r require.NoError(t, err) } -func TestAddTeleportResourceOriginRole(t *testing.T) { - r := resources.RoleReconciler{} - tests := []struct { - name string - resource types.Role - }{ - { - name: "origin already set correctly", - resource: &types.RoleV6{ - Metadata: types.Metadata{ - Name: "user with correct origin", - Labels: map[string]string{types.OriginLabel: types.OriginKubernetes}, - }, - }, - }, - { - name: "origin already set incorrectly", - resource: &types.RoleV6{ - Metadata: types.Metadata{ - Name: "user with correct origin", - Labels: map[string]string{types.OriginLabel: types.OriginConfigFile}, - }, - }, - }, - { - name: "origin not set", - resource: &types.RoleV6{ - Metadata: types.Metadata{ - Name: "user with correct origin", - Labels: map[string]string{"foo": "bar"}, - }, - }, - }, - { - name: "no labels", - resource: &types.RoleV6{ - Metadata: types.Metadata{ - Name: "user with no labels", - }, - }, - }, - } - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - r.AddTeleportResourceOrigin(tc.resource) - metadata := tc.resource.GetMetadata() - require.Contains(t, metadata.Labels, types.OriginLabel) - require.Equal(t, types.OriginKubernetes, metadata.Labels[types.OriginLabel]) - }) - } -} - func getRoleStatusConditionError(object map[string]interface{}) []metav1.Condition { var conditionsWithError []metav1.Condition - var status resourcesv5.TeleportRoleStatus + var status apiresources.Status _ = mapstructure.Decode(object["status"], &status) for _, condition := range status.Conditions { diff --git a/integrations/operator/controllers/resources/rolev6_controller_test.go b/integrations/operator/controllers/resources/rolev6_controller_test.go new file mode 100644 index 0000000000000..66341c4f84e79 --- /dev/null +++ b/integrations/operator/controllers/resources/rolev6_controller_test.go @@ -0,0 +1,146 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package resources_test + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/gravitational/trace" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + kclient "sigs.k8s.io/controller-runtime/pkg/client" + + "github.com/gravitational/teleport/api/types" + resourcesv1 "github.com/gravitational/teleport/integrations/operator/apis/resources/v1" + "github.com/gravitational/teleport/integrations/operator/controllers/resources/testlib" +) + +var roleV6Spec = types.RoleSpecV6{ + Options: types.RoleOptions{ + ForwardAgent: true, + }, + Allow: types.RoleConditions{ + Logins: []string{"foo"}, + KubernetesLabels: types.Labels{"env": {"dev", "prod"}}, + KubernetesResources: []types.KubernetesResource{ + { + Kind: "pod", + Namespace: "monitoring", + Name: "^prometheus-.*", + }, + }, + }, + Deny: types.RoleConditions{}, +} + +type roleV6TestingPrimitives struct { + setup *testSetup +} + +func (g *roleV6TestingPrimitives) Init(setup *testSetup) { + g.setup = setup +} + +func (g *roleV6TestingPrimitives) SetupTeleportFixtures(ctx context.Context) error { + return nil +} + +func (g *roleV6TestingPrimitives) CreateTeleportResource(ctx context.Context, name string) error { + role, err := types.NewRoleWithVersion(name, types.V6, roleV6Spec) + if err != nil { + return trace.Wrap(err) + } + role.SetOrigin(types.OriginKubernetes) + _, err = g.setup.TeleportClient.CreateRole(ctx, role) + return trace.Wrap(err) +} + +func (g *roleV6TestingPrimitives) GetTeleportResource(ctx context.Context, name string) (types.Role, error) { + return g.setup.TeleportClient.GetRole(ctx, name) +} + +func (g *roleV6TestingPrimitives) DeleteTeleportResource(ctx context.Context, name string) error { + return trace.Wrap(g.setup.TeleportClient.DeleteRole(ctx, name)) +} + +func (g *roleV6TestingPrimitives) CreateKubernetesResource(ctx context.Context, name string) error { + role := &resourcesv1.TeleportRoleV6{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: g.setup.Namespace.Name, + }, + Spec: resourcesv1.TeleportRoleV6Spec(roleV6Spec), + } + return trace.Wrap(g.setup.K8sClient.Create(ctx, role)) +} + +func (g *roleV6TestingPrimitives) DeleteKubernetesResource(ctx context.Context, name string) error { + role := &resourcesv1.TeleportRoleV6{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: g.setup.Namespace.Name, + }, + } + return trace.Wrap(g.setup.K8sClient.Delete(ctx, role)) +} + +func (g *roleV6TestingPrimitives) GetKubernetesResource(ctx context.Context, name string) (*resourcesv1.TeleportRoleV6, error) { + role := &resourcesv1.TeleportRoleV6{} + obj := kclient.ObjectKey{ + Name: name, + Namespace: g.setup.Namespace.Name, + } + err := g.setup.K8sClient.Get(ctx, obj, role) + return role, trace.Wrap(err) +} + +func (g *roleV6TestingPrimitives) ModifyKubernetesResource(ctx context.Context, name string) error { + role, err := g.GetKubernetesResource(ctx, name) + if err != nil { + return trace.Wrap(err) + } + role.Spec.Allow.Logins = []string{"foo", "bar"} + return g.setup.K8sClient.Update(ctx, role) +} + +func (g *roleV6TestingPrimitives) CompareTeleportAndKubernetesResource(tResource types.Role, kubeResource *resourcesv1.TeleportRoleV6) (bool, string) { + ignoreServerSideDefaults := []cmp.Option{ + cmpopts.IgnoreFields(types.RoleSpecV6{}, "Options"), + cmpopts.IgnoreFields(types.RoleConditions{}, "Namespaces"), + } + diff := cmp.Diff(tResource, kubeResource.ToTeleport(), testlib.CompareOptions(ignoreServerSideDefaults...)...) + return diff == "", diff +} + +func TestTeleportRoleV6Creation(t *testing.T) { + test := &roleV6TestingPrimitives{} + testlib.ResourceCreationTest[types.Role, *resourcesv1.TeleportRoleV6](t, test) +} + +func TestTeleportRoleV6DeletionDrift(t *testing.T) { + test := &roleV6TestingPrimitives{} + testlib.ResourceDeletionDriftTest[types.Role, *resourcesv1.TeleportRoleV6](t, test) +} + +func TestTeleportRoleV6Update(t *testing.T) { + test := &roleV6TestingPrimitives{} + testlib.ResourceUpdateTest[types.Role, *resourcesv1.TeleportRoleV6](t, test) +} diff --git a/integrations/operator/controllers/resources/rolev7_controller_test.go b/integrations/operator/controllers/resources/rolev7_controller_test.go new file mode 100644 index 0000000000000..1091680a75485 --- /dev/null +++ b/integrations/operator/controllers/resources/rolev7_controller_test.go @@ -0,0 +1,143 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package resources_test + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/gravitational/trace" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + kclient "sigs.k8s.io/controller-runtime/pkg/client" + + "github.com/gravitational/teleport/api/types" + resourcesv1 "github.com/gravitational/teleport/integrations/operator/apis/resources/v1" + "github.com/gravitational/teleport/integrations/operator/controllers/resources/testlib" +) + +var roleV7Spec = types.RoleSpecV6{ + Allow: types.RoleConditions{ + Logins: []string{"foo"}, + KubernetesLabels: types.Labels{"env": {"dev", "prod"}}, + KubernetesResources: []types.KubernetesResource{ + { + Kind: "*", + Namespace: "monitoring", + Name: "^prometheus-.*", + }, + }, + }, + Deny: types.RoleConditions{}, +} + +type roleV7TestingPrimitives struct { + setup *testSetup +} + +func (g *roleV7TestingPrimitives) Init(setup *testSetup) { + g.setup = setup +} + +func (g *roleV7TestingPrimitives) SetupTeleportFixtures(ctx context.Context) error { + return nil +} + +func (g *roleV7TestingPrimitives) CreateTeleportResource(ctx context.Context, name string) error { + role, err := types.NewRoleWithVersion(name, types.V6, roleV6Spec) + if err != nil { + return trace.Wrap(err) + } + role.SetOrigin(types.OriginKubernetes) + _, err = g.setup.TeleportClient.CreateRole(ctx, role) + return trace.Wrap(err) +} + +func (g *roleV7TestingPrimitives) GetTeleportResource(ctx context.Context, name string) (types.Role, error) { + return g.setup.TeleportClient.GetRole(ctx, name) +} + +func (g *roleV7TestingPrimitives) DeleteTeleportResource(ctx context.Context, name string) error { + return trace.Wrap(g.setup.TeleportClient.DeleteRole(ctx, name)) +} + +func (g *roleV7TestingPrimitives) CreateKubernetesResource(ctx context.Context, name string) error { + role := &resourcesv1.TeleportRoleV7{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: g.setup.Namespace.Name, + }, + Spec: resourcesv1.TeleportRoleV7Spec(roleV7Spec), + } + return trace.Wrap(g.setup.K8sClient.Create(ctx, role)) +} + +func (g *roleV7TestingPrimitives) DeleteKubernetesResource(ctx context.Context, name string) error { + role := &resourcesv1.TeleportRoleV7{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: g.setup.Namespace.Name, + }, + } + return trace.Wrap(g.setup.K8sClient.Delete(ctx, role)) +} + +func (g *roleV7TestingPrimitives) GetKubernetesResource(ctx context.Context, name string) (*resourcesv1.TeleportRoleV7, error) { + role := &resourcesv1.TeleportRoleV7{} + obj := kclient.ObjectKey{ + Name: name, + Namespace: g.setup.Namespace.Name, + } + err := g.setup.K8sClient.Get(ctx, obj, role) + return role, trace.Wrap(err) +} + +func (g *roleV7TestingPrimitives) ModifyKubernetesResource(ctx context.Context, name string) error { + role, err := g.GetKubernetesResource(ctx, name) + if err != nil { + return trace.Wrap(err) + } + role.Spec.Allow.Logins = []string{"foo", "bar"} + return g.setup.K8sClient.Update(ctx, role) +} + +func (g *roleV7TestingPrimitives) CompareTeleportAndKubernetesResource(tResource types.Role, kubeResource *resourcesv1.TeleportRoleV7) (bool, string) { + ignoreServerSideDefaults := []cmp.Option{ + cmpopts.IgnoreFields(types.RoleSpecV6{}, "Options"), + cmpopts.IgnoreFields(types.RoleConditions{}, "Namespaces"), + } + diff := cmp.Diff(tResource, kubeResource.ToTeleport(), testlib.CompareOptions(ignoreServerSideDefaults...)...) + return diff == "", diff +} + +func TestTeleportRoleV7Creation(t *testing.T) { + test := &roleV7TestingPrimitives{} + testlib.ResourceCreationTest[types.Role, *resourcesv1.TeleportRoleV7](t, test) +} + +func TestTeleportRoleV7DeletionDrift(t *testing.T) { + test := &roleV7TestingPrimitives{} + testlib.ResourceDeletionDriftTest[types.Role, *resourcesv1.TeleportRoleV7](t, test) +} + +func TestTeleportRoleV7Update(t *testing.T) { + test := &roleV7TestingPrimitives{} + testlib.ResourceUpdateTest[types.Role, *resourcesv1.TeleportRoleV7](t, test) +} diff --git a/integrations/operator/controllers/resources/rolevX_controller.go b/integrations/operator/controllers/resources/rolevX_controller.go new file mode 100644 index 0000000000000..c4ceaf7ec7903 --- /dev/null +++ b/integrations/operator/controllers/resources/rolevX_controller.go @@ -0,0 +1,104 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package resources + +import ( + "context" + + "github.com/gravitational/trace" + kclient "sigs.k8s.io/controller-runtime/pkg/client" + + "github.com/gravitational/teleport/api/client" + "github.com/gravitational/teleport/api/types" + resourcesv1 "github.com/gravitational/teleport/integrations/operator/apis/resources/v1" + resourcesv5 "github.com/gravitational/teleport/integrations/operator/apis/resources/v5" +) + +// roleClient implements TeleportResourceClient and offers CRUD methods needed to reconcile roles +// Currently the same client is used by all role versions. If we need to treat +// them differently at some point, for example by introducing Mutate or MutateExisting +// functions, we can always split the client into separate clients. +type roleClient struct { + teleportClient *client.Client +} + +// Get gets the Teleport role of a given name +func (r roleClient) Get(ctx context.Context, name string) (types.Role, error) { + role, err := r.teleportClient.GetRole(ctx, name) + return role, trace.Wrap(err) +} + +// Create creates a Teleport role +func (r roleClient) Create(ctx context.Context, role types.Role) error { + _, err := r.teleportClient.UpsertRole(ctx, role) + return trace.Wrap(err) +} + +// Update updates a Teleport role +func (r roleClient) Update(ctx context.Context, role types.Role) error { + _, err := r.teleportClient.UpsertRole(ctx, role) + return trace.Wrap(err) +} + +// Delete deletes a Teleport role +func (r roleClient) Delete(ctx context.Context, name string) error { + return trace.Wrap(r.teleportClient.DeleteRole(ctx, name)) +} + +// NewRoleReconciler instantiates a new Kubernetes controller reconciling legacy role v5 resources +func NewRoleReconciler(client kclient.Client, tClient *client.Client) (Reconciler, error) { + roleClient := &roleClient{ + teleportClient: tClient, + } + + resourceReconciler, err := NewTeleportResourceReconciler[types.Role, *resourcesv5.TeleportRole]( + client, + roleClient, + ) + + return resourceReconciler, trace.Wrap(err, "building teleport resource reconciler") +} + +// NewRoleV6Reconciler instantiates a new Kubernetes controller reconciling role v6 resources +func NewRoleV6Reconciler(client kclient.Client, tClient *client.Client) (Reconciler, error) { + roleClient := &roleClient{ + teleportClient: tClient, + } + + resourceReconciler, err := NewTeleportResourceReconciler[types.Role, *resourcesv1.TeleportRoleV6]( + client, + roleClient, + ) + + return resourceReconciler, trace.Wrap(err, "building teleport resource reconciler") +} + +// NewRoleV7Reconciler instantiates a new Kubernetes controller reconciling role v7 resources +func NewRoleV7Reconciler(client kclient.Client, tClient *client.Client) (Reconciler, error) { + roleClient := &roleClient{ + teleportClient: tClient, + } + + resourceReconciler, err := NewTeleportResourceReconciler[types.Role, *resourcesv1.TeleportRoleV7]( + client, + roleClient, + ) + + return resourceReconciler, trace.Wrap(err, "building teleport resource reconciler") +} diff --git a/integrations/operator/controllers/resources/saml_connector_controller.go b/integrations/operator/controllers/resources/saml_connector_controller.go index 299fc48112bf7..e940fcec91340 100644 --- a/integrations/operator/controllers/resources/saml_connector_controller.go +++ b/integrations/operator/controllers/resources/saml_connector_controller.go @@ -58,15 +58,15 @@ func (r samlConnectorClient) Delete(ctx context.Context, name string) error { } // NewSAMLConnectorReconciler instantiates a new Kubernetes controller reconciling saml_connector resources -func NewSAMLConnectorReconciler(client kclient.Client, tClient *client.Client) *TeleportResourceReconciler[types.SAMLConnector, *resourcesv2.TeleportSAMLConnector] { +func NewSAMLConnectorReconciler(client kclient.Client, tClient *client.Client) (Reconciler, error) { samlClient := &samlConnectorClient{ teleportClient: tClient, } - resourceReconciler := NewTeleportResourceReconciler[types.SAMLConnector, *resourcesv2.TeleportSAMLConnector]( + resourceReconciler, err := NewTeleportResourceReconciler[types.SAMLConnector, *resourcesv2.TeleportSAMLConnector]( client, samlClient, ) - return resourceReconciler + return resourceReconciler, trace.Wrap(err, "building teleport resource reconciler") } diff --git a/integrations/operator/controllers/resources/teleport_reconciler.go b/integrations/operator/controllers/resources/teleport_reconciler.go index f9879e29865f3..8052a22fe67d1 100644 --- a/integrations/operator/controllers/resources/teleport_reconciler.go +++ b/integrations/operator/controllers/resources/teleport_reconciler.go @@ -20,11 +20,15 @@ package resources import ( "context" + "fmt" "reflect" "slices" "github.com/gravitational/trace" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" ctrl "sigs.k8s.io/controller-runtime" kclient "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/event" @@ -53,6 +57,7 @@ type TeleportKubernetesResource[T TeleportResource] interface { type TeleportResourceReconciler[T TeleportResource, K TeleportKubernetesResource[T]] struct { ResourceBaseReconciler resourceClient TeleportResourceClient[T] + gvk schema.GroupVersionKind } // TeleportResourceClient is a CRUD client for a specific Teleport resource. @@ -82,28 +87,51 @@ type TeleportExistingResourceMutator[T TeleportResource] interface { func NewTeleportResourceReconciler[T TeleportResource, K TeleportKubernetesResource[T]]( client kclient.Client, resourceClient TeleportResourceClient[T], -) *TeleportResourceReconciler[T, K] { +) (*TeleportResourceReconciler[T, K], error) { + gvk, err := gvkFromScheme[T, K](Scheme) + if err != nil { + return nil, trace.Wrap(err) + } reconciler := &TeleportResourceReconciler[T, K]{ ResourceBaseReconciler: ResourceBaseReconciler{Client: client}, resourceClient: resourceClient, + gvk: gvk, } reconciler.ResourceBaseReconciler.UpsertExternal = reconciler.Upsert reconciler.ResourceBaseReconciler.DeleteExternal = reconciler.Delete - return reconciler + return reconciler, nil } -// Upsert is the TeleportResourceReconciler of the ResourceBaseReconciler UpsertExertal +// Upsert is the TeleportResourceReconciler of the ResourceBaseReconciler UpsertExternal // It contains the logic to check if the resource already exists, if it is owned by the operator and what // to do to reconcile the Teleport resource based on the Kubernetes one. func (r TeleportResourceReconciler[T, K]) Upsert(ctx context.Context, obj kclient.Object) error { - k8sResource, ok := obj.(K) + u, ok := obj.(*unstructured.Unstructured) if !ok { - return trace.BadParameter("failed to convert Object into resource object: %T", obj) + return fmt.Errorf("failed to convert Object into resource object: %T", obj) + } + k8sResource := newKubeResource[T, K]() + + // If an error happens we want to put it in status.conditions before returning. + err := runtime.DefaultUnstructuredConverter.FromUnstructuredWithValidation( + u.Object, + k8sResource, + true, /* returnUnknownFields */ + ) + updateErr := updateStatus(updateStatusConfig{ + ctx: ctx, + client: r.Client, + k8sResource: k8sResource, + condition: getStructureConditionFromError(err), + }) + if err != nil || updateErr != nil { + return trace.NewAggregate(err, updateErr) } + teleportResource := k8sResource.ToTeleport() existingResource, err := r.resourceClient.Get(ctx, teleportResource.GetName()) - updateErr := updateStatus(updateStatusConfig{ + updateErr = updateStatus(updateStatusConfig{ ctx: ctx, client: r.Client, k8sResource: k8sResource, @@ -176,22 +204,49 @@ func (r TeleportResourceReconciler[T, K]) Delete(ctx context.Context, obj kclien // Reconcile allows the TeleportResourceReconciler to implement the reconcile.Reconciler interface func (r TeleportResourceReconciler[T, K]) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - kubeResource := newKubeResource[T, K]() - return r.Do(ctx, req, kubeResource) + obj, err := GetUnstructuredObjectFromGVK(r.gvk) + if err != nil { + return ctrl.Result{}, trace.Wrap(err, "creating object in which the CR will be unmarshalled") + } + return r.Do(ctx, req, obj) } // SetupWithManager have a controllerruntime.Manager run the TeleportResourceReconciler func (r TeleportResourceReconciler[T, K]) SetupWithManager(mgr ctrl.Manager) error { - kubeResource := newKubeResource[T, K]() + // The TeleportResourceReconciler uses unstructured objects because of a silly json marshaling + // issue. Teleport's utils.String is a list of strings, but marshals as a single string if there's a single item. + // This is a questionable design as it breaks the openapi schema, but we're stuck with it. We had to relax openapi + // validation in those CRD fields, and use an unstructured object for the client, else JSON unmarshalling fails. + obj, err := GetUnstructuredObjectFromGVK(r.gvk) + if err != nil { + return trace.Wrap(err, "creating the model object for the manager watcher/client") + } return ctrl. NewControllerManagedBy(mgr). - For(kubeResource). + For(obj). WithEventFilter( buildPredicate(), ). Complete(r) } +// gvkFromScheme looks up the GVK from the a runtime scheme. +// The structured type must have been registered before in the scheme. This function is used when you have a structured +// type, a scheme containing this structured type, and want to build an unstructured object for the same GVK. +func gvkFromScheme[T TeleportResource, K TeleportKubernetesResource[T]](scheme *runtime.Scheme) (schema.GroupVersionKind, error) { + structuredObj := newKubeResource[T, K]() + gvks, _, err := scheme.ObjectKinds(structuredObj) + if err != nil { + return schema.GroupVersionKind{}, trace.Wrap(err, "looking up gvk in scheme for type %T", structuredObj) + } + if len(gvks) != 1 { + return schema.GroupVersionKind{}, trace.CompareFailed( + "failed GVK lookup in scheme, looked up %T and got %d matches, expected 1", structuredObj, len(gvks), + ) + } + return gvks[0], nil +} + // newKubeResource creates a new TeleportKubernetesResource // the function supports structs or pointer to struct implementations of the TeleportKubernetesResource interface func newKubeResource[T TeleportResource, K TeleportKubernetesResource[T]]() K { diff --git a/integrations/operator/controllers/resources/testlib/accesslist_controller_tests.go b/integrations/operator/controllers/resources/testlib/accesslist_controller_tests.go index 6bce0ec137679..7fb39cab9ef02 100644 --- a/integrations/operator/controllers/resources/testlib/accesslist_controller_tests.go +++ b/integrations/operator/controllers/resources/testlib/accesslist_controller_tests.go @@ -26,6 +26,8 @@ import ( "github.com/gravitational/trace" "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" kclient "sigs.k8s.io/controller-runtime/pkg/client" "github.com/gravitational/teleport/api/client" @@ -211,10 +213,24 @@ func AccessListMutateExistingTest(t *testing.T, clt *client.Client) { } require.NoError(t, setup.K8sClient.Get(ctx, key, kubeAccessList)) - reconciler := resources.NewAccessListReconciler(setup.K8sClient, clt) + reconciler, err := resources.NewAccessListReconciler(setup.K8sClient, clt) + require.NoError(t, err) + // TODO: remove this hack when the role controller uses the teleport reconciler + // and we can simplify Do, UpsertExternal, Upsert and Reconcile + r, ok := reconciler.(interface { + Upsert(context.Context, kclient.Object) error + }) + require.True(t, ok) + + // Also a hack: convert the structured object into an unstructured one + // to accommodate the teleport reconciler that casts first as an + // unstructured object before converting into the final struct. + content, err := runtime.DefaultUnstructuredConverter.ToUnstructured(kubeAccessList) + require.NoError(t, err) + obj := &unstructured.Unstructured{Object: content} // Test execution: we trigger a single reconciliation - require.NoError(t, reconciler.Upsert(ctx, kubeAccessList)) + require.NoError(t, r.Upsert(ctx, obj)) // Then we check if the AccessList audit date has been preserved in teleport accessList, err = clt.AccessListClient().GetAccessList(ctx, name) diff --git a/integrations/operator/controllers/resources/testlib/env.go b/integrations/operator/controllers/resources/testlib/env.go index 4bcb6e245f807..3b45638285dcf 100644 --- a/integrations/operator/controllers/resources/testlib/env.go +++ b/integrations/operator/controllers/resources/testlib/env.go @@ -31,14 +31,16 @@ import ( "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" core "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - apiruntime "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/client-go/rest" ctrl "sigs.k8s.io/controller-runtime" + ctrlclient "sigs.k8s.io/controller-runtime/pkg/client" kclient "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/envtest" + "sigs.k8s.io/controller-runtime/pkg/log/zap" "sigs.k8s.io/controller-runtime/pkg/manager" metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" @@ -56,7 +58,7 @@ import ( // scheme is our own test-specific scheme to avoid using the global // unprotected scheme.Scheme that triggers the race detector -var scheme = apiruntime.NewScheme() +var scheme = resources.Scheme func init() { utilruntime.Must(core.AddToScheme(scheme)) @@ -186,38 +188,17 @@ func (s *TestSetup) StartKubernetesOperator(t *testing.T) { k8sManager, err := ctrl.NewManager(s.K8sRestConfig, ctrl.Options{ Scheme: scheme, Metrics: metricsserver.Options{BindAddress: "0"}, + // We enable cache to ensure the tests are close to how the manager is created when running in a real cluster + Client: ctrlclient.Options{Cache: &ctrlclient.CacheOptions{Unstructured: true}}, }) require.NoError(t, err) - err = (&resources.RoleReconciler{ - Client: s.K8sClient, - Scheme: k8sManager.GetScheme(), - TeleportClient: s.TeleportClient, - }).SetupWithManager(k8sManager) - require.NoError(t, err) - - err = resources.NewUserReconciler(s.K8sClient, s.TeleportClient).SetupWithManager(k8sManager) - require.NoError(t, err) - - err = resources.NewGithubConnectorReconciler(s.K8sClient, s.TeleportClient).SetupWithManager(k8sManager) - require.NoError(t, err) - - err = resources.NewOIDCConnectorReconciler(s.K8sClient, s.TeleportClient).SetupWithManager(k8sManager) - require.NoError(t, err) + setupLog := ctrl.Log.WithName("setup") + ctrl.SetLogger(zap.New(zap.UseDevMode(true), zap.Level(zapcore.DebugLevel))) - err = resources.NewSAMLConnectorReconciler(s.K8sClient, s.TeleportClient).SetupWithManager(k8sManager) + pong, err := s.TeleportClient.Ping(context.Background()) require.NoError(t, err) - - err = resources.NewLoginRuleReconciler(s.K8sClient, s.TeleportClient).SetupWithManager(k8sManager) - require.NoError(t, err) - - err = resources.NewProvisionTokenReconciler(s.K8sClient, s.TeleportClient).SetupWithManager(k8sManager) - require.NoError(t, err) - - err = resources.NewOktaImportRuleReconciler(s.K8sClient, s.TeleportClient).SetupWithManager(k8sManager) - require.NoError(t, err) - - err = resources.NewAccessListReconciler(s.K8sClient, s.TeleportClient).SetupWithManager(k8sManager) + err = resources.SetupAllControllers(setupLog, k8sManager, s.TeleportClient, pong.ServerFeatures) require.NoError(t, err) ctx, ctxCancel := context.WithCancel(context.Background()) diff --git a/integrations/operator/controllers/resources/user_controller.go b/integrations/operator/controllers/resources/user_controller.go index a405a7f9ed73d..d446e1a3c3eaa 100644 --- a/integrations/operator/controllers/resources/user_controller.go +++ b/integrations/operator/controllers/resources/user_controller.go @@ -65,15 +65,15 @@ func (r userClient) MutateExisting(newUser, existingUser types.User) { } // NewUserReconciler instantiates a new Kubernetes controller reconciling user resources -func NewUserReconciler(client kclient.Client, tClient *client.Client) *TeleportResourceReconciler[types.User, *resourcesv2.TeleportUser] { +func NewUserReconciler(client kclient.Client, tClient *client.Client) (Reconciler, error) { userClient := &userClient{ teleportClient: tClient, } - resourceReconciler := NewTeleportResourceReconciler[types.User, *resourcesv2.TeleportUser]( + resourceReconciler, err := NewTeleportResourceReconciler[types.User, *resourcesv2.TeleportUser]( client, userClient, ) - return resourceReconciler + return resourceReconciler, trace.Wrap(err, "building teleport resource reconciler") } diff --git a/integrations/operator/controllers/resources/user_controller_test.go b/integrations/operator/controllers/resources/user_controller_test.go index 57152c2500fce..38d56d3bf711a 100644 --- a/integrations/operator/controllers/resources/user_controller_test.go +++ b/integrations/operator/controllers/resources/user_controller_test.go @@ -37,8 +37,8 @@ import ( kclient "sigs.k8s.io/controller-runtime/pkg/client" "github.com/gravitational/teleport/api/types" + apiresources "github.com/gravitational/teleport/integrations/operator/apis/resources" v2 "github.com/gravitational/teleport/integrations/operator/apis/resources/v2" - resourcesv5 "github.com/gravitational/teleport/integrations/operator/apis/resources/v5" "github.com/gravitational/teleport/integrations/operator/controllers/resources" "github.com/gravitational/teleport/integrations/operator/controllers/resources/testlib" ) @@ -159,7 +159,8 @@ traits: userName := validRandomResourceName("user-") - obj := resources.GetUnstructuredObjectFromGVK(teleportUserGVK) + obj, err := resources.GetUnstructuredObjectFromGVK(teleportUserGVK) + require.NoError(t, err) obj.Object["spec"] = userManifest obj.SetName(userName) obj.SetNamespace(setup.Namespace.Name) @@ -399,7 +400,7 @@ func k8sCreateUser(ctx context.Context, t *testing.T, kc kclient.Client, user *v func getUserStatusConditionError(object map[string]interface{}) []metav1.Condition { var conditionsWithError []metav1.Condition - var status resourcesv5.TeleportRoleStatus + var status apiresources.Status _ = mapstructure.Decode(object["status"], &status) for _, condition := range status.Conditions { diff --git a/integrations/operator/controllers/resources/utils.go b/integrations/operator/controllers/resources/utils.go index e4a798b0bc771..32d48ece073f9 100644 --- a/integrations/operator/controllers/resources/utils.go +++ b/integrations/operator/controllers/resources/utils.go @@ -21,10 +21,13 @@ package resources import ( "context" "fmt" + "strconv" "github.com/gravitational/trace" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" kclient "sigs.k8s.io/controller-runtime/pkg/client" ctrllog "sigs.k8s.io/controller-runtime/pkg/log" @@ -156,3 +159,29 @@ func updateStatus(config updateStatusConfig) error { } return trace.Wrap(statusErr) } + +// GetUnstructuredObjectFromGVK creates a new empty unstructured object with the +// given Group Version and Kind. +func GetUnstructuredObjectFromGVK(gvk schema.GroupVersionKind) (*unstructured.Unstructured, error) { + if gvk.Empty() { + return nil, trace.BadParameter("cannot create an object for an empty GVK, aborting") + } + obj := unstructured.Unstructured{} + obj.SetGroupVersionKind(gvk) + return &obj, nil +} + +// checkAnnotationFlag checks is the Kubernetes resource is annotated with a +// flag and parses its value. Returns the default value if the flag is missing +// or the annotation value cannot be parsed. +func checkAnnotationFlag(object kclient.Object, flagName string, defaultValue bool) bool { + annotation, ok := object.GetAnnotations()[flagName] + if !ok { + return defaultValue + } + value, err := strconv.ParseBool(annotation) + if err != nil { + return defaultValue + } + return value +} diff --git a/integrations/operator/controllers/resources/utils_test.go b/integrations/operator/controllers/resources/utils_test.go index 0c7c1a0b07852..d22ed80697712 100644 --- a/integrations/operator/controllers/resources/utils_test.go +++ b/integrations/operator/controllers/resources/utils_test.go @@ -23,6 +23,7 @@ import ( "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "github.com/gravitational/teleport/api/types" ) @@ -95,3 +96,71 @@ func TestCheckOwnership(t *testing.T) { }) } } + +func TestCheckAnnotationFlag(t *testing.T) { + testFlag := "foo" + tests := []struct { + name string + annotations map[string]string + defaultValue bool + expectedOutput bool + }{ + { + name: "flag set true, default true", + annotations: map[string]string{testFlag: "true"}, + defaultValue: true, + expectedOutput: true, + }, + { + name: "flag set false, default true", + annotations: map[string]string{testFlag: "false"}, + defaultValue: true, + expectedOutput: false, + }, + { + name: "flag set true, default false", + annotations: map[string]string{testFlag: "true"}, + defaultValue: false, + expectedOutput: true, + }, + { + name: "flag set false, default false", + annotations: map[string]string{testFlag: "false"}, + defaultValue: false, + expectedOutput: false, + }, + { + name: "flag missing, default true", + annotations: map[string]string{}, + defaultValue: true, + expectedOutput: true, + }, + { + name: "flag missing, default false", + annotations: map[string]string{}, + defaultValue: false, + expectedOutput: false, + }, + { + name: "flag malformed, default true", + annotations: map[string]string{testFlag: "malformed"}, + defaultValue: true, + expectedOutput: true, + }, + { + name: "flag malformed, default false", + annotations: map[string]string{testFlag: "malformed"}, + defaultValue: false, + expectedOutput: false, + }, + } + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + obj := &unstructured.Unstructured{} + obj.SetAnnotations(tt.annotations) + require.Equal(t, tt.expectedOutput, checkAnnotationFlag(obj, testFlag, tt.defaultValue)) + }) + } +} diff --git a/integrations/operator/crdgen/handlerequest.go b/integrations/operator/crdgen/handlerequest.go index 6ef0331b22a42..27c788aa69a5d 100644 --- a/integrations/operator/crdgen/handlerequest.go +++ b/integrations/operator/crdgen/handlerequest.go @@ -85,8 +85,14 @@ func generateSchema(file *File, groupName string, resp *gogoplugin.CodeGenerator resources := []resource{ {name: "UserV2"}, + // Role V5 is using the RoleV6 message {name: "RoleV6", opts: []resourceSchemaOption{withVersionOverride(types.V5)}}, + // For backward compatibility in v15, it actually creates v5 roles though. {name: "RoleV6"}, + // Role V6 and V7 have their own Kubernetes kind + {name: "RoleV6", opts: []resourceSchemaOption{withVersionInKindOverride()}}, + // Role V7 is using the RoleV6 message + {name: "RoleV6", opts: []resourceSchemaOption{withVersionOverride(types.V7), withVersionInKindOverride()}}, {name: "SAMLConnectorV2"}, {name: "OIDCConnectorV3"}, {name: "GithubConnectorV3"}, @@ -122,10 +128,13 @@ func generateSchema(file *File, groupName string, resp *gogoplugin.CodeGenerator } for _, root := range generator.roots { - crd := root.CustomResourceDefinition() + crd, err := root.CustomResourceDefinition() + if err != nil { + return trace.Wrap(err, "generating CRD") + } data, err := yaml.Marshal(crd) if err != nil { - return trace.Wrap(err) + return trace.Wrap(err, "marshaling CRD") } name := fmt.Sprintf("%s_%s.yaml", groupName, root.pluralName) content := string(data) diff --git a/integrations/operator/crdgen/schemagen.go b/integrations/operator/crdgen/schemagen.go index e550f9513e6c4..4d480828bca91 100644 --- a/integrations/operator/crdgen/schemagen.go +++ b/integrations/operator/crdgen/schemagen.go @@ -34,7 +34,13 @@ import ( "sigs.k8s.io/controller-tools/pkg/markers" ) -const k8sKindPrefix = "Teleport" +const ( + k8sKindPrefix = "Teleport" + statusPackagePath = "github.com/gravitational/teleport/integrations/operator/apis" + statusPackageName = "resources" + statusPackage = statusPackagePath + "/" + statusPackageName + statusTypeName = "Status" +) // Add names to this array when adding support to new Teleport resources that could conflict with Kubernetes var ( @@ -55,10 +61,21 @@ type RootSchema struct { versions []SchemaVersion name string pluralName string - kind string + // teleportKind is the kind of the Teleport resource + teleportKind string + // kubernetesKind is the kind of the Kubernetes resource. This is the + // teleportKind, prefixed by "Teleport" and potentially suffixed by the + // version. Since v15, resources with multiple versions are exposed through + // different kinds. At some point we will suffix all kinds by the version + // and deprecate the old resources. + kubernetesKind string } type SchemaVersion struct { + // Version is the Kubernetes CR API version. For single-version + // Teleport resource, this is equal to the Teleport resource Version for + // compatibility purposes. For multi-version resource, the value is always + // "v1" as the version is already in the CR kind. Version string Schema *Schema } @@ -92,8 +109,9 @@ func NewSchema() *Schema { } type resourceSchemaConfig struct { - versionOverride string - customSpecFields []string + versionOverride string + customSpecFields []string + kindContainsVersion bool } type resourceSchemaOption func(*resourceSchemaConfig) @@ -104,6 +122,13 @@ func withVersionOverride(version string) resourceSchemaOption { } } +// set this onlt on new multi-version resources +func withVersionInKindOverride() resourceSchemaOption { + return func(cfg *resourceSchemaConfig) { + cfg.kindContainsVersion = true + } +} + func withCustomSpecFields(customSpecFields []string) resourceSchemaOption { return func(cfg *resourceSchemaConfig) { cfg.customSpecFields = customSpecFields @@ -165,20 +190,38 @@ func (generator *SchemaGenerator) addResource(file *File, name string, opts ...r if cfg.versionOverride != "" { resourceVersion = cfg.versionOverride } + kubernetesKind := resourceKind + if cfg.kindContainsVersion { + kubernetesKind = resourceKind + strings.ToUpper(resourceVersion) + } schema.Description = fmt.Sprintf("%s resource definition %s from Teleport", resourceKind, resourceVersion) - root, ok := generator.roots[resourceKind] + root, ok := generator.roots[kubernetesKind] if !ok { + pluralName := strings.ToLower(english.PluralWord(2, resourceKind, "")) + if cfg.kindContainsVersion { + pluralName = pluralName + resourceVersion + } root = &RootSchema{ - groupName: generator.groupName, - kind: resourceKind, - name: strings.ToLower(resourceKind), - pluralName: strings.ToLower(english.PluralWord(2, resourceKind, "")), + groupName: generator.groupName, + teleportKind: resourceKind, + kubernetesKind: kubernetesKind, + name: strings.ToLower(kubernetesKind), + pluralName: pluralName, } - generator.roots[resourceKind] = root + generator.roots[kubernetesKind] = root + } + + // For legacy CRs with a single version, we use the Teleport version as the + // Kubernetes API version + kubernetesVersion := resourceVersion + if cfg.kindContainsVersion { + // For new multi-version resources we always set the version to "v1" as + // the Teleport version is also in the CR kind. + kubernetesVersion = "v1" } root.versions = append(root.versions, SchemaVersion{ - Version: resourceVersion, + Version: kubernetesVersion, Schema: schema, }) @@ -378,7 +421,7 @@ func (generator *SchemaGenerator) singularProp(field *Field, prop *apiextv1.JSON return nil } -func (root RootSchema) CustomResourceDefinition() apiextv1.CustomResourceDefinition { +func (root RootSchema) CustomResourceDefinition() (apiextv1.CustomResourceDefinition, error) { crd := apiextv1.CustomResourceDefinition{ TypeMeta: metav1.TypeMeta{ APIVersion: apiextv1.SchemeGroupVersion.String(), @@ -390,8 +433,8 @@ func (root RootSchema) CustomResourceDefinition() apiextv1.CustomResourceDefinit Spec: apiextv1.CustomResourceDefinitionSpec{ Group: root.groupName, Names: apiextv1.CustomResourceDefinitionNames{ - Kind: k8sKindPrefix + root.kind, - ListKind: k8sKindPrefix + root.kind + "List", + Kind: k8sKindPrefix + root.kubernetesKind, + ListKind: k8sKindPrefix + root.kubernetesKind + "List", Plural: strings.ToLower(k8sKindPrefix + root.pluralName), Singular: strings.ToLower(k8sKindPrefix + root.name), ShortNames: root.getShortNames(), @@ -408,7 +451,11 @@ func (root RootSchema) CustomResourceDefinition() apiextv1.CustomResourceDefinit registry := &markers.Registry{} // CRD markers contain special markers used by the parser to discover properties // e.g. `+kubebuilder:validation:Minimum=0` - crdmarkers.Register(registry) + err := crdmarkers.Register(registry) + if err != nil { + return apiextv1.CustomResourceDefinition{}, + trace.Wrap(err, "adding CRD markers to the registry") + } parser := &crdtools.Parser{ Collector: &markers.Collector{Registry: registry}, Checker: &loader.TypeChecker{}, @@ -417,31 +464,20 @@ func (root RootSchema) CustomResourceDefinition() apiextv1.CustomResourceDefinit // Some types are special and require manual overrides, like metav1.Time. crdtools.AddKnownTypes(parser) - pkgs, err := loader.LoadRoots("github.com/gravitational/teleport/integrations/operator/apis/...") + // Status does not exist in Teleport, only in the CR. + // We parse go's AST to find its struct and convert it in a schema. + statusSchema, err := getStatusSchema(parser) if err != nil { - fmt.Printf("parser error: %s", err) + return apiextv1.CustomResourceDefinition{}, + trace.Wrap(err, "getting status schema from go's AST") } for i, schemaVersion := range root.versions { - var statusType crdtools.TypeIdent - versionName := schemaVersion.Version schema := schemaVersion.Schema - for _, pkg := range pkgs { - // This if is a bit janky, condition checking should be stronger - if pkg.Name == versionName { - parser.NeedPackage(pkg) - statusType = crdtools.TypeIdent{ - Package: pkg, - Name: fmt.Sprintf("%s%sStatus", k8sKindPrefix, root.kind), - } - // Kubernetes CRDs don't support $ref in openapi schemas, we need a flattened schema - parser.NeedFlattenedSchemaFor(statusType) - } - } crd.Spec.Versions = append(crd.Spec.Versions, apiextv1.CustomResourceDefinitionVersion{ - Name: versionName, + Name: schemaVersion.Version, Served: true, // Storage the first version available. Storage: i == 0, @@ -451,7 +487,7 @@ func (root RootSchema) CustomResourceDefinition() apiextv1.CustomResourceDefinit Schema: &apiextv1.CustomResourceValidation{ OpenAPIV3Schema: &apiextv1.JSONSchemaProps{ Type: "object", - Description: fmt.Sprintf("%s is the Schema for the %s API", root.kind, root.pluralName), + Description: fmt.Sprintf("%s is the Schema for the %s API", root.kubernetesKind, root.pluralName), Properties: map[string]apiextv1.JSONSchemaProps{ "apiVersion": { Type: "string", @@ -463,13 +499,13 @@ func (root RootSchema) CustomResourceDefinition() apiextv1.CustomResourceDefinit }, "metadata": {Type: "object"}, "spec": schema.JSONSchemaProps, - "status": parser.FlattenedSchemata[statusType], + "status": statusSchema, }, }, }, }) } - return crd + return crd, nil } // getShortNames returns the schema short names while ensuring they won't conflict with existing Kubernetes resources @@ -480,3 +516,25 @@ func (root RootSchema) getShortNames() []string { } return []string{root.name, root.pluralName} } + +func getStatusSchema(parser *crdtools.Parser) (apiextv1.JSONSchemaProps, error) { + pkgs, err := loader.LoadRoots(statusPackage) + if err != nil { + // Loader errors might be non-critical. + // e.g. the loader complains about the unknown "toolchain" directive in our go mod + fmt.Printf("loader error: %s", err) + } + var statusType crdtools.TypeIdent + for _, pkg := range pkgs { + if pkg.Name == "resources" { + parser.NeedPackage(pkg) + statusType = crdtools.TypeIdent{ + Package: pkg, + Name: statusTypeName, + } + parser.NeedFlattenedSchemaFor(statusType) + return parser.FlattenedSchemata[statusType], nil + } + } + return apiextv1.JSONSchemaProps{}, trace.NotFound("Package %q not found, cannot generate status JSON Schema", statusPackage) +} diff --git a/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_accesslists.yaml b/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_accesslists.yaml index 88cafa60554a5..4c9c2918d03ec 100644 --- a/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_accesslists.yaml +++ b/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_accesslists.yaml @@ -170,6 +170,7 @@ spec: type: string type: object status: + description: Status defines the observed state of the Teleport resource properties: conditions: description: Conditions represent the latest available observations diff --git a/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_githubconnectors.yaml b/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_githubconnectors.yaml index a262e618b0154..b96d4eb6e8734 100644 --- a/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_githubconnectors.yaml +++ b/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_githubconnectors.yaml @@ -78,8 +78,7 @@ spec: type: array type: object status: - description: TeleportGithubConnectorStatus defines the observed state - of TeleportGithubConnector + description: Status defines the observed state of the Teleport resource properties: conditions: description: Conditions represent the latest available observations diff --git a/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_loginrules.yaml b/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_loginrules.yaml index cdb3a30050b51..7b5928ca4c255 100644 --- a/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_loginrules.yaml +++ b/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_loginrules.yaml @@ -57,6 +57,7 @@ spec: type: object type: object status: + description: Status defines the observed state of the Teleport resource properties: conditions: description: Conditions represent the latest available observations diff --git a/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_oidcconnectors.yaml b/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_oidcconnectors.yaml index edd8bf5e13623..087bdc7d4a4b1 100644 --- a/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_oidcconnectors.yaml +++ b/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_oidcconnectors.yaml @@ -123,8 +123,7 @@ spec: type: string type: object status: - description: TeleportOIDCConnectorStatus defines the observed state of - TeleportOIDCConnector + description: Status defines the observed state of the Teleport resource properties: conditions: description: Conditions represent the latest available observations diff --git a/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_oktaimportrules.yaml b/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_oktaimportrules.yaml index b16ac422df459..f6077e45c357f 100644 --- a/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_oktaimportrules.yaml +++ b/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_oktaimportrules.yaml @@ -95,6 +95,7 @@ spec: type: integer type: object status: + description: Status defines the observed state of the Teleport resource properties: conditions: description: Conditions represent the latest available observations diff --git a/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_provisiontokens.yaml b/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_provisiontokens.yaml index e5ee2931647b9..a27f54890e348 100644 --- a/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_provisiontokens.yaml +++ b/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_provisiontokens.yaml @@ -263,8 +263,7 @@ spec: type: object type: object status: - description: TeleportProvisionTokenStatus defines the observed state of - TeleportProvisionToken + description: Status defines the observed state of the Teleport resource properties: conditions: description: Conditions represent the latest available observations diff --git a/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_roles.yaml b/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_roles.yaml index 5678aae4b8eeb..8dc82f85ee6ac 100644 --- a/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_roles.yaml +++ b/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_roles.yaml @@ -1124,7 +1124,7 @@ spec: type: object type: object status: - description: TeleportRoleStatus defines the observed state of TeleportRole + description: Status defines the observed state of the Teleport resource properties: conditions: description: Conditions represent the latest available observations @@ -2318,7 +2318,7 @@ spec: type: object type: object status: - description: TeleportRoleStatus defines the observed state of TeleportRole + description: Status defines the observed state of the Teleport resource properties: conditions: description: Conditions represent the latest available observations diff --git a/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_rolesv6.yaml b/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_rolesv6.yaml new file mode 100644 index 0000000000000..c09e644792aaf --- /dev/null +++ b/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_rolesv6.yaml @@ -0,0 +1,1217 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + name: teleportrolesv6.resources.teleport.dev +spec: + group: resources.teleport.dev + names: + kind: TeleportRoleV6 + listKind: TeleportRoleV6List + plural: teleportrolesv6 + shortNames: + - rolev6 + - rolesv6 + singular: teleportrolev6 + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: RoleV6 is the Schema for the rolesv6 API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Role resource definition v6 from Teleport + properties: + allow: + description: Allow is the set of conditions evaluated to grant access. + properties: + app_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: AppLabels is a map of labels used as part of the + RBAC system. + type: object + app_labels_expression: + description: AppLabelsExpression is a predicate expression used + to allow/deny access to Apps. + type: string + aws_role_arns: + description: AWSRoleARNs is a list of AWS role ARNs this role + is allowed to assume. + items: + type: string + nullable: true + type: array + azure_identities: + description: AzureIdentities is a list of Azure identities this + role is allowed to assume. + items: + type: string + nullable: true + type: array + cluster_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: ClusterLabels is a map of node labels (used to dynamically + grant access to clusters). + type: object + cluster_labels_expression: + description: ClusterLabelsExpression is a predicate expression + used to allow/deny access to remote Teleport clusters. + type: string + db_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: DatabaseLabels are used in RBAC system to allow/deny + access to databases. + type: object + db_labels_expression: + description: DatabaseLabelsExpression is a predicate expression + used to allow/deny access to Databases. + type: string + db_names: + description: DatabaseNames is a list of database names this role + is allowed to connect to. + items: + type: string + nullable: true + type: array + db_roles: + description: DatabaseRoles is a list of databases roles for automatic + user creation. + items: + type: string + nullable: true + type: array + db_service_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: DatabaseServiceLabels are used in RBAC system to + allow/deny access to Database Services. + type: object + db_service_labels_expression: + description: DatabaseServiceLabelsExpression is a predicate expression + used to allow/deny access to Database Services. + type: string + db_users: + description: DatabaseUsers is a list of databases users this role + is allowed to connect as. + items: + type: string + nullable: true + type: array + desktop_groups: + description: DesktopGroups is a list of groups for created desktop + users to be added to + items: + type: string + nullable: true + type: array + gcp_service_accounts: + description: GCPServiceAccounts is a list of GCP service accounts + this role is allowed to assume. + items: + type: string + nullable: true + type: array + group_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: GroupLabels is a map of labels used as part of the + RBAC system. + type: object + group_labels_expression: + description: GroupLabelsExpression is a predicate expression used + to allow/deny access to user groups. + type: string + host_groups: + description: HostGroups is a list of groups for created users + to be added to + items: + type: string + nullable: true + type: array + host_sudoers: + description: HostSudoers is a list of entries to include in a + users sudoer file + items: + type: string + nullable: true + type: array + impersonate: + description: Impersonate specifies what users and roles this role + is allowed to impersonate by issuing certificates or other possible + means. + nullable: true + properties: + roles: + description: Roles is a list of resources this role is allowed + to impersonate + items: + type: string + nullable: true + type: array + users: + description: Users is a list of resources this role is allowed + to impersonate, could be an empty list or a Wildcard pattern + items: + type: string + nullable: true + type: array + where: + description: Where specifies optional advanced matcher + type: string + type: object + join_sessions: + description: JoinSessions specifies policies to allow users to + join other sessions. + items: + properties: + kinds: + description: Kinds are the session kinds this policy applies + to. + items: + type: string + nullable: true + type: array + modes: + description: Modes is a list of permitted participant modes + for this policy. + items: + type: string + nullable: true + type: array + name: + description: Name is the name of the policy. + type: string + roles: + description: Roles is a list of roles that you can join + the session of. + items: + type: string + nullable: true + type: array + type: object + nullable: true + type: array + kubernetes_groups: + description: KubeGroups is a list of kubernetes groups + items: + type: string + nullable: true + type: array + kubernetes_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: KubernetesLabels is a map of kubernetes cluster labels + used for RBAC. + type: object + kubernetes_labels_expression: + description: KubernetesLabelsExpression is a predicate expression + used to allow/deny access to kubernetes clusters. + type: string + kubernetes_resources: + description: KubernetesResources is the Kubernetes Resources this + Role grants access to. + items: + properties: + kind: + description: Kind specifies the Kubernetes Resource type. + At the moment only "pod" is supported. + type: string + name: + description: Name is the resource name. It supports wildcards. + type: string + namespace: + description: Namespace is the resource namespace. It supports + wildcards. + type: string + verbs: + description: Verbs are the allowed Kubernetes verbs for + the following resource. + items: + type: string + nullable: true + type: array + type: object + type: array + kubernetes_users: + description: KubeUsers is an optional kubernetes users to impersonate + items: + type: string + nullable: true + type: array + logins: + description: Logins is a list of *nix system logins. + items: + type: string + nullable: true + type: array + node_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: NodeLabels is a map of node labels (used to dynamically + grant access to nodes). + type: object + node_labels_expression: + description: NodeLabelsExpression is a predicate expression used + to allow/deny access to SSH nodes. + type: string + request: + nullable: true + properties: + annotations: + additionalProperties: + items: + type: string + type: array + description: Annotations is a collection of annotations to + be programmatically appended to pending access requests + at the time of their creation. These annotations serve as + a mechanism to propagate extra information to plugins. Since + these annotations support variable interpolation syntax, + they also offer a mechanism for forwarding claims from an + external identity provider, to a plugin via `{{external.trait_name}}` + style substitutions. + type: object + claims_to_roles: + description: ClaimsToRoles specifies a mapping from claims + (traits) to teleport roles. + items: + properties: + claim: + description: Claim is a claim name. + type: string + roles: + description: Roles is a list of static teleport roles + to match. + items: + type: string + nullable: true + type: array + value: + description: Value is a claim value to match. + type: string + type: object + type: array + max_duration: + description: MaxDuration is the amount of time the access + will be granted for. If this is zero, the default duration + is used. + format: duration + type: string + roles: + description: Roles is the name of roles which will match the + request rule. + items: + type: string + nullable: true + type: array + search_as_roles: + description: SearchAsRoles is a list of extra roles which + should apply to a user while they are searching for resources + as part of a Resource Access Request, and defines the underlying + roles which will be requested as part of any Resource Access + Request. + items: + type: string + nullable: true + type: array + suggested_reviewers: + description: SuggestedReviewers is a list of reviewer suggestions. These + can be teleport usernames, but that is not a requirement. + items: + type: string + nullable: true + type: array + thresholds: + description: Thresholds is a list of thresholds, one of which + must be met in order for reviews to trigger a state-transition. If + no thresholds are provided, a default threshold of 1 for + approval and denial is used. + items: + properties: + approve: + description: Approve is the number of matching approvals + needed for state-transition. + format: int32 + type: integer + deny: + description: Deny is the number of denials needed for + state-transition. + format: int32 + type: integer + filter: + description: Filter is an optional predicate used to + determine which reviews count toward this threshold. + type: string + name: + description: Name is the optional human-readable name + of the threshold. + type: string + type: object + type: array + type: object + require_session_join: + description: RequireSessionJoin specifies policies for required + users to start a session. + items: + properties: + count: + description: Count is the amount of people that need to + be matched for this policy to be fulfilled. + format: int32 + type: integer + filter: + description: Filter is a predicate that determines what + users count towards this policy. + type: string + kinds: + description: Kinds are the session kinds this policy applies + to. + items: + type: string + nullable: true + type: array + modes: + description: Modes is the list of modes that may be used + to fulfill this policy. + items: + type: string + nullable: true + type: array + name: + description: Name is the name of the policy. + type: string + on_leave: + description: OnLeave is the behaviour that's used when the + policy is no longer fulfilled for a live session. + type: string + type: object + nullable: true + type: array + review_requests: + description: ReviewRequests defines conditions for submitting + access reviews. + nullable: true + properties: + claims_to_roles: + description: ClaimsToRoles specifies a mapping from claims + (traits) to teleport roles. + items: + properties: + claim: + description: Claim is a claim name. + type: string + roles: + description: Roles is a list of static teleport roles + to match. + items: + type: string + nullable: true + type: array + value: + description: Value is a claim value to match. + type: string + type: object + type: array + preview_as_roles: + description: PreviewAsRoles is a list of extra roles which + should apply to a reviewer while they are viewing a Resource + Access Request for the purposes of viewing details such + as the hostname and labels of requested resources. + items: + type: string + nullable: true + type: array + roles: + description: Roles is the name of roles which may be reviewed. + items: + type: string + nullable: true + type: array + where: + description: Where is an optional predicate which further + limits which requests are reviewable. + type: string + type: object + rules: + description: Rules is a list of rules and their access levels. + Rules are a high level construct used for access control. + items: + properties: + actions: + description: Actions specifies optional actions taken when + this rule matches + items: + type: string + nullable: true + type: array + resources: + description: Resources is a list of resources + items: + type: string + nullable: true + type: array + verbs: + description: Verbs is a list of verbs + items: + type: string + nullable: true + type: array + where: + description: Where specifies optional advanced matcher + type: string + type: object + type: array + windows_desktop_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: WindowsDesktopLabels are used in the RBAC system + to allow/deny access to Windows desktops. + type: object + windows_desktop_labels_expression: + description: WindowsDesktopLabelsExpression is a predicate expression + used to allow/deny access to Windows desktops. + type: string + windows_desktop_logins: + description: WindowsDesktopLogins is a list of desktop login names + allowed/denied for Windows desktops. + items: + type: string + nullable: true + type: array + type: object + deny: + description: Deny is the set of conditions evaluated to deny access. + Deny takes priority over allow. + properties: + app_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: AppLabels is a map of labels used as part of the + RBAC system. + type: object + app_labels_expression: + description: AppLabelsExpression is a predicate expression used + to allow/deny access to Apps. + type: string + aws_role_arns: + description: AWSRoleARNs is a list of AWS role ARNs this role + is allowed to assume. + items: + type: string + nullable: true + type: array + azure_identities: + description: AzureIdentities is a list of Azure identities this + role is allowed to assume. + items: + type: string + nullable: true + type: array + cluster_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: ClusterLabels is a map of node labels (used to dynamically + grant access to clusters). + type: object + cluster_labels_expression: + description: ClusterLabelsExpression is a predicate expression + used to allow/deny access to remote Teleport clusters. + type: string + db_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: DatabaseLabels are used in RBAC system to allow/deny + access to databases. + type: object + db_labels_expression: + description: DatabaseLabelsExpression is a predicate expression + used to allow/deny access to Databases. + type: string + db_names: + description: DatabaseNames is a list of database names this role + is allowed to connect to. + items: + type: string + nullable: true + type: array + db_roles: + description: DatabaseRoles is a list of databases roles for automatic + user creation. + items: + type: string + nullable: true + type: array + db_service_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: DatabaseServiceLabels are used in RBAC system to + allow/deny access to Database Services. + type: object + db_service_labels_expression: + description: DatabaseServiceLabelsExpression is a predicate expression + used to allow/deny access to Database Services. + type: string + db_users: + description: DatabaseUsers is a list of databases users this role + is allowed to connect as. + items: + type: string + nullable: true + type: array + desktop_groups: + description: DesktopGroups is a list of groups for created desktop + users to be added to + items: + type: string + nullable: true + type: array + gcp_service_accounts: + description: GCPServiceAccounts is a list of GCP service accounts + this role is allowed to assume. + items: + type: string + nullable: true + type: array + group_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: GroupLabels is a map of labels used as part of the + RBAC system. + type: object + group_labels_expression: + description: GroupLabelsExpression is a predicate expression used + to allow/deny access to user groups. + type: string + host_groups: + description: HostGroups is a list of groups for created users + to be added to + items: + type: string + nullable: true + type: array + host_sudoers: + description: HostSudoers is a list of entries to include in a + users sudoer file + items: + type: string + nullable: true + type: array + impersonate: + description: Impersonate specifies what users and roles this role + is allowed to impersonate by issuing certificates or other possible + means. + nullable: true + properties: + roles: + description: Roles is a list of resources this role is allowed + to impersonate + items: + type: string + nullable: true + type: array + users: + description: Users is a list of resources this role is allowed + to impersonate, could be an empty list or a Wildcard pattern + items: + type: string + nullable: true + type: array + where: + description: Where specifies optional advanced matcher + type: string + type: object + join_sessions: + description: JoinSessions specifies policies to allow users to + join other sessions. + items: + properties: + kinds: + description: Kinds are the session kinds this policy applies + to. + items: + type: string + nullable: true + type: array + modes: + description: Modes is a list of permitted participant modes + for this policy. + items: + type: string + nullable: true + type: array + name: + description: Name is the name of the policy. + type: string + roles: + description: Roles is a list of roles that you can join + the session of. + items: + type: string + nullable: true + type: array + type: object + nullable: true + type: array + kubernetes_groups: + description: KubeGroups is a list of kubernetes groups + items: + type: string + nullable: true + type: array + kubernetes_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: KubernetesLabels is a map of kubernetes cluster labels + used for RBAC. + type: object + kubernetes_labels_expression: + description: KubernetesLabelsExpression is a predicate expression + used to allow/deny access to kubernetes clusters. + type: string + kubernetes_resources: + description: KubernetesResources is the Kubernetes Resources this + Role grants access to. + items: + properties: + kind: + description: Kind specifies the Kubernetes Resource type. + At the moment only "pod" is supported. + type: string + name: + description: Name is the resource name. It supports wildcards. + type: string + namespace: + description: Namespace is the resource namespace. It supports + wildcards. + type: string + verbs: + description: Verbs are the allowed Kubernetes verbs for + the following resource. + items: + type: string + nullable: true + type: array + type: object + type: array + kubernetes_users: + description: KubeUsers is an optional kubernetes users to impersonate + items: + type: string + nullable: true + type: array + logins: + description: Logins is a list of *nix system logins. + items: + type: string + nullable: true + type: array + node_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: NodeLabels is a map of node labels (used to dynamically + grant access to nodes). + type: object + node_labels_expression: + description: NodeLabelsExpression is a predicate expression used + to allow/deny access to SSH nodes. + type: string + request: + nullable: true + properties: + annotations: + additionalProperties: + items: + type: string + type: array + description: Annotations is a collection of annotations to + be programmatically appended to pending access requests + at the time of their creation. These annotations serve as + a mechanism to propagate extra information to plugins. Since + these annotations support variable interpolation syntax, + they also offer a mechanism for forwarding claims from an + external identity provider, to a plugin via `{{external.trait_name}}` + style substitutions. + type: object + claims_to_roles: + description: ClaimsToRoles specifies a mapping from claims + (traits) to teleport roles. + items: + properties: + claim: + description: Claim is a claim name. + type: string + roles: + description: Roles is a list of static teleport roles + to match. + items: + type: string + nullable: true + type: array + value: + description: Value is a claim value to match. + type: string + type: object + type: array + max_duration: + description: MaxDuration is the amount of time the access + will be granted for. If this is zero, the default duration + is used. + format: duration + type: string + roles: + description: Roles is the name of roles which will match the + request rule. + items: + type: string + nullable: true + type: array + search_as_roles: + description: SearchAsRoles is a list of extra roles which + should apply to a user while they are searching for resources + as part of a Resource Access Request, and defines the underlying + roles which will be requested as part of any Resource Access + Request. + items: + type: string + nullable: true + type: array + suggested_reviewers: + description: SuggestedReviewers is a list of reviewer suggestions. These + can be teleport usernames, but that is not a requirement. + items: + type: string + nullable: true + type: array + thresholds: + description: Thresholds is a list of thresholds, one of which + must be met in order for reviews to trigger a state-transition. If + no thresholds are provided, a default threshold of 1 for + approval and denial is used. + items: + properties: + approve: + description: Approve is the number of matching approvals + needed for state-transition. + format: int32 + type: integer + deny: + description: Deny is the number of denials needed for + state-transition. + format: int32 + type: integer + filter: + description: Filter is an optional predicate used to + determine which reviews count toward this threshold. + type: string + name: + description: Name is the optional human-readable name + of the threshold. + type: string + type: object + type: array + type: object + require_session_join: + description: RequireSessionJoin specifies policies for required + users to start a session. + items: + properties: + count: + description: Count is the amount of people that need to + be matched for this policy to be fulfilled. + format: int32 + type: integer + filter: + description: Filter is a predicate that determines what + users count towards this policy. + type: string + kinds: + description: Kinds are the session kinds this policy applies + to. + items: + type: string + nullable: true + type: array + modes: + description: Modes is the list of modes that may be used + to fulfill this policy. + items: + type: string + nullable: true + type: array + name: + description: Name is the name of the policy. + type: string + on_leave: + description: OnLeave is the behaviour that's used when the + policy is no longer fulfilled for a live session. + type: string + type: object + nullable: true + type: array + review_requests: + description: ReviewRequests defines conditions for submitting + access reviews. + nullable: true + properties: + claims_to_roles: + description: ClaimsToRoles specifies a mapping from claims + (traits) to teleport roles. + items: + properties: + claim: + description: Claim is a claim name. + type: string + roles: + description: Roles is a list of static teleport roles + to match. + items: + type: string + nullable: true + type: array + value: + description: Value is a claim value to match. + type: string + type: object + type: array + preview_as_roles: + description: PreviewAsRoles is a list of extra roles which + should apply to a reviewer while they are viewing a Resource + Access Request for the purposes of viewing details such + as the hostname and labels of requested resources. + items: + type: string + nullable: true + type: array + roles: + description: Roles is the name of roles which may be reviewed. + items: + type: string + nullable: true + type: array + where: + description: Where is an optional predicate which further + limits which requests are reviewable. + type: string + type: object + rules: + description: Rules is a list of rules and their access levels. + Rules are a high level construct used for access control. + items: + properties: + actions: + description: Actions specifies optional actions taken when + this rule matches + items: + type: string + nullable: true + type: array + resources: + description: Resources is a list of resources + items: + type: string + nullable: true + type: array + verbs: + description: Verbs is a list of verbs + items: + type: string + nullable: true + type: array + where: + description: Where specifies optional advanced matcher + type: string + type: object + type: array + windows_desktop_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: WindowsDesktopLabels are used in the RBAC system + to allow/deny access to Windows desktops. + type: object + windows_desktop_labels_expression: + description: WindowsDesktopLabelsExpression is a predicate expression + used to allow/deny access to Windows desktops. + type: string + windows_desktop_logins: + description: WindowsDesktopLogins is a list of desktop login names + allowed/denied for Windows desktops. + items: + type: string + nullable: true + type: array + type: object + options: + description: Options is for OpenSSH options like agent forwarding. + properties: + cert_extensions: + description: CertExtensions specifies the key/values + items: + properties: + mode: + description: Mode is the type of extension to be used -- + currently critical-option is not supported + x-kubernetes-int-or-string: true + name: + description: Name specifies the key to be used in the cert + extension. + type: string + type: + description: Type represents the certificate type being + extended, only ssh is supported at this time. + x-kubernetes-int-or-string: true + value: + description: Value specifies the value to be used in the + cert extension. + type: string + type: object + nullable: true + type: array + cert_format: + description: CertificateFormat defines the format of the user + certificate to allow compatibility with older versions of OpenSSH. + type: string + client_idle_timeout: + description: ClientIdleTimeout sets disconnect clients on idle + timeout behavior, if set to 0 means do not disconnect, otherwise + is set to the idle duration. + format: duration + type: string + create_db_user: + description: CreateDatabaseUser enabled automatic database user + creation. + type: boolean + create_desktop_user: + description: CreateDesktopUser allows users to be automatically + created on a Windows desktop + type: boolean + create_host_user: + description: CreateHostUser allows users to be automatically created + on a host + type: boolean + create_host_user_mode: + description: CreateHostUserMode allows users to be automatically + created on a host when not set to off + x-kubernetes-int-or-string: true + desktop_clipboard: + description: DesktopClipboard indicates whether clipboard sharing + is allowed between the user's workstation and the remote desktop. + It defaults to true unless explicitly set to false. + type: boolean + desktop_directory_sharing: + description: DesktopDirectorySharing indicates whether directory + sharing is allowed between the user's workstation and the remote + desktop. It defaults to false unless explicitly set to true. + type: boolean + device_trust_mode: + description: DeviceTrustMode is the device authorization mode + used for the resources associated with the role. See DeviceTrust.Mode. + Reserved for future use, not yet used by Teleport. + type: string + disconnect_expired_cert: + description: DisconnectExpiredCert sets disconnect clients on + expired certificates. + type: boolean + enhanced_recording: + description: BPF defines what events to record for the BPF-based + session recorder. + items: + type: string + nullable: true + type: array + forward_agent: + description: ForwardAgent is SSH agent forwarding. + type: boolean + idp: + description: IDP is a set of options related to accessing IdPs + within Teleport. Requires Teleport Enterprise. + nullable: true + properties: + saml: + description: SAML are options related to the Teleport SAML + IdP. + nullable: true + properties: + enabled: + description: Enabled is set to true if this option allows + access to the Teleport SAML IdP. + type: boolean + type: object + type: object + lock: + description: Lock specifies the locking mode (strict|best_effort) + to be applied with the role. + type: string + max_connections: + description: MaxConnections defines the maximum number of concurrent + connections a user may hold. + format: int64 + type: integer + max_kubernetes_connections: + description: MaxKubernetesConnections defines the maximum number + of concurrent Kubernetes sessions a user may hold. + format: int64 + type: integer + max_session_ttl: + description: MaxSessionTTL defines how long a SSH session can + last for. + format: duration + type: string + max_sessions: + description: MaxSessions defines the maximum number of concurrent + sessions per connection. + format: int64 + type: integer + permit_x11_forwarding: + description: PermitX11Forwarding authorizes use of X11 forwarding. + type: boolean + pin_source_ip: + description: PinSourceIP forces the same client IP for certificate + generation and usage + type: boolean + port_forwarding: + description: PortForwarding defines if the certificate will have + "permit-port-forwarding" in the certificate. PortForwarding + is "yes" if not set, that's why this is a pointer + type: boolean + record_session: + description: RecordDesktopSession indicates whether desktop access + sessions should be recorded. It defaults to true unless explicitly + set to false. + nullable: true + properties: + default: + description: Default indicates the default value for the services. + type: string + desktop: + description: Desktop indicates whether desktop sessions should + be recorded. It defaults to true unless explicitly set to + false. + type: boolean + ssh: + description: SSH indicates the session mode used on SSH sessions. + type: string + type: object + request_access: + description: RequestAccess defines the access request strategy + (optional|note|always) where optional is the default. + type: string + request_prompt: + description: RequestPrompt is an optional message which tells + users what they aught to request. + type: string + require_session_mfa: + description: RequireMFAType is the type of MFA requirement enforced + for this user. + x-kubernetes-int-or-string: true + ssh_file_copy: + description: SSHFileCopy indicates whether remote file operations + via SCP or SFTP are allowed over an SSH session. It defaults + to true unless explicitly set to false. + type: boolean + type: object + type: object + status: + description: Status defines the observed state of the Teleport resource + properties: + conditions: + description: Conditions represent the latest available observations + of an object's state + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + teleportResourceID: + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_rolesv7.yaml b/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_rolesv7.yaml new file mode 100644 index 0000000000000..7900d32138175 --- /dev/null +++ b/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_rolesv7.yaml @@ -0,0 +1,1217 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + name: teleportrolesv7.resources.teleport.dev +spec: + group: resources.teleport.dev + names: + kind: TeleportRoleV7 + listKind: TeleportRoleV7List + plural: teleportrolesv7 + shortNames: + - rolev7 + - rolesv7 + singular: teleportrolev7 + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: RoleV7 is the Schema for the rolesv7 API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Role resource definition v7 from Teleport + properties: + allow: + description: Allow is the set of conditions evaluated to grant access. + properties: + app_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: AppLabels is a map of labels used as part of the + RBAC system. + type: object + app_labels_expression: + description: AppLabelsExpression is a predicate expression used + to allow/deny access to Apps. + type: string + aws_role_arns: + description: AWSRoleARNs is a list of AWS role ARNs this role + is allowed to assume. + items: + type: string + nullable: true + type: array + azure_identities: + description: AzureIdentities is a list of Azure identities this + role is allowed to assume. + items: + type: string + nullable: true + type: array + cluster_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: ClusterLabels is a map of node labels (used to dynamically + grant access to clusters). + type: object + cluster_labels_expression: + description: ClusterLabelsExpression is a predicate expression + used to allow/deny access to remote Teleport clusters. + type: string + db_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: DatabaseLabels are used in RBAC system to allow/deny + access to databases. + type: object + db_labels_expression: + description: DatabaseLabelsExpression is a predicate expression + used to allow/deny access to Databases. + type: string + db_names: + description: DatabaseNames is a list of database names this role + is allowed to connect to. + items: + type: string + nullable: true + type: array + db_roles: + description: DatabaseRoles is a list of databases roles for automatic + user creation. + items: + type: string + nullable: true + type: array + db_service_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: DatabaseServiceLabels are used in RBAC system to + allow/deny access to Database Services. + type: object + db_service_labels_expression: + description: DatabaseServiceLabelsExpression is a predicate expression + used to allow/deny access to Database Services. + type: string + db_users: + description: DatabaseUsers is a list of databases users this role + is allowed to connect as. + items: + type: string + nullable: true + type: array + desktop_groups: + description: DesktopGroups is a list of groups for created desktop + users to be added to + items: + type: string + nullable: true + type: array + gcp_service_accounts: + description: GCPServiceAccounts is a list of GCP service accounts + this role is allowed to assume. + items: + type: string + nullable: true + type: array + group_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: GroupLabels is a map of labels used as part of the + RBAC system. + type: object + group_labels_expression: + description: GroupLabelsExpression is a predicate expression used + to allow/deny access to user groups. + type: string + host_groups: + description: HostGroups is a list of groups for created users + to be added to + items: + type: string + nullable: true + type: array + host_sudoers: + description: HostSudoers is a list of entries to include in a + users sudoer file + items: + type: string + nullable: true + type: array + impersonate: + description: Impersonate specifies what users and roles this role + is allowed to impersonate by issuing certificates or other possible + means. + nullable: true + properties: + roles: + description: Roles is a list of resources this role is allowed + to impersonate + items: + type: string + nullable: true + type: array + users: + description: Users is a list of resources this role is allowed + to impersonate, could be an empty list or a Wildcard pattern + items: + type: string + nullable: true + type: array + where: + description: Where specifies optional advanced matcher + type: string + type: object + join_sessions: + description: JoinSessions specifies policies to allow users to + join other sessions. + items: + properties: + kinds: + description: Kinds are the session kinds this policy applies + to. + items: + type: string + nullable: true + type: array + modes: + description: Modes is a list of permitted participant modes + for this policy. + items: + type: string + nullable: true + type: array + name: + description: Name is the name of the policy. + type: string + roles: + description: Roles is a list of roles that you can join + the session of. + items: + type: string + nullable: true + type: array + type: object + nullable: true + type: array + kubernetes_groups: + description: KubeGroups is a list of kubernetes groups + items: + type: string + nullable: true + type: array + kubernetes_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: KubernetesLabels is a map of kubernetes cluster labels + used for RBAC. + type: object + kubernetes_labels_expression: + description: KubernetesLabelsExpression is a predicate expression + used to allow/deny access to kubernetes clusters. + type: string + kubernetes_resources: + description: KubernetesResources is the Kubernetes Resources this + Role grants access to. + items: + properties: + kind: + description: Kind specifies the Kubernetes Resource type. + At the moment only "pod" is supported. + type: string + name: + description: Name is the resource name. It supports wildcards. + type: string + namespace: + description: Namespace is the resource namespace. It supports + wildcards. + type: string + verbs: + description: Verbs are the allowed Kubernetes verbs for + the following resource. + items: + type: string + nullable: true + type: array + type: object + type: array + kubernetes_users: + description: KubeUsers is an optional kubernetes users to impersonate + items: + type: string + nullable: true + type: array + logins: + description: Logins is a list of *nix system logins. + items: + type: string + nullable: true + type: array + node_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: NodeLabels is a map of node labels (used to dynamically + grant access to nodes). + type: object + node_labels_expression: + description: NodeLabelsExpression is a predicate expression used + to allow/deny access to SSH nodes. + type: string + request: + nullable: true + properties: + annotations: + additionalProperties: + items: + type: string + type: array + description: Annotations is a collection of annotations to + be programmatically appended to pending access requests + at the time of their creation. These annotations serve as + a mechanism to propagate extra information to plugins. Since + these annotations support variable interpolation syntax, + they also offer a mechanism for forwarding claims from an + external identity provider, to a plugin via `{{external.trait_name}}` + style substitutions. + type: object + claims_to_roles: + description: ClaimsToRoles specifies a mapping from claims + (traits) to teleport roles. + items: + properties: + claim: + description: Claim is a claim name. + type: string + roles: + description: Roles is a list of static teleport roles + to match. + items: + type: string + nullable: true + type: array + value: + description: Value is a claim value to match. + type: string + type: object + type: array + max_duration: + description: MaxDuration is the amount of time the access + will be granted for. If this is zero, the default duration + is used. + format: duration + type: string + roles: + description: Roles is the name of roles which will match the + request rule. + items: + type: string + nullable: true + type: array + search_as_roles: + description: SearchAsRoles is a list of extra roles which + should apply to a user while they are searching for resources + as part of a Resource Access Request, and defines the underlying + roles which will be requested as part of any Resource Access + Request. + items: + type: string + nullable: true + type: array + suggested_reviewers: + description: SuggestedReviewers is a list of reviewer suggestions. These + can be teleport usernames, but that is not a requirement. + items: + type: string + nullable: true + type: array + thresholds: + description: Thresholds is a list of thresholds, one of which + must be met in order for reviews to trigger a state-transition. If + no thresholds are provided, a default threshold of 1 for + approval and denial is used. + items: + properties: + approve: + description: Approve is the number of matching approvals + needed for state-transition. + format: int32 + type: integer + deny: + description: Deny is the number of denials needed for + state-transition. + format: int32 + type: integer + filter: + description: Filter is an optional predicate used to + determine which reviews count toward this threshold. + type: string + name: + description: Name is the optional human-readable name + of the threshold. + type: string + type: object + type: array + type: object + require_session_join: + description: RequireSessionJoin specifies policies for required + users to start a session. + items: + properties: + count: + description: Count is the amount of people that need to + be matched for this policy to be fulfilled. + format: int32 + type: integer + filter: + description: Filter is a predicate that determines what + users count towards this policy. + type: string + kinds: + description: Kinds are the session kinds this policy applies + to. + items: + type: string + nullable: true + type: array + modes: + description: Modes is the list of modes that may be used + to fulfill this policy. + items: + type: string + nullable: true + type: array + name: + description: Name is the name of the policy. + type: string + on_leave: + description: OnLeave is the behaviour that's used when the + policy is no longer fulfilled for a live session. + type: string + type: object + nullable: true + type: array + review_requests: + description: ReviewRequests defines conditions for submitting + access reviews. + nullable: true + properties: + claims_to_roles: + description: ClaimsToRoles specifies a mapping from claims + (traits) to teleport roles. + items: + properties: + claim: + description: Claim is a claim name. + type: string + roles: + description: Roles is a list of static teleport roles + to match. + items: + type: string + nullable: true + type: array + value: + description: Value is a claim value to match. + type: string + type: object + type: array + preview_as_roles: + description: PreviewAsRoles is a list of extra roles which + should apply to a reviewer while they are viewing a Resource + Access Request for the purposes of viewing details such + as the hostname and labels of requested resources. + items: + type: string + nullable: true + type: array + roles: + description: Roles is the name of roles which may be reviewed. + items: + type: string + nullable: true + type: array + where: + description: Where is an optional predicate which further + limits which requests are reviewable. + type: string + type: object + rules: + description: Rules is a list of rules and their access levels. + Rules are a high level construct used for access control. + items: + properties: + actions: + description: Actions specifies optional actions taken when + this rule matches + items: + type: string + nullable: true + type: array + resources: + description: Resources is a list of resources + items: + type: string + nullable: true + type: array + verbs: + description: Verbs is a list of verbs + items: + type: string + nullable: true + type: array + where: + description: Where specifies optional advanced matcher + type: string + type: object + type: array + windows_desktop_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: WindowsDesktopLabels are used in the RBAC system + to allow/deny access to Windows desktops. + type: object + windows_desktop_labels_expression: + description: WindowsDesktopLabelsExpression is a predicate expression + used to allow/deny access to Windows desktops. + type: string + windows_desktop_logins: + description: WindowsDesktopLogins is a list of desktop login names + allowed/denied for Windows desktops. + items: + type: string + nullable: true + type: array + type: object + deny: + description: Deny is the set of conditions evaluated to deny access. + Deny takes priority over allow. + properties: + app_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: AppLabels is a map of labels used as part of the + RBAC system. + type: object + app_labels_expression: + description: AppLabelsExpression is a predicate expression used + to allow/deny access to Apps. + type: string + aws_role_arns: + description: AWSRoleARNs is a list of AWS role ARNs this role + is allowed to assume. + items: + type: string + nullable: true + type: array + azure_identities: + description: AzureIdentities is a list of Azure identities this + role is allowed to assume. + items: + type: string + nullable: true + type: array + cluster_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: ClusterLabels is a map of node labels (used to dynamically + grant access to clusters). + type: object + cluster_labels_expression: + description: ClusterLabelsExpression is a predicate expression + used to allow/deny access to remote Teleport clusters. + type: string + db_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: DatabaseLabels are used in RBAC system to allow/deny + access to databases. + type: object + db_labels_expression: + description: DatabaseLabelsExpression is a predicate expression + used to allow/deny access to Databases. + type: string + db_names: + description: DatabaseNames is a list of database names this role + is allowed to connect to. + items: + type: string + nullable: true + type: array + db_roles: + description: DatabaseRoles is a list of databases roles for automatic + user creation. + items: + type: string + nullable: true + type: array + db_service_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: DatabaseServiceLabels are used in RBAC system to + allow/deny access to Database Services. + type: object + db_service_labels_expression: + description: DatabaseServiceLabelsExpression is a predicate expression + used to allow/deny access to Database Services. + type: string + db_users: + description: DatabaseUsers is a list of databases users this role + is allowed to connect as. + items: + type: string + nullable: true + type: array + desktop_groups: + description: DesktopGroups is a list of groups for created desktop + users to be added to + items: + type: string + nullable: true + type: array + gcp_service_accounts: + description: GCPServiceAccounts is a list of GCP service accounts + this role is allowed to assume. + items: + type: string + nullable: true + type: array + group_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: GroupLabels is a map of labels used as part of the + RBAC system. + type: object + group_labels_expression: + description: GroupLabelsExpression is a predicate expression used + to allow/deny access to user groups. + type: string + host_groups: + description: HostGroups is a list of groups for created users + to be added to + items: + type: string + nullable: true + type: array + host_sudoers: + description: HostSudoers is a list of entries to include in a + users sudoer file + items: + type: string + nullable: true + type: array + impersonate: + description: Impersonate specifies what users and roles this role + is allowed to impersonate by issuing certificates or other possible + means. + nullable: true + properties: + roles: + description: Roles is a list of resources this role is allowed + to impersonate + items: + type: string + nullable: true + type: array + users: + description: Users is a list of resources this role is allowed + to impersonate, could be an empty list or a Wildcard pattern + items: + type: string + nullable: true + type: array + where: + description: Where specifies optional advanced matcher + type: string + type: object + join_sessions: + description: JoinSessions specifies policies to allow users to + join other sessions. + items: + properties: + kinds: + description: Kinds are the session kinds this policy applies + to. + items: + type: string + nullable: true + type: array + modes: + description: Modes is a list of permitted participant modes + for this policy. + items: + type: string + nullable: true + type: array + name: + description: Name is the name of the policy. + type: string + roles: + description: Roles is a list of roles that you can join + the session of. + items: + type: string + nullable: true + type: array + type: object + nullable: true + type: array + kubernetes_groups: + description: KubeGroups is a list of kubernetes groups + items: + type: string + nullable: true + type: array + kubernetes_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: KubernetesLabels is a map of kubernetes cluster labels + used for RBAC. + type: object + kubernetes_labels_expression: + description: KubernetesLabelsExpression is a predicate expression + used to allow/deny access to kubernetes clusters. + type: string + kubernetes_resources: + description: KubernetesResources is the Kubernetes Resources this + Role grants access to. + items: + properties: + kind: + description: Kind specifies the Kubernetes Resource type. + At the moment only "pod" is supported. + type: string + name: + description: Name is the resource name. It supports wildcards. + type: string + namespace: + description: Namespace is the resource namespace. It supports + wildcards. + type: string + verbs: + description: Verbs are the allowed Kubernetes verbs for + the following resource. + items: + type: string + nullable: true + type: array + type: object + type: array + kubernetes_users: + description: KubeUsers is an optional kubernetes users to impersonate + items: + type: string + nullable: true + type: array + logins: + description: Logins is a list of *nix system logins. + items: + type: string + nullable: true + type: array + node_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: NodeLabels is a map of node labels (used to dynamically + grant access to nodes). + type: object + node_labels_expression: + description: NodeLabelsExpression is a predicate expression used + to allow/deny access to SSH nodes. + type: string + request: + nullable: true + properties: + annotations: + additionalProperties: + items: + type: string + type: array + description: Annotations is a collection of annotations to + be programmatically appended to pending access requests + at the time of their creation. These annotations serve as + a mechanism to propagate extra information to plugins. Since + these annotations support variable interpolation syntax, + they also offer a mechanism for forwarding claims from an + external identity provider, to a plugin via `{{external.trait_name}}` + style substitutions. + type: object + claims_to_roles: + description: ClaimsToRoles specifies a mapping from claims + (traits) to teleport roles. + items: + properties: + claim: + description: Claim is a claim name. + type: string + roles: + description: Roles is a list of static teleport roles + to match. + items: + type: string + nullable: true + type: array + value: + description: Value is a claim value to match. + type: string + type: object + type: array + max_duration: + description: MaxDuration is the amount of time the access + will be granted for. If this is zero, the default duration + is used. + format: duration + type: string + roles: + description: Roles is the name of roles which will match the + request rule. + items: + type: string + nullable: true + type: array + search_as_roles: + description: SearchAsRoles is a list of extra roles which + should apply to a user while they are searching for resources + as part of a Resource Access Request, and defines the underlying + roles which will be requested as part of any Resource Access + Request. + items: + type: string + nullable: true + type: array + suggested_reviewers: + description: SuggestedReviewers is a list of reviewer suggestions. These + can be teleport usernames, but that is not a requirement. + items: + type: string + nullable: true + type: array + thresholds: + description: Thresholds is a list of thresholds, one of which + must be met in order for reviews to trigger a state-transition. If + no thresholds are provided, a default threshold of 1 for + approval and denial is used. + items: + properties: + approve: + description: Approve is the number of matching approvals + needed for state-transition. + format: int32 + type: integer + deny: + description: Deny is the number of denials needed for + state-transition. + format: int32 + type: integer + filter: + description: Filter is an optional predicate used to + determine which reviews count toward this threshold. + type: string + name: + description: Name is the optional human-readable name + of the threshold. + type: string + type: object + type: array + type: object + require_session_join: + description: RequireSessionJoin specifies policies for required + users to start a session. + items: + properties: + count: + description: Count is the amount of people that need to + be matched for this policy to be fulfilled. + format: int32 + type: integer + filter: + description: Filter is a predicate that determines what + users count towards this policy. + type: string + kinds: + description: Kinds are the session kinds this policy applies + to. + items: + type: string + nullable: true + type: array + modes: + description: Modes is the list of modes that may be used + to fulfill this policy. + items: + type: string + nullable: true + type: array + name: + description: Name is the name of the policy. + type: string + on_leave: + description: OnLeave is the behaviour that's used when the + policy is no longer fulfilled for a live session. + type: string + type: object + nullable: true + type: array + review_requests: + description: ReviewRequests defines conditions for submitting + access reviews. + nullable: true + properties: + claims_to_roles: + description: ClaimsToRoles specifies a mapping from claims + (traits) to teleport roles. + items: + properties: + claim: + description: Claim is a claim name. + type: string + roles: + description: Roles is a list of static teleport roles + to match. + items: + type: string + nullable: true + type: array + value: + description: Value is a claim value to match. + type: string + type: object + type: array + preview_as_roles: + description: PreviewAsRoles is a list of extra roles which + should apply to a reviewer while they are viewing a Resource + Access Request for the purposes of viewing details such + as the hostname and labels of requested resources. + items: + type: string + nullable: true + type: array + roles: + description: Roles is the name of roles which may be reviewed. + items: + type: string + nullable: true + type: array + where: + description: Where is an optional predicate which further + limits which requests are reviewable. + type: string + type: object + rules: + description: Rules is a list of rules and their access levels. + Rules are a high level construct used for access control. + items: + properties: + actions: + description: Actions specifies optional actions taken when + this rule matches + items: + type: string + nullable: true + type: array + resources: + description: Resources is a list of resources + items: + type: string + nullable: true + type: array + verbs: + description: Verbs is a list of verbs + items: + type: string + nullable: true + type: array + where: + description: Where specifies optional advanced matcher + type: string + type: object + type: array + windows_desktop_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: WindowsDesktopLabels are used in the RBAC system + to allow/deny access to Windows desktops. + type: object + windows_desktop_labels_expression: + description: WindowsDesktopLabelsExpression is a predicate expression + used to allow/deny access to Windows desktops. + type: string + windows_desktop_logins: + description: WindowsDesktopLogins is a list of desktop login names + allowed/denied for Windows desktops. + items: + type: string + nullable: true + type: array + type: object + options: + description: Options is for OpenSSH options like agent forwarding. + properties: + cert_extensions: + description: CertExtensions specifies the key/values + items: + properties: + mode: + description: Mode is the type of extension to be used -- + currently critical-option is not supported + x-kubernetes-int-or-string: true + name: + description: Name specifies the key to be used in the cert + extension. + type: string + type: + description: Type represents the certificate type being + extended, only ssh is supported at this time. + x-kubernetes-int-or-string: true + value: + description: Value specifies the value to be used in the + cert extension. + type: string + type: object + nullable: true + type: array + cert_format: + description: CertificateFormat defines the format of the user + certificate to allow compatibility with older versions of OpenSSH. + type: string + client_idle_timeout: + description: ClientIdleTimeout sets disconnect clients on idle + timeout behavior, if set to 0 means do not disconnect, otherwise + is set to the idle duration. + format: duration + type: string + create_db_user: + description: CreateDatabaseUser enabled automatic database user + creation. + type: boolean + create_desktop_user: + description: CreateDesktopUser allows users to be automatically + created on a Windows desktop + type: boolean + create_host_user: + description: CreateHostUser allows users to be automatically created + on a host + type: boolean + create_host_user_mode: + description: CreateHostUserMode allows users to be automatically + created on a host when not set to off + x-kubernetes-int-or-string: true + desktop_clipboard: + description: DesktopClipboard indicates whether clipboard sharing + is allowed between the user's workstation and the remote desktop. + It defaults to true unless explicitly set to false. + type: boolean + desktop_directory_sharing: + description: DesktopDirectorySharing indicates whether directory + sharing is allowed between the user's workstation and the remote + desktop. It defaults to false unless explicitly set to true. + type: boolean + device_trust_mode: + description: DeviceTrustMode is the device authorization mode + used for the resources associated with the role. See DeviceTrust.Mode. + Reserved for future use, not yet used by Teleport. + type: string + disconnect_expired_cert: + description: DisconnectExpiredCert sets disconnect clients on + expired certificates. + type: boolean + enhanced_recording: + description: BPF defines what events to record for the BPF-based + session recorder. + items: + type: string + nullable: true + type: array + forward_agent: + description: ForwardAgent is SSH agent forwarding. + type: boolean + idp: + description: IDP is a set of options related to accessing IdPs + within Teleport. Requires Teleport Enterprise. + nullable: true + properties: + saml: + description: SAML are options related to the Teleport SAML + IdP. + nullable: true + properties: + enabled: + description: Enabled is set to true if this option allows + access to the Teleport SAML IdP. + type: boolean + type: object + type: object + lock: + description: Lock specifies the locking mode (strict|best_effort) + to be applied with the role. + type: string + max_connections: + description: MaxConnections defines the maximum number of concurrent + connections a user may hold. + format: int64 + type: integer + max_kubernetes_connections: + description: MaxKubernetesConnections defines the maximum number + of concurrent Kubernetes sessions a user may hold. + format: int64 + type: integer + max_session_ttl: + description: MaxSessionTTL defines how long a SSH session can + last for. + format: duration + type: string + max_sessions: + description: MaxSessions defines the maximum number of concurrent + sessions per connection. + format: int64 + type: integer + permit_x11_forwarding: + description: PermitX11Forwarding authorizes use of X11 forwarding. + type: boolean + pin_source_ip: + description: PinSourceIP forces the same client IP for certificate + generation and usage + type: boolean + port_forwarding: + description: PortForwarding defines if the certificate will have + "permit-port-forwarding" in the certificate. PortForwarding + is "yes" if not set, that's why this is a pointer + type: boolean + record_session: + description: RecordDesktopSession indicates whether desktop access + sessions should be recorded. It defaults to true unless explicitly + set to false. + nullable: true + properties: + default: + description: Default indicates the default value for the services. + type: string + desktop: + description: Desktop indicates whether desktop sessions should + be recorded. It defaults to true unless explicitly set to + false. + type: boolean + ssh: + description: SSH indicates the session mode used on SSH sessions. + type: string + type: object + request_access: + description: RequestAccess defines the access request strategy + (optional|note|always) where optional is the default. + type: string + request_prompt: + description: RequestPrompt is an optional message which tells + users what they aught to request. + type: string + require_session_mfa: + description: RequireMFAType is the type of MFA requirement enforced + for this user. + x-kubernetes-int-or-string: true + ssh_file_copy: + description: SSHFileCopy indicates whether remote file operations + via SCP or SFTP are allowed over an SSH session. It defaults + to true unless explicitly set to false. + type: boolean + type: object + type: object + status: + description: Status defines the observed state of the Teleport resource + properties: + conditions: + description: Conditions represent the latest available observations + of an object's state + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + teleportResourceID: + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_samlconnectors.yaml b/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_samlconnectors.yaml index dc51a28419136..caaa7f3a5fb1e 100644 --- a/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_samlconnectors.yaml +++ b/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_samlconnectors.yaml @@ -120,8 +120,7 @@ spec: type: string type: object status: - description: TeleportSAMLConnectorStatus defines the observed state of - TeleportSAMLConnector + description: Status defines the observed state of the Teleport resource properties: conditions: description: Conditions represent the latest available observations diff --git a/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_users.yaml b/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_users.yaml index 01c405d0adeed..030a2b6f59bf8 100644 --- a/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_users.yaml +++ b/integrations/operator/crdgen/testdata/golden/resources.teleport.dev_users.yaml @@ -106,7 +106,7 @@ spec: type: array type: object status: - description: TeleportUserStatus defines the observed state of TeleportUser + description: Status defines the observed state of the Teleport resource properties: conditions: description: Conditions represent the latest available observations diff --git a/integrations/operator/main.go b/integrations/operator/main.go index 21a2506d5137e..7c81f8685ab20 100644 --- a/integrations/operator/main.go +++ b/integrations/operator/main.go @@ -24,44 +24,25 @@ import ( "os" "time" - apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - "k8s.io/apimachinery/pkg/runtime" - utilruntime "k8s.io/apimachinery/pkg/util/runtime" - clientgoscheme "k8s.io/client-go/kubernetes/scheme" // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) // to ensure that exec-entrypoint and run can make use of them. _ "k8s.io/client-go/plugin/pkg/client/auth" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/cache" + ctrlclient "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/healthz" "sigs.k8s.io/controller-runtime/pkg/log/zap" metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" - resourcesv1 "github.com/gravitational/teleport/integrations/operator/apis/resources/v1" - resourcesv2 "github.com/gravitational/teleport/integrations/operator/apis/resources/v2" - resourcesv3 "github.com/gravitational/teleport/integrations/operator/apis/resources/v3" - resourcesv5 "github.com/gravitational/teleport/integrations/operator/apis/resources/v5" "github.com/gravitational/teleport/integrations/operator/controllers/resources" "github.com/gravitational/teleport/integrations/operator/embeddedtbot" ) var ( - scheme = runtime.NewScheme() + scheme = resources.Scheme setupLog = ctrl.Log.WithName("setup") ) -func init() { - utilruntime.Must(clientgoscheme.AddToScheme(scheme)) - - utilruntime.Must(resourcesv5.AddToScheme(scheme)) - utilruntime.Must(resourcesv3.AddToScheme(scheme)) - utilruntime.Must(resourcesv2.AddToScheme(scheme)) - utilruntime.Must(resourcesv1.AddToScheme(scheme)) - //+kubebuilder:scaffold:scheme - - utilruntime.Must(apiextv1.AddToScheme(scheme)) -} - func main() { ctx := ctrl.SetupSignalHandler() @@ -116,9 +97,11 @@ func main() { config.namespace: {}, }, }, + // All our controllers now use unstructured objects, we need to cache them. + Client: ctrlclient.Options{Cache: &ctrlclient.CacheOptions{Unstructured: true}}, }) if err != nil { - setupLog.Error(err, "unable to start manager") + setupLog.Error(err, "unable to create manager") os.Exit(1) } @@ -127,78 +110,11 @@ func main() { os.Exit(1) } - if err = (&resources.RoleReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - TeleportClient: client, - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "TeleportRole") - os.Exit(1) - } - - if err = resources.NewUserReconciler(mgr.GetClient(), client). - SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "TeleportUser") - os.Exit(1) - } - - if err = resources.NewGithubConnectorReconciler(mgr.GetClient(), client). - SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "TeleportGithubConnector") - os.Exit(1) - } - - if pong.ServerFeatures.OIDC { - if err = resources.NewOIDCConnectorReconciler(mgr.GetClient(), client). - SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "TeleportOIDCConnector") - os.Exit(1) - } - } else { - setupLog.Info("OIDC connectors are only available in Teleport Enterprise edition. TeleportOIDCConnector resources won't be reconciled") - } - - if pong.ServerFeatures.SAML { - if err = resources.NewSAMLConnectorReconciler(mgr.GetClient(), client). - SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "TeleportSAMLConnector") - os.Exit(1) - } - } else { - setupLog.Info("SAML connectors are only available in Teleport Enterprise edition. TeleportSAMLConnector resources won't be reconciled") - } - - // Login Rules are enterprise-only but there is no specific feature flag for them. - if pong.ServerFeatures.OIDC || pong.ServerFeatures.SAML { - if err := resources.NewLoginRuleReconciler(mgr.GetClient(), client).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "TeleportLoginRule") - os.Exit(1) - } - } else { - setupLog.Info("Login Rules are only available in Teleport Enterprise edition. TeleportLoginRule resources won't be reconciled") - } - - if err = resources.NewProvisionTokenReconciler(mgr.GetClient(), client). - SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "TeleportProvisionToken") - os.Exit(1) - } - - if err = resources.NewOktaImportRuleReconciler(mgr.GetClient(), client). - SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "TeleportOktaImportRule") + if err = resources.SetupAllControllers(setupLog, mgr, client, pong.ServerFeatures); err != nil { + setupLog.Error(err, "failed to setup controllers") os.Exit(1) } - // AccessLists are enterprise-only but there is no specific feature-flag for them. - if pong.ServerFeatures.AdvancedAccessWorkflows { - if err = resources.NewAccessListReconciler(mgr.GetClient(), client). - SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "TeleportAccessList") - os.Exit(1) - } - } - //+kubebuilder:scaffold:builder if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { setupLog.Error(err, "unable to set up health check") From 900f146ed4a7b974bb8a53ee9f5203d8a124becf Mon Sep 17 00:00:00 2001 From: Hugo Shaka Date: Thu, 25 Jan 2024 15:43:21 -0500 Subject: [PATCH 2/2] go mod tidy --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index e85964dfbba4a..494f29db50b3d 100644 --- a/go.mod +++ b/go.mod @@ -177,6 +177,7 @@ require ( go.opentelemetry.io/otel/sdk v1.21.0 go.opentelemetry.io/otel/trace v1.21.0 go.opentelemetry.io/proto/otlp v1.0.0 + go.uber.org/zap v1.26.0 golang.org/x/crypto v0.17.0 golang.org/x/exp v0.0.0-20231108232855-2478ac86f678 golang.org/x/mod v0.14.0 @@ -490,7 +491,6 @@ require ( go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.26.0 // indirect golang.org/x/tools v0.16.1 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect