WIP: hack in a deploy_carvel/supervisor directory, but strip out the deployment for simplicity
This commit is contained in:
parent
1ac8691199
commit
7002e4dd13
3
deploy_carvel/supervisor/config/README.md
Normal file
3
deploy_carvel/supervisor/config/README.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Pinniped Supervisor Deployment
|
||||||
|
|
||||||
|
See [the how-to guide for details](https://pinniped.dev/docs/howto/install-supervisor/).
|
@ -0,0 +1,170 @@
|
|||||||
|
---
|
||||||
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
|
kind: CustomResourceDefinition
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
controller-gen.kubebuilder.io/version: v0.8.0
|
||||||
|
creationTimestamp: null
|
||||||
|
name: federationdomains.config.supervisor.pinniped.dev
|
||||||
|
spec:
|
||||||
|
group: config.supervisor.pinniped.dev
|
||||||
|
names:
|
||||||
|
categories:
|
||||||
|
- pinniped
|
||||||
|
kind: FederationDomain
|
||||||
|
listKind: FederationDomainList
|
||||||
|
plural: federationdomains
|
||||||
|
singular: federationdomain
|
||||||
|
scope: Namespaced
|
||||||
|
versions:
|
||||||
|
- additionalPrinterColumns:
|
||||||
|
- jsonPath: .spec.issuer
|
||||||
|
name: Issuer
|
||||||
|
type: string
|
||||||
|
- jsonPath: .status.status
|
||||||
|
name: Status
|
||||||
|
type: string
|
||||||
|
- jsonPath: .metadata.creationTimestamp
|
||||||
|
name: Age
|
||||||
|
type: date
|
||||||
|
name: v1alpha1
|
||||||
|
schema:
|
||||||
|
openAPIV3Schema:
|
||||||
|
description: FederationDomain describes the configuration of an OIDC provider.
|
||||||
|
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: Spec of the OIDC provider.
|
||||||
|
properties:
|
||||||
|
issuer:
|
||||||
|
description: "Issuer is the OIDC Provider's issuer, per the OIDC Discovery
|
||||||
|
Metadata document, as well as the identifier that it will use for
|
||||||
|
the iss claim in issued JWTs. This field will also be used as the
|
||||||
|
base URL for any endpoints used by the OIDC Provider (e.g., if your
|
||||||
|
issuer is https://example.com/foo, then your authorization endpoint
|
||||||
|
will look like https://example.com/foo/some/path/to/auth/endpoint).
|
||||||
|
\n See https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3
|
||||||
|
for more information."
|
||||||
|
minLength: 1
|
||||||
|
type: string
|
||||||
|
tls:
|
||||||
|
description: TLS configures how this FederationDomain is served over
|
||||||
|
Transport Layer Security (TLS).
|
||||||
|
properties:
|
||||||
|
secretName:
|
||||||
|
description: "SecretName is an optional name of a Secret in the
|
||||||
|
same namespace, of type `kubernetes.io/tls`, which contains
|
||||||
|
the TLS serving certificate for the HTTPS endpoints served by
|
||||||
|
this FederationDomain. When provided, the TLS Secret named here
|
||||||
|
must contain keys named `tls.crt` and `tls.key` that contain
|
||||||
|
the certificate and private key to use for TLS. \n Server Name
|
||||||
|
Indication (SNI) is an extension to the Transport Layer Security
|
||||||
|
(TLS) supported by all major browsers. \n SecretName is required
|
||||||
|
if you would like to use different TLS certificates for issuers
|
||||||
|
of different hostnames. SNI requests do not include port numbers,
|
||||||
|
so all issuers with the same DNS hostname must use the same
|
||||||
|
SecretName value even if they have different port numbers. \n
|
||||||
|
SecretName is not required when you would like to use only the
|
||||||
|
HTTP endpoints (e.g. when the HTTP listener is configured to
|
||||||
|
listen on loopback interfaces or UNIX domain sockets for traffic
|
||||||
|
from a service mesh sidecar). It is also not required when you
|
||||||
|
would like all requests to this OIDC Provider's HTTPS endpoints
|
||||||
|
to use the default TLS certificate, which is configured elsewhere.
|
||||||
|
\n When your Issuer URL's host is an IP address, then this field
|
||||||
|
is ignored. SNI does not work for IP addresses."
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- issuer
|
||||||
|
type: object
|
||||||
|
status:
|
||||||
|
description: Status of the OIDC provider.
|
||||||
|
properties:
|
||||||
|
lastUpdateTime:
|
||||||
|
description: LastUpdateTime holds the time at which the Status was
|
||||||
|
last updated. It is a pointer to get around some undesirable behavior
|
||||||
|
with respect to the empty metav1.Time value (see https://github.com/kubernetes/kubernetes/issues/86811).
|
||||||
|
format: date-time
|
||||||
|
type: string
|
||||||
|
message:
|
||||||
|
description: Message provides human-readable details about the Status.
|
||||||
|
type: string
|
||||||
|
secrets:
|
||||||
|
description: Secrets contains information about this OIDC Provider's
|
||||||
|
secrets.
|
||||||
|
properties:
|
||||||
|
jwks:
|
||||||
|
description: JWKS holds the name of the corev1.Secret in which
|
||||||
|
this OIDC Provider's signing/verification keys are stored. If
|
||||||
|
it is empty, then the signing/verification keys are either unknown
|
||||||
|
or they don't exist.
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||||
|
TODO: Add other useful fields. apiVersion, kind, uid?'
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
stateEncryptionKey:
|
||||||
|
description: StateSigningKey holds the name of the corev1.Secret
|
||||||
|
in which this OIDC Provider's key for encrypting state parameters
|
||||||
|
is stored.
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||||
|
TODO: Add other useful fields. apiVersion, kind, uid?'
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
stateSigningKey:
|
||||||
|
description: StateSigningKey holds the name of the corev1.Secret
|
||||||
|
in which this OIDC Provider's key for signing state parameters
|
||||||
|
is stored.
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||||
|
TODO: Add other useful fields. apiVersion, kind, uid?'
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
tokenSigningKey:
|
||||||
|
description: TokenSigningKey holds the name of the corev1.Secret
|
||||||
|
in which this OIDC Provider's key for signing tokens is stored.
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||||
|
TODO: Add other useful fields. apiVersion, kind, uid?'
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
status:
|
||||||
|
description: Status holds an enum that describes the state of this
|
||||||
|
OIDC Provider. Note that this Status can represent success or failure.
|
||||||
|
enum:
|
||||||
|
- Success
|
||||||
|
- Duplicate
|
||||||
|
- Invalid
|
||||||
|
- SameIssuerHostMustUseSameSecret
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- spec
|
||||||
|
type: object
|
||||||
|
served: true
|
||||||
|
storage: true
|
||||||
|
subresources:
|
||||||
|
status: {}
|
||||||
|
status:
|
||||||
|
acceptedNames:
|
||||||
|
kind: ""
|
||||||
|
plural: ""
|
||||||
|
conditions: []
|
||||||
|
storedVersions: []
|
@ -0,0 +1,221 @@
|
|||||||
|
---
|
||||||
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
|
kind: CustomResourceDefinition
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
controller-gen.kubebuilder.io/version: v0.8.0
|
||||||
|
creationTimestamp: null
|
||||||
|
name: oidcclients.config.supervisor.pinniped.dev
|
||||||
|
spec:
|
||||||
|
group: config.supervisor.pinniped.dev
|
||||||
|
names:
|
||||||
|
categories:
|
||||||
|
- pinniped
|
||||||
|
kind: OIDCClient
|
||||||
|
listKind: OIDCClientList
|
||||||
|
plural: oidcclients
|
||||||
|
singular: oidcclient
|
||||||
|
scope: Namespaced
|
||||||
|
versions:
|
||||||
|
- additionalPrinterColumns:
|
||||||
|
- jsonPath: .spec.allowedScopes[?(@ == "pinniped:request-audience")]
|
||||||
|
name: Privileged Scopes
|
||||||
|
type: string
|
||||||
|
- jsonPath: .status.totalClientSecrets
|
||||||
|
name: Client Secrets
|
||||||
|
type: integer
|
||||||
|
- jsonPath: .status.phase
|
||||||
|
name: Status
|
||||||
|
type: string
|
||||||
|
- jsonPath: .metadata.creationTimestamp
|
||||||
|
name: Age
|
||||||
|
type: date
|
||||||
|
name: v1alpha1
|
||||||
|
schema:
|
||||||
|
openAPIV3Schema:
|
||||||
|
description: OIDCClient describes the configuration of an OIDC client.
|
||||||
|
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: Spec of the OIDC client.
|
||||||
|
properties:
|
||||||
|
allowedGrantTypes:
|
||||||
|
description: "allowedGrantTypes is a list of the allowed grant_type
|
||||||
|
param values that should be accepted during OIDC flows with this
|
||||||
|
client. \n Must only contain the following values: - authorization_code:
|
||||||
|
allows the client to perform the authorization code grant flow,
|
||||||
|
i.e. allows the webapp to authenticate users. This grant must always
|
||||||
|
be listed. - refresh_token: allows the client to perform refresh
|
||||||
|
grants for the user to extend the user's session. This grant must
|
||||||
|
be listed if allowedScopes lists offline_access. - urn:ietf:params:oauth:grant-type:token-exchange:
|
||||||
|
allows the client to perform RFC8693 token exchange, which is a
|
||||||
|
step in the process to be able to get a cluster credential for the
|
||||||
|
user. This grant must be listed if allowedScopes lists pinniped:request-audience."
|
||||||
|
items:
|
||||||
|
enum:
|
||||||
|
- authorization_code
|
||||||
|
- refresh_token
|
||||||
|
- urn:ietf:params:oauth:grant-type:token-exchange
|
||||||
|
type: string
|
||||||
|
minItems: 1
|
||||||
|
type: array
|
||||||
|
x-kubernetes-list-type: set
|
||||||
|
allowedRedirectURIs:
|
||||||
|
description: allowedRedirectURIs is a list of the allowed redirect_uri
|
||||||
|
param values that should be accepted during OIDC flows with this
|
||||||
|
client. Any other uris will be rejected. Must be a URI with the
|
||||||
|
https scheme, unless the hostname is 127.0.0.1 or ::1 which may
|
||||||
|
use the http scheme. Port numbers are not required for 127.0.0.1
|
||||||
|
or ::1 and are ignored when checking for a matching redirect_uri.
|
||||||
|
items:
|
||||||
|
pattern: ^https://.+|^http://(127\.0\.0\.1|\[::1\])(:\d+)?/
|
||||||
|
type: string
|
||||||
|
minItems: 1
|
||||||
|
type: array
|
||||||
|
x-kubernetes-list-type: set
|
||||||
|
allowedScopes:
|
||||||
|
description: "allowedScopes is a list of the allowed scopes param
|
||||||
|
values that should be accepted during OIDC flows with this client.
|
||||||
|
\n Must only contain the following values: - openid: The client
|
||||||
|
is allowed to request ID tokens. ID tokens only include the required
|
||||||
|
claims by default (iss, sub, aud, exp, iat). This scope must always
|
||||||
|
be listed. - offline_access: The client is allowed to request an
|
||||||
|
initial refresh token during the authorization code grant flow.
|
||||||
|
This scope must be listed if allowedGrantTypes lists refresh_token.
|
||||||
|
- pinniped:request-audience: The client is allowed to request a
|
||||||
|
new audience value during a RFC8693 token exchange, which is a step
|
||||||
|
in the process to be able to get a cluster credential for the user.
|
||||||
|
openid, username and groups scopes must be listed when this scope
|
||||||
|
is present. This scope must be listed if allowedGrantTypes lists
|
||||||
|
urn:ietf:params:oauth:grant-type:token-exchange. - username: The
|
||||||
|
client is allowed to request that ID tokens contain the user's username.
|
||||||
|
Without the username scope being requested and allowed, the ID token
|
||||||
|
will not contain the user's username. - groups: The client is allowed
|
||||||
|
to request that ID tokens contain the user's group membership, if
|
||||||
|
their group membership is discoverable by the Supervisor. Without
|
||||||
|
the groups scope being requested and allowed, the ID token will
|
||||||
|
not contain groups."
|
||||||
|
items:
|
||||||
|
enum:
|
||||||
|
- openid
|
||||||
|
- offline_access
|
||||||
|
- username
|
||||||
|
- groups
|
||||||
|
- pinniped:request-audience
|
||||||
|
type: string
|
||||||
|
minItems: 1
|
||||||
|
type: array
|
||||||
|
x-kubernetes-list-type: set
|
||||||
|
required:
|
||||||
|
- allowedGrantTypes
|
||||||
|
- allowedRedirectURIs
|
||||||
|
- allowedScopes
|
||||||
|
type: object
|
||||||
|
status:
|
||||||
|
description: Status of the OIDC client.
|
||||||
|
properties:
|
||||||
|
conditions:
|
||||||
|
description: conditions represent the observations of an OIDCClient's
|
||||||
|
current state.
|
||||||
|
items:
|
||||||
|
description: Condition status of a resource (mirrored from the metav1.Condition
|
||||||
|
type added in Kubernetes 1.19). In a future API version we can
|
||||||
|
switch to using the upstream type. See https://github.com/kubernetes/apimachinery/blob/v0.19.0/pkg/apis/meta/v1/types.go#L1353-L1413.
|
||||||
|
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
|
||||||
|
x-kubernetes-list-map-keys:
|
||||||
|
- type
|
||||||
|
x-kubernetes-list-type: map
|
||||||
|
phase:
|
||||||
|
default: Pending
|
||||||
|
description: phase summarizes the overall status of the OIDCClient.
|
||||||
|
enum:
|
||||||
|
- Pending
|
||||||
|
- Ready
|
||||||
|
- Error
|
||||||
|
type: string
|
||||||
|
totalClientSecrets:
|
||||||
|
description: totalClientSecrets is the current number of client secrets
|
||||||
|
that are detected for this OIDCClient.
|
||||||
|
format: int32
|
||||||
|
type: integer
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- spec
|
||||||
|
type: object
|
||||||
|
served: true
|
||||||
|
storage: true
|
||||||
|
subresources:
|
||||||
|
status: {}
|
||||||
|
status:
|
||||||
|
acceptedNames:
|
||||||
|
kind: ""
|
||||||
|
plural: ""
|
||||||
|
conditions: []
|
||||||
|
storedVersions: []
|
73
deploy_carvel/supervisor/config/deployment-HACKED.yaml
Normal file
73
deploy_carvel/supervisor/config/deployment-HACKED.yaml
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||||
|
#! SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
#@ load("@ytt:data", "data")
|
||||||
|
#@ load("@ytt:yaml", "yaml")
|
||||||
|
#@ load("helpers.lib.yaml",
|
||||||
|
#@ "defaultLabel",
|
||||||
|
#@ "labels",
|
||||||
|
#@ "deploymentPodLabel",
|
||||||
|
#@ "namespace",
|
||||||
|
#@ "defaultResourceName",
|
||||||
|
#@ "defaultResourceNameWithSuffix",
|
||||||
|
#@ "pinnipedDevAPIGroupWithPrefix",
|
||||||
|
#@ "getPinnipedConfigMapData",
|
||||||
|
#@ "hasUnixNetworkEndpoint",
|
||||||
|
#@ )
|
||||||
|
#@ load("@ytt:template", "template")
|
||||||
|
|
||||||
|
#@ if not data.values.into_namespace:
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: #@ data.values.namespace
|
||||||
|
labels: #@ labels()
|
||||||
|
#@ end
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: #@ defaultResourceName()
|
||||||
|
namespace: #@ namespace()
|
||||||
|
labels: #@ labels()
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: #@ defaultResourceNameWithSuffix("static-config")
|
||||||
|
namespace: #@ namespace()
|
||||||
|
labels: #@ labels()
|
||||||
|
data:
|
||||||
|
#@yaml/text-templated-strings
|
||||||
|
pinniped.yaml: #@ yaml.encode(getPinnipedConfigMapData())
|
||||||
|
---
|
||||||
|
#@ if data.values.image_pull_dockerconfigjson and data.values.image_pull_dockerconfigjson != "":
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: image-pull-secret
|
||||||
|
namespace: #@ namespace()
|
||||||
|
labels: #@ labels()
|
||||||
|
type: kubernetes.io/dockerconfigjson
|
||||||
|
data:
|
||||||
|
.dockerconfigjson: #@ data.values.image_pull_dockerconfigjson
|
||||||
|
#@ end
|
||||||
|
---
|
||||||
|
#! THE DEPLOYMENT IS GONE!!!
|
||||||
|
#! THE DEPLOYMENT IS GONE!!!
|
||||||
|
#! THE DEPLOYMENT IS GONE!!! For initial prototype, just installing some simple things.
|
||||||
|
#! THE DEPLOYMENT IS GONE!!!
|
||||||
|
#! THE DEPLOYMENT IS GONE!!!
|
||||||
|
---
|
||||||
|
#! THE SERVICE IS GONE!!!
|
||||||
|
#! THE SERVICE IS GONE!!!
|
||||||
|
#! THE SERVICE IS GONE!!! For initial prototype, just installing some simple things.
|
||||||
|
#! THE SERVICE IS GONE!!!
|
||||||
|
#! THE SERVICE IS GONE!!!
|
||||||
|
---
|
||||||
|
#! THE API SERVICE IS GONE!!!
|
||||||
|
#! THE API SERVICE IS GONE!!!
|
||||||
|
#! THE API SERVICE IS GONE!!! For initial prototype, just installing some simple things.
|
||||||
|
#! THE API SERVICE IS GONE!!!
|
||||||
|
#! THE API SERVICE IS GONE!!!
|
88
deploy_carvel/supervisor/config/helpers.lib.yaml
Normal file
88
deploy_carvel/supervisor/config/helpers.lib.yaml
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||||
|
#! SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
#@ load("@ytt:data", "data")
|
||||||
|
#@ load("@ytt:template", "template")
|
||||||
|
|
||||||
|
#@ def defaultResourceName():
|
||||||
|
#@ return data.values.app_name
|
||||||
|
#@ end
|
||||||
|
|
||||||
|
#@ def defaultResourceNameWithSuffix(suffix):
|
||||||
|
#@ return data.values.app_name + "-" + suffix
|
||||||
|
#@ end
|
||||||
|
|
||||||
|
#@ def pinnipedDevAPIGroupWithPrefix(prefix):
|
||||||
|
#@ return prefix + "." + data.values.api_group_suffix
|
||||||
|
#@ end
|
||||||
|
|
||||||
|
#@ def namespace():
|
||||||
|
#@ if data.values.into_namespace:
|
||||||
|
#@ return data.values.into_namespace
|
||||||
|
#@ else:
|
||||||
|
#@ return data.values.namespace
|
||||||
|
#@ end
|
||||||
|
#@ end
|
||||||
|
|
||||||
|
#@ def defaultLabel():
|
||||||
|
app: #@ data.values.app_name
|
||||||
|
#@ end
|
||||||
|
|
||||||
|
#@ def deploymentPodLabel():
|
||||||
|
deployment.pinniped.dev: supervisor
|
||||||
|
#@ end
|
||||||
|
|
||||||
|
#@ def labels():
|
||||||
|
_: #@ template.replace(defaultLabel())
|
||||||
|
_: #@ template.replace(data.values.custom_labels)
|
||||||
|
#@ end
|
||||||
|
|
||||||
|
#@ def getAndValidateLogLevel():
|
||||||
|
#@ log_level = data.values.log_level
|
||||||
|
#@ if log_level != "info" and log_level != "debug" and log_level != "trace" and log_level != "all":
|
||||||
|
#@ fail("log_level '" + log_level + "' is invalid")
|
||||||
|
#@ end
|
||||||
|
#@ return log_level
|
||||||
|
#@ end
|
||||||
|
|
||||||
|
#@ def getPinnipedConfigMapData():
|
||||||
|
#@ config = {
|
||||||
|
#@ "apiGroupSuffix": data.values.api_group_suffix,
|
||||||
|
#@ "names": {
|
||||||
|
#@ "defaultTLSCertificateSecret": defaultResourceNameWithSuffix("default-tls-certificate"),
|
||||||
|
#@ "apiService": defaultResourceNameWithSuffix("api"),
|
||||||
|
#@ },
|
||||||
|
#@ "labels": labels(),
|
||||||
|
#@ "insecureAcceptExternalUnencryptedHttpRequests": data.values.deprecated_insecure_accept_external_unencrypted_http_requests
|
||||||
|
#@ }
|
||||||
|
#@ if data.values.log_level or data.values.deprecated_log_format:
|
||||||
|
#@ config["log"] = {}
|
||||||
|
#@ end
|
||||||
|
#@ if data.values.log_level:
|
||||||
|
#@ config["log"]["level"] = getAndValidateLogLevel()
|
||||||
|
#@ end
|
||||||
|
#@ if data.values.deprecated_log_format:
|
||||||
|
#@ config["log"]["format"] = data.values.deprecated_log_format
|
||||||
|
#@ end
|
||||||
|
#@ if data.values.endpoints:
|
||||||
|
#@ config["endpoints"] = data.values.endpoints
|
||||||
|
#@ end
|
||||||
|
#@ return config
|
||||||
|
#@ end
|
||||||
|
|
||||||
|
#@ def getattr_safe(val, *args):
|
||||||
|
#@ out = None
|
||||||
|
#@ for arg in args:
|
||||||
|
#@ if not hasattr(val, arg):
|
||||||
|
#@ return None
|
||||||
|
#@ end
|
||||||
|
#@ out = getattr(val, arg)
|
||||||
|
#@ val = out
|
||||||
|
#@ end
|
||||||
|
#@ return out
|
||||||
|
#@ end
|
||||||
|
|
||||||
|
#@ def hasUnixNetworkEndpoint():
|
||||||
|
#@ return getattr_safe(data.values.endpoints, "http", "network") == "unix" or \
|
||||||
|
#@ getattr_safe(data.values.endpoints, "https", "network") == "unix"
|
||||||
|
#@ end
|
@ -0,0 +1,319 @@
|
|||||||
|
---
|
||||||
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
|
kind: CustomResourceDefinition
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
controller-gen.kubebuilder.io/version: v0.8.0
|
||||||
|
creationTimestamp: null
|
||||||
|
name: activedirectoryidentityproviders.idp.supervisor.pinniped.dev
|
||||||
|
spec:
|
||||||
|
group: idp.supervisor.pinniped.dev
|
||||||
|
names:
|
||||||
|
categories:
|
||||||
|
- pinniped
|
||||||
|
- pinniped-idp
|
||||||
|
- pinniped-idps
|
||||||
|
kind: ActiveDirectoryIdentityProvider
|
||||||
|
listKind: ActiveDirectoryIdentityProviderList
|
||||||
|
plural: activedirectoryidentityproviders
|
||||||
|
singular: activedirectoryidentityprovider
|
||||||
|
scope: Namespaced
|
||||||
|
versions:
|
||||||
|
- additionalPrinterColumns:
|
||||||
|
- jsonPath: .spec.host
|
||||||
|
name: Host
|
||||||
|
type: string
|
||||||
|
- jsonPath: .status.phase
|
||||||
|
name: Status
|
||||||
|
type: string
|
||||||
|
- jsonPath: .metadata.creationTimestamp
|
||||||
|
name: Age
|
||||||
|
type: date
|
||||||
|
name: v1alpha1
|
||||||
|
schema:
|
||||||
|
openAPIV3Schema:
|
||||||
|
description: ActiveDirectoryIdentityProvider describes the configuration of
|
||||||
|
an upstream Microsoft Active Directory identity provider.
|
||||||
|
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: Spec for configuring the identity provider.
|
||||||
|
properties:
|
||||||
|
bind:
|
||||||
|
description: Bind contains the configuration for how to provide access
|
||||||
|
credentials during an initial bind to the ActiveDirectory server
|
||||||
|
to be allowed to perform searches and binds to validate a user's
|
||||||
|
credentials during a user's authentication attempt.
|
||||||
|
properties:
|
||||||
|
secretName:
|
||||||
|
description: SecretName contains the name of a namespace-local
|
||||||
|
Secret object that provides the username and password for an
|
||||||
|
Active Directory bind user. This account will be used to perform
|
||||||
|
LDAP searches. The Secret should be of type "kubernetes.io/basic-auth"
|
||||||
|
which includes "username" and "password" keys. The username
|
||||||
|
value should be the full dn (distinguished name) of your bind
|
||||||
|
account, e.g. "cn=bind-account,ou=users,dc=example,dc=com".
|
||||||
|
The password must be non-empty.
|
||||||
|
minLength: 1
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- secretName
|
||||||
|
type: object
|
||||||
|
groupSearch:
|
||||||
|
description: GroupSearch contains the configuration for searching
|
||||||
|
for a user's group membership in ActiveDirectory.
|
||||||
|
properties:
|
||||||
|
attributes:
|
||||||
|
description: Attributes specifies how the group's information
|
||||||
|
should be read from each ActiveDirectory entry which was found
|
||||||
|
as the result of the group search.
|
||||||
|
properties:
|
||||||
|
groupName:
|
||||||
|
description: GroupName specifies the name of the attribute
|
||||||
|
in the Active Directory entries whose value shall become
|
||||||
|
a group name in the user's list of groups after a successful
|
||||||
|
authentication. The value of this field is case-sensitive
|
||||||
|
and must match the case of the attribute name returned by
|
||||||
|
the ActiveDirectory server in the user's entry. E.g. "cn"
|
||||||
|
for common name. Distinguished names can be used by specifying
|
||||||
|
lower-case "dn". Optional. When not specified, this defaults
|
||||||
|
to a custom field that looks like "sAMAccountName@domain",
|
||||||
|
where domain is constructed from the domain components of
|
||||||
|
the group DN.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
base:
|
||||||
|
description: Base is the dn (distinguished name) that should be
|
||||||
|
used as the search base when searching for groups. E.g. "ou=groups,dc=example,dc=com".
|
||||||
|
Optional, when not specified it will be based on the result
|
||||||
|
of a query for the defaultNamingContext (see https://docs.microsoft.com/en-us/windows/win32/adschema/rootdse).
|
||||||
|
The default behavior searches your entire domain for groups.
|
||||||
|
It may make sense to specify a subtree as a search base if you
|
||||||
|
wish to exclude some groups for security reasons or to make
|
||||||
|
searches faster.
|
||||||
|
type: string
|
||||||
|
filter:
|
||||||
|
description: Filter is the ActiveDirectory search filter which
|
||||||
|
should be applied when searching for groups for a user. The
|
||||||
|
pattern "{}" must occur in the filter at least once and will
|
||||||
|
be dynamically replaced by the value of an attribute of the
|
||||||
|
user entry found as a result of the user search. Which attribute's
|
||||||
|
value is used to replace the placeholder(s) depends on the value
|
||||||
|
of UserAttributeForFilter. E.g. "member={}" or "&(objectClass=groupOfNames)(member={})".
|
||||||
|
For more information about ActiveDirectory filters, see https://ldap.com/ldap-filters.
|
||||||
|
Note that the dn (distinguished name) is not an attribute of
|
||||||
|
an entry, so "dn={}" cannot be used. Optional. When not specified,
|
||||||
|
the default will act as if the filter were specified as "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={})".
|
||||||
|
This searches nested groups by default. Note that nested group
|
||||||
|
search can be slow for some Active Directory servers. To disable
|
||||||
|
it, you can set the filter to "(&(objectClass=group)(member={})"
|
||||||
|
type: string
|
||||||
|
skipGroupRefresh:
|
||||||
|
description: "The user's group membership is refreshed as they
|
||||||
|
interact with the supervisor to obtain new credentials (as their
|
||||||
|
old credentials expire). This allows group membership changes
|
||||||
|
to be quickly reflected into Kubernetes clusters. Since group
|
||||||
|
membership is often used to bind authorization policies, it
|
||||||
|
is important to keep the groups observed in Kubernetes clusters
|
||||||
|
in-sync with the identity provider. \n In some environments,
|
||||||
|
frequent group membership queries may result in a significant
|
||||||
|
performance impact on the identity provider and/or the supervisor.
|
||||||
|
The best approach to handle performance impacts is to tweak
|
||||||
|
the group query to be more performant, for example by disabling
|
||||||
|
nested group search or by using a more targeted group search
|
||||||
|
base. \n If the group search query cannot be made performant
|
||||||
|
and you are willing to have group memberships remain static
|
||||||
|
for approximately a day, then set skipGroupRefresh to true.
|
||||||
|
\ This is an insecure configuration as authorization policies
|
||||||
|
that are bound to group membership will not notice if a user
|
||||||
|
has been removed from a particular group until their next login.
|
||||||
|
\n This is an experimental feature that may be removed or significantly
|
||||||
|
altered in the future. Consumers of this configuration should
|
||||||
|
carefully read all release notes before upgrading to ensure
|
||||||
|
that the meaning of this field has not changed."
|
||||||
|
type: boolean
|
||||||
|
userAttributeForFilter:
|
||||||
|
description: UserAttributeForFilter specifies which attribute's
|
||||||
|
value from the user entry found as a result of the user search
|
||||||
|
will be used to replace the "{}" placeholder(s) in the group
|
||||||
|
search Filter. For example, specifying "uid" as the UserAttributeForFilter
|
||||||
|
while specifying "&(objectClass=posixGroup)(memberUid={})" as
|
||||||
|
the Filter would search for groups by replacing the "{}" placeholder
|
||||||
|
in the Filter with the value of the user's "uid" attribute.
|
||||||
|
Optional. When not specified, the default will act as if "dn"
|
||||||
|
were specified. For example, leaving UserAttributeForFilter
|
||||||
|
unspecified while specifying "&(objectClass=groupOfNames)(member={})"
|
||||||
|
as the Filter would search for groups by replacing the "{}"
|
||||||
|
placeholder(s) with the dn (distinguished name) of the user.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
host:
|
||||||
|
description: 'Host is the hostname of this Active Directory identity
|
||||||
|
provider, i.e., where to connect. For example: ldap.example.com:636.'
|
||||||
|
minLength: 1
|
||||||
|
type: string
|
||||||
|
tls:
|
||||||
|
description: TLS contains the connection settings for how to establish
|
||||||
|
the connection to the Host.
|
||||||
|
properties:
|
||||||
|
certificateAuthorityData:
|
||||||
|
description: X.509 Certificate Authority (base64-encoded PEM bundle).
|
||||||
|
If omitted, a default set of system roots will be trusted.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
userSearch:
|
||||||
|
description: UserSearch contains the configuration for searching for
|
||||||
|
a user by name in Active Directory.
|
||||||
|
properties:
|
||||||
|
attributes:
|
||||||
|
description: Attributes specifies how the user's information should
|
||||||
|
be read from the ActiveDirectory entry which was found as the
|
||||||
|
result of the user search.
|
||||||
|
properties:
|
||||||
|
uid:
|
||||||
|
description: UID specifies the name of the attribute in the
|
||||||
|
ActiveDirectory entry which whose value shall be used to
|
||||||
|
uniquely identify the user within this ActiveDirectory provider
|
||||||
|
after a successful authentication. Optional, when empty
|
||||||
|
this defaults to "objectGUID".
|
||||||
|
type: string
|
||||||
|
username:
|
||||||
|
description: Username specifies the name of the attribute
|
||||||
|
in Active Directory entry whose value shall become the username
|
||||||
|
of the user after a successful authentication. Optional,
|
||||||
|
when empty this defaults to "userPrincipalName".
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
base:
|
||||||
|
description: Base is the dn (distinguished name) that should be
|
||||||
|
used as the search base when searching for users. E.g. "ou=users,dc=example,dc=com".
|
||||||
|
Optional, when not specified it will be based on the result
|
||||||
|
of a query for the defaultNamingContext (see https://docs.microsoft.com/en-us/windows/win32/adschema/rootdse).
|
||||||
|
The default behavior searches your entire domain for users.
|
||||||
|
It may make sense to specify a subtree as a search base if you
|
||||||
|
wish to exclude some users or to make searches faster.
|
||||||
|
type: string
|
||||||
|
filter:
|
||||||
|
description: Filter is the search filter which should be applied
|
||||||
|
when searching for users. The pattern "{}" must occur in the
|
||||||
|
filter at least once and will be dynamically replaced by the
|
||||||
|
username for which the search is being run. E.g. "mail={}" or
|
||||||
|
"&(objectClass=person)(uid={})". For more information about
|
||||||
|
LDAP filters, see https://ldap.com/ldap-filters. Note that the
|
||||||
|
dn (distinguished name) is not an attribute of an entry, so
|
||||||
|
"dn={}" cannot be used. Optional. When not specified, the default
|
||||||
|
will be '(&(objectClass=person)(!(objectClass=computer))(!(showInAdvancedViewOnly=TRUE))(|(sAMAccountName={}")(mail={})(userPrincipalName={})(sAMAccountType=805306368))'
|
||||||
|
This means that the user is a person, is not a computer, the
|
||||||
|
sAMAccountType is for a normal user account, and is not shown
|
||||||
|
in advanced view only (which would likely mean its a system
|
||||||
|
created service account with advanced permissions). Also, either
|
||||||
|
the sAMAccountName, the userPrincipalName, or the mail attribute
|
||||||
|
matches the input username.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- host
|
||||||
|
type: object
|
||||||
|
status:
|
||||||
|
description: Status of the identity provider.
|
||||||
|
properties:
|
||||||
|
conditions:
|
||||||
|
description: Represents the observations of an identity provider's
|
||||||
|
current state.
|
||||||
|
items:
|
||||||
|
description: Condition status of a resource (mirrored from the metav1.Condition
|
||||||
|
type added in Kubernetes 1.19). In a future API version we can
|
||||||
|
switch to using the upstream type. See https://github.com/kubernetes/apimachinery/blob/v0.19.0/pkg/apis/meta/v1/types.go#L1353-L1413.
|
||||||
|
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
|
||||||
|
x-kubernetes-list-map-keys:
|
||||||
|
- type
|
||||||
|
x-kubernetes-list-type: map
|
||||||
|
phase:
|
||||||
|
default: Pending
|
||||||
|
description: Phase summarizes the overall status of the ActiveDirectoryIdentityProvider.
|
||||||
|
enum:
|
||||||
|
- Pending
|
||||||
|
- Ready
|
||||||
|
- Error
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- spec
|
||||||
|
type: object
|
||||||
|
served: true
|
||||||
|
storage: true
|
||||||
|
subresources:
|
||||||
|
status: {}
|
||||||
|
status:
|
||||||
|
acceptedNames:
|
||||||
|
kind: ""
|
||||||
|
plural: ""
|
||||||
|
conditions: []
|
||||||
|
storedVersions: []
|
@ -0,0 +1,316 @@
|
|||||||
|
---
|
||||||
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
|
kind: CustomResourceDefinition
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
controller-gen.kubebuilder.io/version: v0.8.0
|
||||||
|
creationTimestamp: null
|
||||||
|
name: ldapidentityproviders.idp.supervisor.pinniped.dev
|
||||||
|
spec:
|
||||||
|
group: idp.supervisor.pinniped.dev
|
||||||
|
names:
|
||||||
|
categories:
|
||||||
|
- pinniped
|
||||||
|
- pinniped-idp
|
||||||
|
- pinniped-idps
|
||||||
|
kind: LDAPIdentityProvider
|
||||||
|
listKind: LDAPIdentityProviderList
|
||||||
|
plural: ldapidentityproviders
|
||||||
|
singular: ldapidentityprovider
|
||||||
|
scope: Namespaced
|
||||||
|
versions:
|
||||||
|
- additionalPrinterColumns:
|
||||||
|
- jsonPath: .spec.host
|
||||||
|
name: Host
|
||||||
|
type: string
|
||||||
|
- jsonPath: .status.phase
|
||||||
|
name: Status
|
||||||
|
type: string
|
||||||
|
- jsonPath: .metadata.creationTimestamp
|
||||||
|
name: Age
|
||||||
|
type: date
|
||||||
|
name: v1alpha1
|
||||||
|
schema:
|
||||||
|
openAPIV3Schema:
|
||||||
|
description: LDAPIdentityProvider describes the configuration of an upstream
|
||||||
|
Lightweight Directory Access Protocol (LDAP) identity provider.
|
||||||
|
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: Spec for configuring the identity provider.
|
||||||
|
properties:
|
||||||
|
bind:
|
||||||
|
description: Bind contains the configuration for how to provide access
|
||||||
|
credentials during an initial bind to the LDAP server to be allowed
|
||||||
|
to perform searches and binds to validate a user's credentials during
|
||||||
|
a user's authentication attempt.
|
||||||
|
properties:
|
||||||
|
secretName:
|
||||||
|
description: SecretName contains the name of a namespace-local
|
||||||
|
Secret object that provides the username and password for an
|
||||||
|
LDAP bind user. This account will be used to perform LDAP searches.
|
||||||
|
The Secret should be of type "kubernetes.io/basic-auth" which
|
||||||
|
includes "username" and "password" keys. The username value
|
||||||
|
should be the full dn (distinguished name) of your bind account,
|
||||||
|
e.g. "cn=bind-account,ou=users,dc=example,dc=com". The password
|
||||||
|
must be non-empty.
|
||||||
|
minLength: 1
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- secretName
|
||||||
|
type: object
|
||||||
|
groupSearch:
|
||||||
|
description: GroupSearch contains the configuration for searching
|
||||||
|
for a user's group membership in the LDAP provider.
|
||||||
|
properties:
|
||||||
|
attributes:
|
||||||
|
description: Attributes specifies how the group's information
|
||||||
|
should be read from each LDAP entry which was found as the result
|
||||||
|
of the group search.
|
||||||
|
properties:
|
||||||
|
groupName:
|
||||||
|
description: GroupName specifies the name of the attribute
|
||||||
|
in the LDAP entries whose value shall become a group name
|
||||||
|
in the user's list of groups after a successful authentication.
|
||||||
|
The value of this field is case-sensitive and must match
|
||||||
|
the case of the attribute name returned by the LDAP server
|
||||||
|
in the user's entry. E.g. "cn" for common name. Distinguished
|
||||||
|
names can be used by specifying lower-case "dn". Optional.
|
||||||
|
When not specified, the default will act as if the GroupName
|
||||||
|
were specified as "dn" (distinguished name).
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
base:
|
||||||
|
description: Base is the dn (distinguished name) that should be
|
||||||
|
used as the search base when searching for groups. E.g. "ou=groups,dc=example,dc=com".
|
||||||
|
When not specified, no group search will be performed and authenticated
|
||||||
|
users will not belong to any groups from the LDAP provider.
|
||||||
|
Also, when not specified, the values of Filter, UserAttributeForFilter,
|
||||||
|
Attributes, and SkipGroupRefresh are ignored.
|
||||||
|
type: string
|
||||||
|
filter:
|
||||||
|
description: Filter is the LDAP search filter which should be
|
||||||
|
applied when searching for groups for a user. The pattern "{}"
|
||||||
|
must occur in the filter at least once and will be dynamically
|
||||||
|
replaced by the value of an attribute of the user entry found
|
||||||
|
as a result of the user search. Which attribute's value is used
|
||||||
|
to replace the placeholder(s) depends on the value of UserAttributeForFilter.
|
||||||
|
For more information about LDAP filters, see https://ldap.com/ldap-filters.
|
||||||
|
Note that the dn (distinguished name) is not an attribute of
|
||||||
|
an entry, so "dn={}" cannot be used. Optional. When not specified,
|
||||||
|
the default will act as if the Filter were specified as "member={}".
|
||||||
|
type: string
|
||||||
|
skipGroupRefresh:
|
||||||
|
description: "The user's group membership is refreshed as they
|
||||||
|
interact with the supervisor to obtain new credentials (as their
|
||||||
|
old credentials expire). This allows group membership changes
|
||||||
|
to be quickly reflected into Kubernetes clusters. Since group
|
||||||
|
membership is often used to bind authorization policies, it
|
||||||
|
is important to keep the groups observed in Kubernetes clusters
|
||||||
|
in-sync with the identity provider. \n In some environments,
|
||||||
|
frequent group membership queries may result in a significant
|
||||||
|
performance impact on the identity provider and/or the supervisor.
|
||||||
|
The best approach to handle performance impacts is to tweak
|
||||||
|
the group query to be more performant, for example by disabling
|
||||||
|
nested group search or by using a more targeted group search
|
||||||
|
base. \n If the group search query cannot be made performant
|
||||||
|
and you are willing to have group memberships remain static
|
||||||
|
for approximately a day, then set skipGroupRefresh to true.
|
||||||
|
\ This is an insecure configuration as authorization policies
|
||||||
|
that are bound to group membership will not notice if a user
|
||||||
|
has been removed from a particular group until their next login.
|
||||||
|
\n This is an experimental feature that may be removed or significantly
|
||||||
|
altered in the future. Consumers of this configuration should
|
||||||
|
carefully read all release notes before upgrading to ensure
|
||||||
|
that the meaning of this field has not changed."
|
||||||
|
type: boolean
|
||||||
|
userAttributeForFilter:
|
||||||
|
description: UserAttributeForFilter specifies which attribute's
|
||||||
|
value from the user entry found as a result of the user search
|
||||||
|
will be used to replace the "{}" placeholder(s) in the group
|
||||||
|
search Filter. For example, specifying "uid" as the UserAttributeForFilter
|
||||||
|
while specifying "&(objectClass=posixGroup)(memberUid={})" as
|
||||||
|
the Filter would search for groups by replacing the "{}" placeholder
|
||||||
|
in the Filter with the value of the user's "uid" attribute.
|
||||||
|
Optional. When not specified, the default will act as if "dn"
|
||||||
|
were specified. For example, leaving UserAttributeForFilter
|
||||||
|
unspecified while specifying "&(objectClass=groupOfNames)(member={})"
|
||||||
|
as the Filter would search for groups by replacing the "{}"
|
||||||
|
placeholder(s) with the dn (distinguished name) of the user.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
host:
|
||||||
|
description: 'Host is the hostname of this LDAP identity provider,
|
||||||
|
i.e., where to connect. For example: ldap.example.com:636.'
|
||||||
|
minLength: 1
|
||||||
|
type: string
|
||||||
|
tls:
|
||||||
|
description: TLS contains the connection settings for how to establish
|
||||||
|
the connection to the Host.
|
||||||
|
properties:
|
||||||
|
certificateAuthorityData:
|
||||||
|
description: X.509 Certificate Authority (base64-encoded PEM bundle).
|
||||||
|
If omitted, a default set of system roots will be trusted.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
userSearch:
|
||||||
|
description: UserSearch contains the configuration for searching for
|
||||||
|
a user by name in the LDAP provider.
|
||||||
|
properties:
|
||||||
|
attributes:
|
||||||
|
description: Attributes specifies how the user's information should
|
||||||
|
be read from the LDAP entry which was found as the result of
|
||||||
|
the user search.
|
||||||
|
properties:
|
||||||
|
uid:
|
||||||
|
description: UID specifies the name of the attribute in the
|
||||||
|
LDAP entry which whose value shall be used to uniquely identify
|
||||||
|
the user within this LDAP provider after a successful authentication.
|
||||||
|
E.g. "uidNumber" or "objectGUID". The value of this field
|
||||||
|
is case-sensitive and must match the case of the attribute
|
||||||
|
name returned by the LDAP server in the user's entry. Distinguished
|
||||||
|
names can be used by specifying lower-case "dn".
|
||||||
|
minLength: 1
|
||||||
|
type: string
|
||||||
|
username:
|
||||||
|
description: Username specifies the name of the attribute
|
||||||
|
in the LDAP entry whose value shall become the username
|
||||||
|
of the user after a successful authentication. This would
|
||||||
|
typically be the same attribute name used in the user search
|
||||||
|
filter, although it can be different. E.g. "mail" or "uid"
|
||||||
|
or "userPrincipalName". The value of this field is case-sensitive
|
||||||
|
and must match the case of the attribute name returned by
|
||||||
|
the LDAP server in the user's entry. Distinguished names
|
||||||
|
can be used by specifying lower-case "dn". When this field
|
||||||
|
is set to "dn" then the LDAPIdentityProviderUserSearch's
|
||||||
|
Filter field cannot be blank, since the default value of
|
||||||
|
"dn={}" would not work.
|
||||||
|
minLength: 1
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
base:
|
||||||
|
description: Base is the dn (distinguished name) that should be
|
||||||
|
used as the search base when searching for users. E.g. "ou=users,dc=example,dc=com".
|
||||||
|
minLength: 1
|
||||||
|
type: string
|
||||||
|
filter:
|
||||||
|
description: Filter is the LDAP search filter which should be
|
||||||
|
applied when searching for users. The pattern "{}" must occur
|
||||||
|
in the filter at least once and will be dynamically replaced
|
||||||
|
by the username for which the search is being run. E.g. "mail={}"
|
||||||
|
or "&(objectClass=person)(uid={})". For more information about
|
||||||
|
LDAP filters, see https://ldap.com/ldap-filters. Note that the
|
||||||
|
dn (distinguished name) is not an attribute of an entry, so
|
||||||
|
"dn={}" cannot be used. Optional. When not specified, the default
|
||||||
|
will act as if the Filter were specified as the value from Attributes.Username
|
||||||
|
appended by "={}". When the Attributes.Username is set to "dn"
|
||||||
|
then the Filter must be explicitly specified, since the default
|
||||||
|
value of "dn={}" would not work.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- host
|
||||||
|
type: object
|
||||||
|
status:
|
||||||
|
description: Status of the identity provider.
|
||||||
|
properties:
|
||||||
|
conditions:
|
||||||
|
description: Represents the observations of an identity provider's
|
||||||
|
current state.
|
||||||
|
items:
|
||||||
|
description: Condition status of a resource (mirrored from the metav1.Condition
|
||||||
|
type added in Kubernetes 1.19). In a future API version we can
|
||||||
|
switch to using the upstream type. See https://github.com/kubernetes/apimachinery/blob/v0.19.0/pkg/apis/meta/v1/types.go#L1353-L1413.
|
||||||
|
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
|
||||||
|
x-kubernetes-list-map-keys:
|
||||||
|
- type
|
||||||
|
x-kubernetes-list-type: map
|
||||||
|
phase:
|
||||||
|
default: Pending
|
||||||
|
description: Phase summarizes the overall status of the LDAPIdentityProvider.
|
||||||
|
enum:
|
||||||
|
- Pending
|
||||||
|
- Ready
|
||||||
|
- Error
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- spec
|
||||||
|
type: object
|
||||||
|
served: true
|
||||||
|
storage: true
|
||||||
|
subresources:
|
||||||
|
status: {}
|
||||||
|
status:
|
||||||
|
acceptedNames:
|
||||||
|
kind: ""
|
||||||
|
plural: ""
|
||||||
|
conditions: []
|
||||||
|
storedVersions: []
|
@ -0,0 +1,346 @@
|
|||||||
|
---
|
||||||
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
|
kind: CustomResourceDefinition
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
controller-gen.kubebuilder.io/version: v0.8.0
|
||||||
|
creationTimestamp: null
|
||||||
|
name: oidcidentityproviders.idp.supervisor.pinniped.dev
|
||||||
|
spec:
|
||||||
|
group: idp.supervisor.pinniped.dev
|
||||||
|
names:
|
||||||
|
categories:
|
||||||
|
- pinniped
|
||||||
|
- pinniped-idp
|
||||||
|
- pinniped-idps
|
||||||
|
kind: OIDCIdentityProvider
|
||||||
|
listKind: OIDCIdentityProviderList
|
||||||
|
plural: oidcidentityproviders
|
||||||
|
singular: oidcidentityprovider
|
||||||
|
scope: Namespaced
|
||||||
|
versions:
|
||||||
|
- additionalPrinterColumns:
|
||||||
|
- jsonPath: .spec.issuer
|
||||||
|
name: Issuer
|
||||||
|
type: string
|
||||||
|
- jsonPath: .status.phase
|
||||||
|
name: Status
|
||||||
|
type: string
|
||||||
|
- jsonPath: .metadata.creationTimestamp
|
||||||
|
name: Age
|
||||||
|
type: date
|
||||||
|
name: v1alpha1
|
||||||
|
schema:
|
||||||
|
openAPIV3Schema:
|
||||||
|
description: OIDCIdentityProvider describes the configuration of an upstream
|
||||||
|
OpenID Connect identity provider.
|
||||||
|
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: Spec for configuring the identity provider.
|
||||||
|
properties:
|
||||||
|
authorizationConfig:
|
||||||
|
description: AuthorizationConfig holds information about how to form
|
||||||
|
the OAuth2 authorization request parameters to be used with this
|
||||||
|
OIDC identity provider.
|
||||||
|
properties:
|
||||||
|
additionalAuthorizeParameters:
|
||||||
|
description: additionalAuthorizeParameters are extra query parameters
|
||||||
|
that should be included in the authorize request to your OIDC
|
||||||
|
provider in the authorization request during an OIDC Authorization
|
||||||
|
Code Flow. By default, no extra parameters are sent. The standard
|
||||||
|
parameters that will be sent are "response_type", "scope", "client_id",
|
||||||
|
"state", "nonce", "code_challenge", "code_challenge_method",
|
||||||
|
and "redirect_uri". These parameters cannot be included in this
|
||||||
|
setting. Additionally, the "hd" parameter cannot be included
|
||||||
|
in this setting at this time. The "hd" parameter is used by
|
||||||
|
Google's OIDC provider to provide a hint as to which "hosted
|
||||||
|
domain" the user should use during login. However, Pinniped
|
||||||
|
does not yet support validating the hosted domain in the resulting
|
||||||
|
ID token, so it is not yet safe to use this feature of Google's
|
||||||
|
OIDC provider with Pinniped. This setting does not influence
|
||||||
|
the parameters sent to the token endpoint in the Resource Owner
|
||||||
|
Password Credentials Grant. The Pinniped Supervisor requires
|
||||||
|
that your OIDC provider returns refresh tokens to the Supervisor
|
||||||
|
from the authorization flows. Some OIDC providers may require
|
||||||
|
a certain value for the "prompt" parameter in order to properly
|
||||||
|
request refresh tokens. See the documentation of your OIDC provider's
|
||||||
|
authorization endpoint for its requirements for what to include
|
||||||
|
in the request in order to receive a refresh token in the response,
|
||||||
|
if anything. If your provider requires the prompt parameter
|
||||||
|
to request a refresh token, then include it here. Also note
|
||||||
|
that most providers also require a certain scope to be requested
|
||||||
|
in order to receive refresh tokens. See the additionalScopes
|
||||||
|
setting for more information about using scopes to request refresh
|
||||||
|
tokens.
|
||||||
|
items:
|
||||||
|
description: Parameter is a key/value pair which represents
|
||||||
|
a parameter in an HTTP request.
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
description: The name of the parameter. Required.
|
||||||
|
minLength: 1
|
||||||
|
type: string
|
||||||
|
value:
|
||||||
|
description: The value of the parameter.
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
x-kubernetes-list-map-keys:
|
||||||
|
- name
|
||||||
|
x-kubernetes-list-type: map
|
||||||
|
additionalScopes:
|
||||||
|
description: 'additionalScopes are the additional scopes that
|
||||||
|
will be requested from your OIDC provider in the authorization
|
||||||
|
request during an OIDC Authorization Code Flow and in the token
|
||||||
|
request during a Resource Owner Password Credentials Grant.
|
||||||
|
Note that the "openid" scope will always be requested regardless
|
||||||
|
of the value in this setting, since it is always required according
|
||||||
|
to the OIDC spec. By default, when this field is not set, the
|
||||||
|
Supervisor will request the following scopes: "openid", "offline_access",
|
||||||
|
"email", and "profile". See https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims
|
||||||
|
for a description of the "profile" and "email" scopes. See https://openid.net/specs/openid-connect-core-1_0.html#OfflineAccess
|
||||||
|
for a description of the "offline_access" scope. This default
|
||||||
|
value may change in future versions of Pinniped as the standard
|
||||||
|
evolves, or as common patterns used by providers who implement
|
||||||
|
the standard in the ecosystem evolve. By setting this list to
|
||||||
|
anything other than an empty list, you are overriding the default
|
||||||
|
value, so you may wish to include some of "offline_access",
|
||||||
|
"email", and "profile" in your override list. If you do not
|
||||||
|
want any of these scopes to be requested, you may set this list
|
||||||
|
to contain only "openid". Some OIDC providers may also require
|
||||||
|
a scope to get access to the user''s group membership, in which
|
||||||
|
case you may wish to include it in this list. Sometimes the
|
||||||
|
scope to request the user''s group membership is called "groups",
|
||||||
|
but unfortunately this is not specified in the OIDC standard.
|
||||||
|
Generally speaking, you should include any scopes required to
|
||||||
|
cause the appropriate claims to be the returned by your OIDC
|
||||||
|
provider in the ID token or userinfo endpoint results for those
|
||||||
|
claims which you would like to use in the oidcClaims settings
|
||||||
|
to determine the usernames and group memberships of your Kubernetes
|
||||||
|
users. See your OIDC provider''s documentation for more information
|
||||||
|
about what scopes are available to request claims. Additionally,
|
||||||
|
the Pinniped Supervisor requires that your OIDC provider returns
|
||||||
|
refresh tokens to the Supervisor from these authorization flows.
|
||||||
|
For most OIDC providers, the scope required to receive refresh
|
||||||
|
tokens will be "offline_access". See the documentation of your
|
||||||
|
OIDC provider''s authorization and token endpoints for its requirements
|
||||||
|
for what to include in the request in order to receive a refresh
|
||||||
|
token in the response, if anything. Note that it may be safe
|
||||||
|
to send "offline_access" even to providers which do not require
|
||||||
|
it, since the provider may ignore scopes that it does not understand
|
||||||
|
or require (see https://datatracker.ietf.org/doc/html/rfc6749#section-3.3).
|
||||||
|
In the unusual case that you must avoid sending the "offline_access"
|
||||||
|
scope, then you must override the default value of this setting.
|
||||||
|
This is required if your OIDC provider will reject the request
|
||||||
|
when it includes "offline_access" (e.g. GitLab''s OIDC provider).'
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
allowPasswordGrant:
|
||||||
|
description: allowPasswordGrant, when true, will allow the use
|
||||||
|
of OAuth 2.0's Resource Owner Password Credentials Grant (see
|
||||||
|
https://datatracker.ietf.org/doc/html/rfc6749#section-4.3) to
|
||||||
|
authenticate to the OIDC provider using a username and password
|
||||||
|
without a web browser, in addition to the usual browser-based
|
||||||
|
OIDC Authorization Code Flow. The Resource Owner Password Credentials
|
||||||
|
Grant is not officially part of the OIDC specification, so it
|
||||||
|
may not be supported by your OIDC provider. If your OIDC provider
|
||||||
|
supports returning ID tokens from a Resource Owner Password
|
||||||
|
Credentials Grant token request, then you can choose to set
|
||||||
|
this field to true. This will allow end users to choose to present
|
||||||
|
their username and password to the kubectl CLI (using the Pinniped
|
||||||
|
plugin) to authenticate to the cluster, without using a web
|
||||||
|
browser to log in as is customary in OIDC Authorization Code
|
||||||
|
Flow. This may be convenient for users, especially for identities
|
||||||
|
from your OIDC provider which are not intended to represent
|
||||||
|
a human actor, such as service accounts performing actions in
|
||||||
|
a CI/CD environment. Even if your OIDC provider supports it,
|
||||||
|
you may wish to disable this behavior by setting this field
|
||||||
|
to false when you prefer to only allow users of this OIDCIdentityProvider
|
||||||
|
to log in via the browser-based OIDC Authorization Code Flow.
|
||||||
|
Using the Resource Owner Password Credentials Grant means that
|
||||||
|
the Pinniped CLI and Pinniped Supervisor will directly handle
|
||||||
|
your end users' passwords (similar to LDAPIdentityProvider),
|
||||||
|
and you will not be able to require multi-factor authentication
|
||||||
|
or use the other web-based login features of your OIDC provider
|
||||||
|
during Resource Owner Password Credentials Grant logins. allowPasswordGrant
|
||||||
|
defaults to false.
|
||||||
|
type: boolean
|
||||||
|
type: object
|
||||||
|
claims:
|
||||||
|
description: Claims provides the names of token claims that will be
|
||||||
|
used when inspecting an identity from this OIDC identity provider.
|
||||||
|
properties:
|
||||||
|
additionalClaimMappings:
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
description: AdditionalClaimMappings allows for additional arbitrary
|
||||||
|
upstream claim values to be mapped into the "additionalClaims"
|
||||||
|
claim of the ID tokens generated by the Supervisor. This should
|
||||||
|
be specified as a map of new claim names as the keys, and upstream
|
||||||
|
claim names as the values. These new claim names will be nested
|
||||||
|
under the top-level "additionalClaims" claim in ID tokens generated
|
||||||
|
by the Supervisor when this OIDCIdentityProvider was used for
|
||||||
|
user authentication. These claims will be made available to
|
||||||
|
all clients. This feature is not required to use the Supervisor
|
||||||
|
to provide authentication for Kubernetes clusters, but can be
|
||||||
|
used when using the Supervisor for other authentication purposes.
|
||||||
|
When this map is empty or the upstream claims are not available,
|
||||||
|
the "additionalClaims" claim will be excluded from the ID tokens
|
||||||
|
generated by the Supervisor.
|
||||||
|
type: object
|
||||||
|
groups:
|
||||||
|
description: Groups provides the name of the ID token claim or
|
||||||
|
userinfo endpoint response claim that will be used to ascertain
|
||||||
|
the groups to which an identity belongs. By default, the identities
|
||||||
|
will not include any group memberships when this setting is
|
||||||
|
not configured.
|
||||||
|
type: string
|
||||||
|
username:
|
||||||
|
description: Username provides the name of the ID token claim
|
||||||
|
or userinfo endpoint response claim that will be used to ascertain
|
||||||
|
an identity's username. When not set, the username will be an
|
||||||
|
automatically constructed unique string which will include the
|
||||||
|
issuer URL of your OIDC provider along with the value of the
|
||||||
|
"sub" (subject) claim from the ID token.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
client:
|
||||||
|
description: OIDCClient contains OIDC client information to be used
|
||||||
|
used with this OIDC identity provider.
|
||||||
|
properties:
|
||||||
|
secretName:
|
||||||
|
description: SecretName contains the name of a namespace-local
|
||||||
|
Secret object that provides the clientID and clientSecret for
|
||||||
|
an OIDC client. If only the SecretName is specified in an OIDCClient
|
||||||
|
struct, then it is expected that the Secret is of type "secrets.pinniped.dev/oidc-client"
|
||||||
|
with keys "clientID" and "clientSecret".
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- secretName
|
||||||
|
type: object
|
||||||
|
issuer:
|
||||||
|
description: Issuer is the issuer URL of this OIDC identity provider,
|
||||||
|
i.e., where to fetch /.well-known/openid-configuration.
|
||||||
|
minLength: 1
|
||||||
|
pattern: ^https://
|
||||||
|
type: string
|
||||||
|
tls:
|
||||||
|
description: TLS configuration for discovery/JWKS requests to the
|
||||||
|
issuer.
|
||||||
|
properties:
|
||||||
|
certificateAuthorityData:
|
||||||
|
description: X.509 Certificate Authority (base64-encoded PEM bundle).
|
||||||
|
If omitted, a default set of system roots will be trusted.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- client
|
||||||
|
- issuer
|
||||||
|
type: object
|
||||||
|
status:
|
||||||
|
description: Status of the identity provider.
|
||||||
|
properties:
|
||||||
|
conditions:
|
||||||
|
description: Represents the observations of an identity provider's
|
||||||
|
current state.
|
||||||
|
items:
|
||||||
|
description: Condition status of a resource (mirrored from the metav1.Condition
|
||||||
|
type added in Kubernetes 1.19). In a future API version we can
|
||||||
|
switch to using the upstream type. See https://github.com/kubernetes/apimachinery/blob/v0.19.0/pkg/apis/meta/v1/types.go#L1353-L1413.
|
||||||
|
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
|
||||||
|
x-kubernetes-list-map-keys:
|
||||||
|
- type
|
||||||
|
x-kubernetes-list-type: map
|
||||||
|
phase:
|
||||||
|
default: Pending
|
||||||
|
description: Phase summarizes the overall status of the OIDCIdentityProvider.
|
||||||
|
enum:
|
||||||
|
- Pending
|
||||||
|
- Ready
|
||||||
|
- Error
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- spec
|
||||||
|
type: object
|
||||||
|
served: true
|
||||||
|
storage: true
|
||||||
|
subresources:
|
||||||
|
status: {}
|
||||||
|
status:
|
||||||
|
acceptedNames:
|
||||||
|
kind: ""
|
||||||
|
plural: ""
|
||||||
|
conditions: []
|
||||||
|
storedVersions: []
|
152
deploy_carvel/supervisor/config/rbac.yaml
Normal file
152
deploy_carvel/supervisor/config/rbac.yaml
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||||
|
#! SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
#@ load("@ytt:data", "data")
|
||||||
|
#@ load("helpers.lib.yaml", "labels", "namespace", "defaultResourceName", "defaultResourceNameWithSuffix", "pinnipedDevAPIGroupWithPrefix")
|
||||||
|
|
||||||
|
#! Give permission to various objects within the app's own namespace
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: Role
|
||||||
|
metadata:
|
||||||
|
name: #@ defaultResourceName()
|
||||||
|
namespace: #@ namespace()
|
||||||
|
labels: #@ labels()
|
||||||
|
rules:
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: [secrets]
|
||||||
|
verbs: [create, get, list, patch, update, watch, delete]
|
||||||
|
- apiGroups:
|
||||||
|
- #@ pinnipedDevAPIGroupWithPrefix("config.supervisor")
|
||||||
|
resources: [federationdomains]
|
||||||
|
verbs: [get, list, watch]
|
||||||
|
- apiGroups:
|
||||||
|
- #@ pinnipedDevAPIGroupWithPrefix("config.supervisor")
|
||||||
|
resources: [federationdomains/status]
|
||||||
|
verbs: [get, patch, update]
|
||||||
|
- apiGroups:
|
||||||
|
- #@ pinnipedDevAPIGroupWithPrefix("config.supervisor")
|
||||||
|
resources: [oidcclients]
|
||||||
|
verbs: [get, list, watch]
|
||||||
|
- apiGroups:
|
||||||
|
- #@ pinnipedDevAPIGroupWithPrefix("config.supervisor")
|
||||||
|
resources: [oidcclients/status]
|
||||||
|
verbs: [get, patch, update]
|
||||||
|
- apiGroups:
|
||||||
|
- #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor")
|
||||||
|
resources: [oidcidentityproviders]
|
||||||
|
verbs: [get, list, watch]
|
||||||
|
- apiGroups:
|
||||||
|
- #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor")
|
||||||
|
resources: [oidcidentityproviders/status]
|
||||||
|
verbs: [get, patch, update]
|
||||||
|
- apiGroups:
|
||||||
|
- #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor")
|
||||||
|
resources: [ldapidentityproviders]
|
||||||
|
verbs: [get, list, watch]
|
||||||
|
- apiGroups:
|
||||||
|
- #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor")
|
||||||
|
resources: [ldapidentityproviders/status]
|
||||||
|
verbs: [get, patch, update]
|
||||||
|
- apiGroups:
|
||||||
|
- #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor")
|
||||||
|
resources: [activedirectoryidentityproviders]
|
||||||
|
verbs: [get, list, watch]
|
||||||
|
- apiGroups:
|
||||||
|
- #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor")
|
||||||
|
resources: [activedirectoryidentityproviders/status]
|
||||||
|
verbs: [get, patch, update]
|
||||||
|
#! We want to be able to read pods/replicasets/deployment so we can learn who our deployment is to set
|
||||||
|
#! as an owner reference.
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: [pods]
|
||||||
|
verbs: [get]
|
||||||
|
- apiGroups: [apps]
|
||||||
|
resources: [replicasets,deployments]
|
||||||
|
verbs: [get]
|
||||||
|
- apiGroups: [ coordination.k8s.io ]
|
||||||
|
resources: [ leases ]
|
||||||
|
verbs: [ create, get, update ]
|
||||||
|
---
|
||||||
|
kind: RoleBinding
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
metadata:
|
||||||
|
name: #@ defaultResourceName()
|
||||||
|
namespace: #@ namespace()
|
||||||
|
labels: #@ labels()
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: #@ defaultResourceName()
|
||||||
|
namespace: #@ namespace()
|
||||||
|
roleRef:
|
||||||
|
kind: Role
|
||||||
|
name: #@ defaultResourceName()
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
|
||||||
|
#! Give permissions for a special configmap of CA bundles that is needed by aggregated api servers
|
||||||
|
---
|
||||||
|
kind: RoleBinding
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
metadata:
|
||||||
|
name: #@ defaultResourceNameWithSuffix("extension-apiserver-authentication-reader")
|
||||||
|
namespace: kube-system
|
||||||
|
labels: #@ labels()
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: #@ defaultResourceName()
|
||||||
|
namespace: #@ namespace()
|
||||||
|
roleRef:
|
||||||
|
kind: Role
|
||||||
|
name: extension-apiserver-authentication-reader
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
|
||||||
|
#! Give permissions for subjectaccessreviews, tokenreview that is needed by aggregated api servers
|
||||||
|
---
|
||||||
|
kind: ClusterRoleBinding
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
metadata:
|
||||||
|
name: #@ defaultResourceName()
|
||||||
|
labels: #@ labels()
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: #@ defaultResourceName()
|
||||||
|
namespace: #@ namespace()
|
||||||
|
roleRef:
|
||||||
|
kind: ClusterRole
|
||||||
|
name: system:auth-delegator
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
|
||||||
|
#! Give permission to various cluster-scoped objects
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRole
|
||||||
|
metadata:
|
||||||
|
name: #@ defaultResourceNameWithSuffix("aggregated-api-server")
|
||||||
|
labels: #@ labels()
|
||||||
|
rules:
|
||||||
|
- apiGroups: [ "" ]
|
||||||
|
resources: [ namespaces ]
|
||||||
|
verbs: [ get, list, watch ]
|
||||||
|
- apiGroups: [ apiregistration.k8s.io ]
|
||||||
|
resources: [ apiservices ]
|
||||||
|
verbs: [ get, list, patch, update, watch ]
|
||||||
|
- apiGroups: [ admissionregistration.k8s.io ]
|
||||||
|
resources: [ validatingwebhookconfigurations, mutatingwebhookconfigurations ]
|
||||||
|
verbs: [ get, list, watch ]
|
||||||
|
- apiGroups: [ flowcontrol.apiserver.k8s.io ]
|
||||||
|
resources: [ flowschemas, prioritylevelconfigurations ]
|
||||||
|
verbs: [ get, list, watch ]
|
||||||
|
---
|
||||||
|
kind: ClusterRoleBinding
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
metadata:
|
||||||
|
name: #@ defaultResourceNameWithSuffix("aggregated-api-server")
|
||||||
|
labels: #@ labels()
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: #@ defaultResourceName()
|
||||||
|
namespace: #@ namespace()
|
||||||
|
roleRef:
|
||||||
|
kind: ClusterRole
|
||||||
|
name: #@ defaultResourceNameWithSuffix("aggregated-api-server")
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
115
deploy_carvel/supervisor/config/service.yaml
Normal file
115
deploy_carvel/supervisor/config/service.yaml
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||||
|
#! SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
#@ load("@ytt:data", "data")
|
||||||
|
#@ load("@ytt:assert", "assert")
|
||||||
|
#@ load("helpers.lib.yaml", "labels", "deploymentPodLabel", "namespace", "defaultResourceName", "defaultResourceNameWithSuffix")
|
||||||
|
|
||||||
|
#@ if hasattr(data.values, "service_http_nodeport_port"):
|
||||||
|
#@ assert.fail('value "service_http_nodeport_port" has been renamed to "deprecated_service_http_nodeport_port" and will be removed in a future release')
|
||||||
|
#@ end
|
||||||
|
#@ if hasattr(data.values, "service_http_nodeport_nodeport"):
|
||||||
|
#@ assert.fail('value "service_http_nodeport_nodeport" has been renamed to "deprecated_service_http_nodeport_nodeport" and will be removed in a future release')
|
||||||
|
#@ end
|
||||||
|
#@ if hasattr(data.values, "service_http_loadbalancer_port"):
|
||||||
|
#@ assert.fail('value "service_http_loadbalancer_port" has been renamed to "deprecated_service_http_loadbalancer_port" and will be removed in a future release')
|
||||||
|
#@ end
|
||||||
|
#@ if hasattr(data.values, "service_http_clusterip_port"):
|
||||||
|
#@ assert.fail('value "service_http_clusterip_port" has been renamed to "deprecated_service_http_clusterip_port" and will be removed in a future release')
|
||||||
|
#@ end
|
||||||
|
|
||||||
|
#@ if data.values.deprecated_service_http_nodeport_port or data.values.service_https_nodeport_port:
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: #@ defaultResourceNameWithSuffix("nodeport")
|
||||||
|
namespace: #@ namespace()
|
||||||
|
labels: #@ labels()
|
||||||
|
#! prevent kapp from altering the selector of our services to match kubectl behavior
|
||||||
|
annotations:
|
||||||
|
kapp.k14s.io/disable-default-label-scoping-rules: ""
|
||||||
|
spec:
|
||||||
|
type: NodePort
|
||||||
|
selector: #@ deploymentPodLabel()
|
||||||
|
ports:
|
||||||
|
#@ if data.values.deprecated_service_http_nodeport_port:
|
||||||
|
- name: http
|
||||||
|
protocol: TCP
|
||||||
|
port: #@ data.values.deprecated_service_http_nodeport_port
|
||||||
|
targetPort: 8080
|
||||||
|
#@ if data.values.deprecated_service_http_nodeport_nodeport:
|
||||||
|
nodePort: #@ data.values.deprecated_service_http_nodeport_nodeport
|
||||||
|
#@ end
|
||||||
|
#@ end
|
||||||
|
#@ if data.values.service_https_nodeport_port:
|
||||||
|
- name: https
|
||||||
|
protocol: TCP
|
||||||
|
port: #@ data.values.service_https_nodeport_port
|
||||||
|
targetPort: 8443
|
||||||
|
#@ if data.values.service_https_nodeport_nodeport:
|
||||||
|
nodePort: #@ data.values.service_https_nodeport_nodeport
|
||||||
|
#@ end
|
||||||
|
#@ end
|
||||||
|
#@ end
|
||||||
|
|
||||||
|
#@ if data.values.deprecated_service_http_clusterip_port or data.values.service_https_clusterip_port:
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: #@ defaultResourceNameWithSuffix("clusterip")
|
||||||
|
namespace: #@ namespace()
|
||||||
|
labels: #@ labels()
|
||||||
|
#! prevent kapp from altering the selector of our services to match kubectl behavior
|
||||||
|
annotations:
|
||||||
|
kapp.k14s.io/disable-default-label-scoping-rules: ""
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
selector: #@ deploymentPodLabel()
|
||||||
|
ports:
|
||||||
|
#@ if data.values.deprecated_service_http_clusterip_port:
|
||||||
|
- name: http
|
||||||
|
protocol: TCP
|
||||||
|
port: #@ data.values.deprecated_service_http_clusterip_port
|
||||||
|
targetPort: 8080
|
||||||
|
#@ end
|
||||||
|
#@ if data.values.service_https_clusterip_port:
|
||||||
|
- name: https
|
||||||
|
protocol: TCP
|
||||||
|
port: #@ data.values.service_https_clusterip_port
|
||||||
|
targetPort: 8443
|
||||||
|
#@ end
|
||||||
|
#@ end
|
||||||
|
|
||||||
|
#@ if data.values.deprecated_service_http_loadbalancer_port or data.values.service_https_loadbalancer_port:
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: #@ defaultResourceNameWithSuffix("loadbalancer")
|
||||||
|
namespace: #@ namespace()
|
||||||
|
labels: #@ labels()
|
||||||
|
#! prevent kapp from altering the selector of our services to match kubectl behavior
|
||||||
|
annotations:
|
||||||
|
kapp.k14s.io/disable-default-label-scoping-rules: ""
|
||||||
|
spec:
|
||||||
|
type: LoadBalancer
|
||||||
|
selector: #@ deploymentPodLabel()
|
||||||
|
#@ if data.values.service_loadbalancer_ip:
|
||||||
|
loadBalancerIP: #@ data.values.service_loadbalancer_ip
|
||||||
|
#@ end
|
||||||
|
ports:
|
||||||
|
#@ if data.values.deprecated_service_http_loadbalancer_port:
|
||||||
|
- name: http
|
||||||
|
protocol: TCP
|
||||||
|
port: #@ data.values.deprecated_service_http_loadbalancer_port
|
||||||
|
targetPort: 8080
|
||||||
|
#@ end
|
||||||
|
#@ if data.values.service_https_loadbalancer_port:
|
||||||
|
- name: https
|
||||||
|
protocol: TCP
|
||||||
|
port: #@ data.values.service_https_loadbalancer_port
|
||||||
|
targetPort: 8443
|
||||||
|
#@ end
|
||||||
|
#@ end
|
133
deploy_carvel/supervisor/config/values.yaml
Normal file
133
deploy_carvel/supervisor/config/values.yaml
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||||
|
#! SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
#@data/values
|
||||||
|
---
|
||||||
|
|
||||||
|
app_name: pinniped-supervisor
|
||||||
|
|
||||||
|
#! Creates a new namespace statically in yaml with the given name and installs the app into that namespace.
|
||||||
|
namespace: pinniped-supervisor
|
||||||
|
#! If specified, assumes that a namespace of the given name already exists and installs the app into that namespace.
|
||||||
|
#! If both `namespace` and `into_namespace` are specified, then only `into_namespace` is used.
|
||||||
|
into_namespace: #! e.g. my-preexisting-namespace
|
||||||
|
|
||||||
|
#! All resources created statically by yaml at install-time and all resources created dynamically
|
||||||
|
#! by controllers at runtime will be labelled with `app: $app_name` and also with the labels
|
||||||
|
#! specified here. The value of `custom_labels` must be a map of string keys to string values.
|
||||||
|
#! The app can be uninstalled either by:
|
||||||
|
#! 1. Deleting the static install-time yaml resources including the static namespace, which will cascade and also delete
|
||||||
|
#! resources that were dynamically created by controllers at runtime
|
||||||
|
#! 2. Or, deleting all resources by label, which does not assume that there was a static install-time yaml namespace.
|
||||||
|
custom_labels: {} #! e.g. {myCustomLabelName: myCustomLabelValue, otherCustomLabelName: otherCustomLabelValue}
|
||||||
|
|
||||||
|
#! Specify how many replicas of the Pinniped server to run.
|
||||||
|
replicas: 2
|
||||||
|
|
||||||
|
#! Specify either an image_digest or an image_tag. If both are given, only image_digest will be used.
|
||||||
|
image_repo: projects.registry.vmware.com/pinniped/pinniped-server
|
||||||
|
image_digest: #! e.g. sha256:f3c4fdfd3ef865d4b97a1fd295d94acc3f0c654c46b6f27ffad5cf80216903c8
|
||||||
|
image_tag: latest
|
||||||
|
|
||||||
|
#! Specifies a secret to be used when pulling the above `image_repo` container image.
|
||||||
|
#! Can be used when the above image_repo is a private registry.
|
||||||
|
#! Typically the value would be the output of: kubectl create secret docker-registry x --docker-server=https://example.io --docker-username="USERNAME" --docker-password="PASSWORD" --dry-run=client -o json | jq -r '.data[".dockerconfigjson"]'
|
||||||
|
#! Optional.
|
||||||
|
image_pull_dockerconfigjson: #! e.g. {"auths":{"https://registry.example.com":{"username":"USERNAME","password":"PASSWORD","auth":"BASE64_ENCODED_USERNAME_COLON_PASSWORD"}}}
|
||||||
|
|
||||||
|
#! Specify how to expose the Supervisor app's HTTPS port as a Service.
|
||||||
|
#! Typically, you would set a value for only one of the following service types.
|
||||||
|
#! Setting any of these values means that a Service of that type will be created. They are all optional.
|
||||||
|
#! Note that all port numbers should be numbers (not strings), i.e. use ytt's `--data-value-yaml` instead of `--data-value`.
|
||||||
|
#! Several of these values have been deprecated and will be removed in a future release. Their names have been changed to
|
||||||
|
#! mark them as deprecated and to make it obvious upon upgrade to anyone who was using them that they have been deprecated.
|
||||||
|
deprecated_service_http_nodeport_port: #! will be removed in a future release; when specified, creates a NodePort Service with this `port` value, with port 8080 as its `targetPort`; e.g. 31234
|
||||||
|
deprecated_service_http_nodeport_nodeport: #! will be removed in a future release; the `nodePort` value of the NodePort Service, optional when `deprecated_service_http_nodeport_port` is specified; e.g. 31234
|
||||||
|
deprecated_service_http_loadbalancer_port: #! will be removed in a future release; when specified, creates a LoadBalancer Service with this `port` value, with port 8080 as its `targetPort`; e.g. 8443
|
||||||
|
deprecated_service_http_clusterip_port: #! will be removed in a future release; when specified, creates a ClusterIP Service with this `port` value, with port 8080 as its `targetPort`; e.g. 8443
|
||||||
|
service_https_nodeport_port: #! when specified, creates a NodePort Service with this `port` value, with port 8443 as its `targetPort`; e.g. 31243
|
||||||
|
service_https_nodeport_nodeport: #! the `nodePort` value of the NodePort Service, optional when `service_https_nodeport_port` is specified; e.g. 31243
|
||||||
|
service_https_loadbalancer_port: #! when specified, creates a LoadBalancer Service with this `port` value, with port 8443 as its `targetPort`; e.g. 8443
|
||||||
|
service_https_clusterip_port: #! when specified, creates a ClusterIP Service with this `port` value, with port 8443 as its `targetPort`; e.g. 8443
|
||||||
|
#! The `loadBalancerIP` value of the LoadBalancer Service.
|
||||||
|
#! Ignored unless service_https_loadbalancer_port is provided.
|
||||||
|
#! Optional.
|
||||||
|
service_loadbalancer_ip: #! e.g. 1.2.3.4
|
||||||
|
|
||||||
|
#! Specify the verbosity of logging: info ("nice to know" information), debug (developer information), trace (timing information),
|
||||||
|
#! or all (kitchen sink). Do not use trace or all on production systems, as credentials may get logged.
|
||||||
|
log_level: #! By default, when this value is left unset, only warnings and errors are printed. There is no way to suppress warning and error logs.
|
||||||
|
#! Specify the format of logging: json (for machine parsable logs) and text (for legacy klog formatted logs).
|
||||||
|
#! By default, when this value is left unset, logs are formatted in json.
|
||||||
|
#! This configuration is deprecated and will be removed in a future release at which point logs will always be formatted as json.
|
||||||
|
deprecated_log_format:
|
||||||
|
|
||||||
|
run_as_user: 65532 #! run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice
|
||||||
|
run_as_group: 65532 #! run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice
|
||||||
|
|
||||||
|
#! Specify the API group suffix for all Pinniped API groups. By default, this is set to
|
||||||
|
#! pinniped.dev, so Pinniped API groups will look like foo.pinniped.dev,
|
||||||
|
#! authentication.concierge.pinniped.dev, etc. As an example, if this is set to tuna.io, then
|
||||||
|
#! Pinniped API groups will look like foo.tuna.io. authentication.concierge.tuna.io, etc.
|
||||||
|
api_group_suffix: pinniped.dev
|
||||||
|
|
||||||
|
#! Set the standard golang HTTPS_PROXY and NO_PROXY environment variables on the Supervisor containers.
|
||||||
|
#! These will be used when the Supervisor makes backend-to-backend calls to upstream identity providers using HTTPS,
|
||||||
|
#! e.g. when the Supervisor fetches discovery documents, JWKS keys, and tokens from an upstream OIDC Provider.
|
||||||
|
#! The Supervisor never makes insecure HTTP calls, so there is no reason to set HTTP_PROXY.
|
||||||
|
#! Optional.
|
||||||
|
https_proxy: #! e.g. http://proxy.example.com
|
||||||
|
no_proxy: "$(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.cluster.local" #! do not proxy Kubernetes endpoints
|
||||||
|
|
||||||
|
#! Control the HTTP and HTTPS listeners of the Supervisor.
|
||||||
|
#!
|
||||||
|
#! The schema of this config is as follows:
|
||||||
|
#!
|
||||||
|
#! endpoints:
|
||||||
|
#! https:
|
||||||
|
#! network: tcp | unix | disabled
|
||||||
|
#! address: host:port when network=tcp or /pinniped_socket/socketfile.sock when network=unix
|
||||||
|
#! http:
|
||||||
|
#! network: same as above
|
||||||
|
#! address: same as above, except that when network=tcp then the address is only allowed to bind to loopback interfaces
|
||||||
|
#!
|
||||||
|
#! Setting network to disabled turns off that particular listener.
|
||||||
|
#! See https://pkg.go.dev/net#Listen and https://pkg.go.dev/net#Dial for a description of what can be
|
||||||
|
#! specified in the address parameter based on the given network parameter. To aid in the use of unix
|
||||||
|
#! domain sockets, a writable empty dir volume is mounted at /pinniped_socket when network is set to "unix."
|
||||||
|
#!
|
||||||
|
#! The current defaults are:
|
||||||
|
#!
|
||||||
|
#! endpoints:
|
||||||
|
#! https:
|
||||||
|
#! network: tcp
|
||||||
|
#! address: :8443
|
||||||
|
#! http:
|
||||||
|
#! network: disabled
|
||||||
|
#!
|
||||||
|
#! These defaults mean: For HTTPS listening, bind to all interfaces using TCP on port 8443.
|
||||||
|
#! Disable HTTP listening by default.
|
||||||
|
#!
|
||||||
|
#! The HTTP listener can only be bound to loopback interfaces. This allows the listener to accept
|
||||||
|
#! traffic from within the pod, e.g. from a service mesh sidecar. The HTTP listener should not be
|
||||||
|
#! used to accept traffic from outside the pod, since that would mean that the network traffic could be
|
||||||
|
#! transmitted unencrypted. The HTTPS listener should be used instead to accept traffic from outside the pod.
|
||||||
|
#! Ingresses and load balancers that terminate TLS connections should re-encrypt the data and route traffic
|
||||||
|
#! to the HTTPS listener. Unix domain sockets may also be used for integrations with service meshes.
|
||||||
|
#!
|
||||||
|
#! Changing the HTTPS port number must be accompanied by matching changes to the service and deployment
|
||||||
|
#! manifests. Changes to the HTTPS listener must be coordinated with the deployment health checks.
|
||||||
|
#!
|
||||||
|
#! Optional.
|
||||||
|
endpoints:
|
||||||
|
|
||||||
|
#! Optionally override the validation on the endpoints.http value which checks that only loopback interfaces are used.
|
||||||
|
#! When deprecated_insecure_accept_external_unencrypted_http_requests is true, the HTTP listener is allowed to bind to any
|
||||||
|
#! interface, including interfaces that are listening for traffic from outside the pod. This value is being introduced
|
||||||
|
#! to ease the transition to the new loopback interface validation for the HTTP port for any users who need more time
|
||||||
|
#! to change their ingress strategy to avoid using plain HTTP into the Supervisor pods.
|
||||||
|
#! This value is immediately deprecated upon its introduction. It will be removed in some future release, at which time
|
||||||
|
#! traffic from outside the pod will need to be sent to the HTTPS listener instead, with no simple workaround available.
|
||||||
|
#! Allowed values are true (boolean), "true" (string), false (boolean), and "false" (string). The default is false.
|
||||||
|
#! Optional.
|
||||||
|
deprecated_insecure_accept_external_unencrypted_http_requests: false
|
63
deploy_carvel/supervisor/config/z0_crd_overlay.yaml
Normal file
63
deploy_carvel/supervisor/config/z0_crd_overlay.yaml
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||||
|
#! SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
#@ load("@ytt:overlay", "overlay")
|
||||||
|
#@ load("helpers.lib.yaml", "labels", "pinnipedDevAPIGroupWithPrefix")
|
||||||
|
#@ load("@ytt:data", "data")
|
||||||
|
|
||||||
|
#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"federationdomains.config.supervisor.pinniped.dev"}}), expects=1
|
||||||
|
---
|
||||||
|
metadata:
|
||||||
|
#@overlay/match missing_ok=True
|
||||||
|
labels: #@ labels()
|
||||||
|
name: #@ pinnipedDevAPIGroupWithPrefix("federationdomains.config.supervisor")
|
||||||
|
spec:
|
||||||
|
group: #@ pinnipedDevAPIGroupWithPrefix("config.supervisor")
|
||||||
|
|
||||||
|
#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"oidcidentityproviders.idp.supervisor.pinniped.dev"}}), expects=1
|
||||||
|
---
|
||||||
|
metadata:
|
||||||
|
#@overlay/match missing_ok=True
|
||||||
|
labels: #@ labels()
|
||||||
|
name: #@ pinnipedDevAPIGroupWithPrefix("oidcidentityproviders.idp.supervisor")
|
||||||
|
spec:
|
||||||
|
group: #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor")
|
||||||
|
|
||||||
|
#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"ldapidentityproviders.idp.supervisor.pinniped.dev"}}), expects=1
|
||||||
|
---
|
||||||
|
metadata:
|
||||||
|
#@overlay/match missing_ok=True
|
||||||
|
labels: #@ labels()
|
||||||
|
name: #@ pinnipedDevAPIGroupWithPrefix("ldapidentityproviders.idp.supervisor")
|
||||||
|
spec:
|
||||||
|
group: #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor")
|
||||||
|
|
||||||
|
#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"activedirectoryidentityproviders.idp.supervisor.pinniped.dev"}}), expects=1
|
||||||
|
---
|
||||||
|
metadata:
|
||||||
|
#@overlay/match missing_ok=True
|
||||||
|
labels: #@ labels()
|
||||||
|
name: #@ pinnipedDevAPIGroupWithPrefix("activedirectoryidentityproviders.idp.supervisor")
|
||||||
|
spec:
|
||||||
|
group: #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor")
|
||||||
|
|
||||||
|
#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"oidcclients.config.supervisor.pinniped.dev"}}), expects=1
|
||||||
|
---
|
||||||
|
metadata:
|
||||||
|
#@overlay/match missing_ok=True
|
||||||
|
labels: #@ labels()
|
||||||
|
name: #@ pinnipedDevAPIGroupWithPrefix("oidcclients.config.supervisor")
|
||||||
|
spec:
|
||||||
|
group: #@ pinnipedDevAPIGroupWithPrefix("config.supervisor")
|
||||||
|
versions:
|
||||||
|
#@overlay/match by=overlay.all, expects="1+"
|
||||||
|
- schema:
|
||||||
|
openAPIV3Schema:
|
||||||
|
#@overlay/match by=overlay.subset({"metadata":{"type":"object"}}), expects=1
|
||||||
|
properties:
|
||||||
|
metadata:
|
||||||
|
#@overlay/match missing_ok=True
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
pattern: ^client\.oauth\.pinniped\.dev-
|
||||||
|
type: string
|
Loading…
Reference in New Issue
Block a user