Use vendir sync instead of cp to sync the deploy manifests
This commit is contained in:
parent
0f0d9927c0
commit
de1bbde2cc
1
deploy_carvel/concierge/.gitignore
vendored
Normal file
1
deploy_carvel/concierge/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
config/
|
@ -1,3 +0,0 @@
|
|||||||
# Pinniped Concierge Deployment
|
|
||||||
|
|
||||||
See [the how-to guide for details](https://pinniped.dev/docs/howto/install-concierge/).
|
|
@ -1,175 +0,0 @@
|
|||||||
---
|
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
|
||||||
kind: CustomResourceDefinition
|
|
||||||
metadata:
|
|
||||||
annotations:
|
|
||||||
controller-gen.kubebuilder.io/version: v0.13.0
|
|
||||||
name: jwtauthenticators.authentication.concierge.pinniped.dev
|
|
||||||
spec:
|
|
||||||
group: authentication.concierge.pinniped.dev
|
|
||||||
names:
|
|
||||||
categories:
|
|
||||||
- pinniped
|
|
||||||
- pinniped-authenticator
|
|
||||||
- pinniped-authenticators
|
|
||||||
kind: JWTAuthenticator
|
|
||||||
listKind: JWTAuthenticatorList
|
|
||||||
plural: jwtauthenticators
|
|
||||||
singular: jwtauthenticator
|
|
||||||
scope: Cluster
|
|
||||||
versions:
|
|
||||||
- additionalPrinterColumns:
|
|
||||||
- jsonPath: .spec.issuer
|
|
||||||
name: Issuer
|
|
||||||
type: string
|
|
||||||
- jsonPath: .spec.audience
|
|
||||||
name: Audience
|
|
||||||
type: string
|
|
||||||
- jsonPath: .metadata.creationTimestamp
|
|
||||||
name: Age
|
|
||||||
type: date
|
|
||||||
name: v1alpha1
|
|
||||||
schema:
|
|
||||||
openAPIV3Schema:
|
|
||||||
description: "JWTAuthenticator describes the configuration of a JWT authenticator.
|
|
||||||
\n Upon receiving a signed JWT, a JWTAuthenticator will performs some validation
|
|
||||||
on it (e.g., valid signature, existence of claims, etc.) and extract the
|
|
||||||
username and groups from the token."
|
|
||||||
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 authenticator.
|
|
||||||
properties:
|
|
||||||
audience:
|
|
||||||
description: Audience is the required value of the "aud" JWT claim.
|
|
||||||
minLength: 1
|
|
||||||
type: string
|
|
||||||
claims:
|
|
||||||
description: Claims allows customization of the claims that will be
|
|
||||||
mapped to user identity for Kubernetes access.
|
|
||||||
properties:
|
|
||||||
groups:
|
|
||||||
description: Groups is the name of the claim which should be read
|
|
||||||
to extract the user's group membership from the JWT token. When
|
|
||||||
not specified, it will default to "groups".
|
|
||||||
type: string
|
|
||||||
username:
|
|
||||||
description: Username is the name of the claim which should be
|
|
||||||
read to extract the username from the JWT token. When not specified,
|
|
||||||
it will default to "username".
|
|
||||||
type: string
|
|
||||||
type: object
|
|
||||||
issuer:
|
|
||||||
description: Issuer is the OIDC issuer URL that will be used to discover
|
|
||||||
public signing keys. Issuer is also used to validate the "iss" JWT
|
|
||||||
claim.
|
|
||||||
minLength: 1
|
|
||||||
pattern: ^https://
|
|
||||||
type: string
|
|
||||||
tls:
|
|
||||||
description: TLS configuration for communicating with the OIDC provider.
|
|
||||||
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:
|
|
||||||
- audience
|
|
||||||
- issuer
|
|
||||||
type: object
|
|
||||||
status:
|
|
||||||
description: Status of the authenticator.
|
|
||||||
properties:
|
|
||||||
conditions:
|
|
||||||
description: Represents the observations of the authenticator's current
|
|
||||||
state.
|
|
||||||
items:
|
|
||||||
description: "Condition contains details for one aspect of the current
|
|
||||||
state of this API Resource. --- This struct is intended for direct
|
|
||||||
use as an array at the field path .status.conditions. For example,
|
|
||||||
\n type FooStatus struct{ // Represents the observations of a
|
|
||||||
foo's current state. // Known .status.conditions.type are: \"Available\",
|
|
||||||
\"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
|
|
||||||
// +listType=map // +listMapKey=type Conditions []metav1.Condition
|
|
||||||
`json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
|
|
||||||
protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
|
|
||||||
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
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- spec
|
|
||||||
type: object
|
|
||||||
served: true
|
|
||||||
storage: true
|
|
||||||
subresources:
|
|
||||||
status: {}
|
|
@ -1,148 +0,0 @@
|
|||||||
---
|
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
|
||||||
kind: CustomResourceDefinition
|
|
||||||
metadata:
|
|
||||||
annotations:
|
|
||||||
controller-gen.kubebuilder.io/version: v0.13.0
|
|
||||||
name: webhookauthenticators.authentication.concierge.pinniped.dev
|
|
||||||
spec:
|
|
||||||
group: authentication.concierge.pinniped.dev
|
|
||||||
names:
|
|
||||||
categories:
|
|
||||||
- pinniped
|
|
||||||
- pinniped-authenticator
|
|
||||||
- pinniped-authenticators
|
|
||||||
kind: WebhookAuthenticator
|
|
||||||
listKind: WebhookAuthenticatorList
|
|
||||||
plural: webhookauthenticators
|
|
||||||
singular: webhookauthenticator
|
|
||||||
scope: Cluster
|
|
||||||
versions:
|
|
||||||
- additionalPrinterColumns:
|
|
||||||
- jsonPath: .spec.endpoint
|
|
||||||
name: Endpoint
|
|
||||||
type: string
|
|
||||||
- jsonPath: .metadata.creationTimestamp
|
|
||||||
name: Age
|
|
||||||
type: date
|
|
||||||
name: v1alpha1
|
|
||||||
schema:
|
|
||||||
openAPIV3Schema:
|
|
||||||
description: WebhookAuthenticator describes the configuration of a webhook
|
|
||||||
authenticator.
|
|
||||||
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 authenticator.
|
|
||||||
properties:
|
|
||||||
endpoint:
|
|
||||||
description: Webhook server endpoint URL.
|
|
||||||
minLength: 1
|
|
||||||
pattern: ^https://
|
|
||||||
type: string
|
|
||||||
tls:
|
|
||||||
description: TLS configuration.
|
|
||||||
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:
|
|
||||||
- endpoint
|
|
||||||
type: object
|
|
||||||
status:
|
|
||||||
description: Status of the authenticator.
|
|
||||||
properties:
|
|
||||||
conditions:
|
|
||||||
description: Represents the observations of the authenticator's current
|
|
||||||
state.
|
|
||||||
items:
|
|
||||||
description: "Condition contains details for one aspect of the current
|
|
||||||
state of this API Resource. --- This struct is intended for direct
|
|
||||||
use as an array at the field path .status.conditions. For example,
|
|
||||||
\n type FooStatus struct{ // Represents the observations of a
|
|
||||||
foo's current state. // Known .status.conditions.type are: \"Available\",
|
|
||||||
\"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
|
|
||||||
// +listType=map // +listMapKey=type Conditions []metav1.Condition
|
|
||||||
`json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
|
|
||||||
protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
|
|
||||||
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
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- spec
|
|
||||||
type: object
|
|
||||||
served: true
|
|
||||||
storage: true
|
|
||||||
subresources:
|
|
||||||
status: {}
|
|
@ -1,257 +0,0 @@
|
|||||||
---
|
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
|
||||||
kind: CustomResourceDefinition
|
|
||||||
metadata:
|
|
||||||
annotations:
|
|
||||||
controller-gen.kubebuilder.io/version: v0.13.0
|
|
||||||
name: credentialissuers.config.concierge.pinniped.dev
|
|
||||||
spec:
|
|
||||||
group: config.concierge.pinniped.dev
|
|
||||||
names:
|
|
||||||
categories:
|
|
||||||
- pinniped
|
|
||||||
kind: CredentialIssuer
|
|
||||||
listKind: CredentialIssuerList
|
|
||||||
plural: credentialissuers
|
|
||||||
singular: credentialissuer
|
|
||||||
scope: Cluster
|
|
||||||
versions:
|
|
||||||
- additionalPrinterColumns:
|
|
||||||
- jsonPath: .spec.impersonationProxy.mode
|
|
||||||
name: ProxyMode
|
|
||||||
type: string
|
|
||||||
- jsonPath: .status.strategies[?(@.status == "Success")].type
|
|
||||||
name: DefaultStrategy
|
|
||||||
type: string
|
|
||||||
- jsonPath: .metadata.creationTimestamp
|
|
||||||
name: Age
|
|
||||||
type: date
|
|
||||||
name: v1alpha1
|
|
||||||
schema:
|
|
||||||
openAPIV3Schema:
|
|
||||||
description: CredentialIssuer describes the configuration and status of the
|
|
||||||
Pinniped Concierge credential issuer.
|
|
||||||
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 describes the intended configuration of the Concierge.
|
|
||||||
properties:
|
|
||||||
impersonationProxy:
|
|
||||||
description: ImpersonationProxy describes the intended configuration
|
|
||||||
of the Concierge impersonation proxy.
|
|
||||||
properties:
|
|
||||||
externalEndpoint:
|
|
||||||
description: "ExternalEndpoint describes the HTTPS endpoint where
|
|
||||||
the proxy will be exposed. If not set, the proxy will be served
|
|
||||||
using the external name of the LoadBalancer service or the cluster
|
|
||||||
service DNS name. \n This field must be non-empty when spec.impersonationProxy.service.type
|
|
||||||
is \"None\"."
|
|
||||||
type: string
|
|
||||||
mode:
|
|
||||||
description: 'Mode configures whether the impersonation proxy
|
|
||||||
should be started: - "disabled" explicitly disables the impersonation
|
|
||||||
proxy. This is the default. - "enabled" explicitly enables the
|
|
||||||
impersonation proxy. - "auto" enables or disables the impersonation
|
|
||||||
proxy based upon the cluster in which it is running.'
|
|
||||||
enum:
|
|
||||||
- auto
|
|
||||||
- enabled
|
|
||||||
- disabled
|
|
||||||
type: string
|
|
||||||
service:
|
|
||||||
default:
|
|
||||||
type: LoadBalancer
|
|
||||||
description: Service describes the configuration of the Service
|
|
||||||
provisioned to expose the impersonation proxy to clients.
|
|
||||||
properties:
|
|
||||||
annotations:
|
|
||||||
additionalProperties:
|
|
||||||
type: string
|
|
||||||
description: Annotations specifies zero or more key/value
|
|
||||||
pairs to set as annotations on the provisioned Service.
|
|
||||||
type: object
|
|
||||||
loadBalancerIP:
|
|
||||||
description: LoadBalancerIP specifies the IP address to set
|
|
||||||
in the spec.loadBalancerIP field of the provisioned Service.
|
|
||||||
This is not supported on all cloud providers.
|
|
||||||
maxLength: 255
|
|
||||||
minLength: 1
|
|
||||||
type: string
|
|
||||||
type:
|
|
||||||
default: LoadBalancer
|
|
||||||
description: "Type specifies the type of Service to provision
|
|
||||||
for the impersonation proxy. \n If the type is \"None\",
|
|
||||||
then the \"spec.impersonationProxy.externalEndpoint\" field
|
|
||||||
must be set to a non-empty value so that the Concierge can
|
|
||||||
properly advertise the endpoint in the CredentialIssuer's
|
|
||||||
status."
|
|
||||||
enum:
|
|
||||||
- LoadBalancer
|
|
||||||
- ClusterIP
|
|
||||||
- None
|
|
||||||
type: string
|
|
||||||
type: object
|
|
||||||
tls:
|
|
||||||
description: "TLS contains information about how the Concierge
|
|
||||||
impersonation proxy should serve TLS. \n If this field is empty,
|
|
||||||
the impersonation proxy will generate its own TLS certificate."
|
|
||||||
properties:
|
|
||||||
certificateAuthorityData:
|
|
||||||
description: X.509 Certificate Authority (base64-encoded PEM
|
|
||||||
bundle). Used to advertise the CA bundle for the impersonation
|
|
||||||
proxy endpoint.
|
|
||||||
type: string
|
|
||||||
secretName:
|
|
||||||
description: SecretName is the name of a Secret in the same
|
|
||||||
namespace, of type `kubernetes.io/tls`, which contains the
|
|
||||||
TLS serving certificate for the Concierge impersonation
|
|
||||||
proxy endpoint.
|
|
||||||
minLength: 1
|
|
||||||
type: string
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- mode
|
|
||||||
- service
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- impersonationProxy
|
|
||||||
type: object
|
|
||||||
status:
|
|
||||||
description: CredentialIssuerStatus describes the status of the Concierge.
|
|
||||||
properties:
|
|
||||||
kubeConfigInfo:
|
|
||||||
description: Information needed to form a valid Pinniped-based kubeconfig
|
|
||||||
using this credential issuer. This field is deprecated and will
|
|
||||||
be removed in a future version.
|
|
||||||
properties:
|
|
||||||
certificateAuthorityData:
|
|
||||||
description: The K8s API server CA bundle.
|
|
||||||
minLength: 1
|
|
||||||
type: string
|
|
||||||
server:
|
|
||||||
description: The K8s API server URL.
|
|
||||||
minLength: 1
|
|
||||||
pattern: ^https://|^http://
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- certificateAuthorityData
|
|
||||||
- server
|
|
||||||
type: object
|
|
||||||
strategies:
|
|
||||||
description: List of integration strategies that were attempted by
|
|
||||||
Pinniped.
|
|
||||||
items:
|
|
||||||
description: CredentialIssuerStrategy describes the status of an
|
|
||||||
integration strategy that was attempted by Pinniped.
|
|
||||||
properties:
|
|
||||||
frontend:
|
|
||||||
description: Frontend describes how clients can connect using
|
|
||||||
this strategy.
|
|
||||||
properties:
|
|
||||||
impersonationProxyInfo:
|
|
||||||
description: ImpersonationProxyInfo describes the parameters
|
|
||||||
for the impersonation proxy on this Concierge. This field
|
|
||||||
is only set when Type is "ImpersonationProxy".
|
|
||||||
properties:
|
|
||||||
certificateAuthorityData:
|
|
||||||
description: CertificateAuthorityData is the base64-encoded
|
|
||||||
PEM CA bundle of the impersonation proxy.
|
|
||||||
minLength: 1
|
|
||||||
type: string
|
|
||||||
endpoint:
|
|
||||||
description: Endpoint is the HTTPS endpoint of the impersonation
|
|
||||||
proxy.
|
|
||||||
minLength: 1
|
|
||||||
pattern: ^https://
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- certificateAuthorityData
|
|
||||||
- endpoint
|
|
||||||
type: object
|
|
||||||
tokenCredentialRequestInfo:
|
|
||||||
description: TokenCredentialRequestAPIInfo describes the
|
|
||||||
parameters for the TokenCredentialRequest API on this
|
|
||||||
Concierge. This field is only set when Type is "TokenCredentialRequestAPI".
|
|
||||||
properties:
|
|
||||||
certificateAuthorityData:
|
|
||||||
description: CertificateAuthorityData is the base64-encoded
|
|
||||||
Kubernetes API server CA bundle.
|
|
||||||
minLength: 1
|
|
||||||
type: string
|
|
||||||
server:
|
|
||||||
description: Server is the Kubernetes API server URL.
|
|
||||||
minLength: 1
|
|
||||||
pattern: ^https://|^http://
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- certificateAuthorityData
|
|
||||||
- server
|
|
||||||
type: object
|
|
||||||
type:
|
|
||||||
description: Type describes which frontend mechanism clients
|
|
||||||
can use with a strategy.
|
|
||||||
enum:
|
|
||||||
- TokenCredentialRequestAPI
|
|
||||||
- ImpersonationProxy
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- type
|
|
||||||
type: object
|
|
||||||
lastUpdateTime:
|
|
||||||
description: When the status was last checked.
|
|
||||||
format: date-time
|
|
||||||
type: string
|
|
||||||
message:
|
|
||||||
description: Human-readable description of the current status.
|
|
||||||
minLength: 1
|
|
||||||
type: string
|
|
||||||
reason:
|
|
||||||
description: Reason for the current status.
|
|
||||||
enum:
|
|
||||||
- Listening
|
|
||||||
- Pending
|
|
||||||
- Disabled
|
|
||||||
- ErrorDuringSetup
|
|
||||||
- CouldNotFetchKey
|
|
||||||
- CouldNotGetClusterInfo
|
|
||||||
- FetchedKey
|
|
||||||
type: string
|
|
||||||
status:
|
|
||||||
description: Status of the attempted integration strategy.
|
|
||||||
enum:
|
|
||||||
- Success
|
|
||||||
- Error
|
|
||||||
type: string
|
|
||||||
type:
|
|
||||||
description: Type of integration attempted.
|
|
||||||
enum:
|
|
||||||
- KubeClusterSigningCertificate
|
|
||||||
- ImpersonationProxy
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- lastUpdateTime
|
|
||||||
- message
|
|
||||||
- reason
|
|
||||||
- status
|
|
||||||
- type
|
|
||||||
type: object
|
|
||||||
type: array
|
|
||||||
required:
|
|
||||||
- strategies
|
|
||||||
type: object
|
|
||||||
type: object
|
|
||||||
served: true
|
|
||||||
storage: true
|
|
||||||
subresources:
|
|
||||||
status: {}
|
|
@ -1,355 +0,0 @@
|
|||||||
#! Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
|
||||||
#! SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
#@ load("@ytt:data", "data")
|
|
||||||
#@ load("@ytt:json", "json")
|
|
||||||
#@ load("helpers.lib.yaml", "defaultLabel", "labels", "deploymentPodLabel", "namespace", "defaultResourceName", "defaultResourceNameWithSuffix", "getAndValidateLogLevel", "pinnipedDevAPIGroupWithPrefix")
|
|
||||||
#@ load("@ytt:template", "template")
|
|
||||||
|
|
||||||
#@ if not data.values.into_namespace:
|
|
||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Namespace
|
|
||||||
metadata:
|
|
||||||
name: #@ data.values.namespace
|
|
||||||
labels:
|
|
||||||
_: #@ template.replace(labels())
|
|
||||||
#! When deploying onto a cluster which has PSAs enabled by default for namespaces,
|
|
||||||
#! effectively disable them for this namespace. The kube-cert-agent Deployment's pod
|
|
||||||
#! created by the Concierge in this namespace needs to be able to perform privileged
|
|
||||||
#! actions. The regular Concierge pod containers created by the Deployment below do
|
|
||||||
#! not need special privileges and are marked as such in their securityContext settings.
|
|
||||||
pod-security.kubernetes.io/enforce: privileged
|
|
||||||
#@ end
|
|
||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: ServiceAccount
|
|
||||||
metadata:
|
|
||||||
name: #@ defaultResourceName()
|
|
||||||
namespace: #@ namespace()
|
|
||||||
labels: #@ labels()
|
|
||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: ServiceAccount
|
|
||||||
metadata:
|
|
||||||
name: #@ defaultResourceNameWithSuffix("kube-cert-agent")
|
|
||||||
namespace: #@ namespace()
|
|
||||||
labels: #@ labels()
|
|
||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: ServiceAccount
|
|
||||||
metadata:
|
|
||||||
name: #@ defaultResourceNameWithSuffix("impersonation-proxy")
|
|
||||||
namespace: #@ namespace()
|
|
||||||
labels: #@ labels()
|
|
||||||
annotations:
|
|
||||||
#! we need to create this service account before we create the secret
|
|
||||||
kapp.k14s.io/change-group: "impersonation-proxy.concierge.pinniped.dev/serviceaccount"
|
|
||||||
secrets: #! make sure the token controller does not create any other secrets
|
|
||||||
- name: #@ defaultResourceNameWithSuffix("impersonation-proxy")
|
|
||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: ConfigMap
|
|
||||||
metadata:
|
|
||||||
name: #@ defaultResourceNameWithSuffix("config")
|
|
||||||
namespace: #@ namespace()
|
|
||||||
labels: #@ labels()
|
|
||||||
data:
|
|
||||||
#! If names.apiService is changed in this ConfigMap, must also change name of the ClusterIP Service resource below.
|
|
||||||
#@yaml/text-templated-strings
|
|
||||||
pinniped.yaml: |
|
|
||||||
discovery:
|
|
||||||
url: (@= data.values.discovery_url or "null" @)
|
|
||||||
api:
|
|
||||||
servingCertificate:
|
|
||||||
durationSeconds: (@= str(data.values.api_serving_certificate_duration_seconds) @)
|
|
||||||
renewBeforeSeconds: (@= str(data.values.api_serving_certificate_renew_before_seconds) @)
|
|
||||||
apiGroupSuffix: (@= data.values.api_group_suffix @)
|
|
||||||
# aggregatedAPIServerPort may be set here, although other YAML references to the default port (10250) may also need to be updated
|
|
||||||
# impersonationProxyServerPort may be set here, although other YAML references to the default port (8444) may also need to be updated
|
|
||||||
names:
|
|
||||||
servingCertificateSecret: (@= defaultResourceNameWithSuffix("api-tls-serving-certificate") @)
|
|
||||||
credentialIssuer: (@= defaultResourceNameWithSuffix("config") @)
|
|
||||||
apiService: (@= defaultResourceNameWithSuffix("api") @)
|
|
||||||
impersonationLoadBalancerService: (@= defaultResourceNameWithSuffix("impersonation-proxy-load-balancer") @)
|
|
||||||
impersonationClusterIPService: (@= defaultResourceNameWithSuffix("impersonation-proxy-cluster-ip") @)
|
|
||||||
impersonationTLSCertificateSecret: (@= defaultResourceNameWithSuffix("impersonation-proxy-tls-serving-certificate") @)
|
|
||||||
impersonationCACertificateSecret: (@= defaultResourceNameWithSuffix("impersonation-proxy-ca-certificate") @)
|
|
||||||
impersonationSignerSecret: (@= defaultResourceNameWithSuffix("impersonation-proxy-signer-ca-certificate") @)
|
|
||||||
agentServiceAccount: (@= defaultResourceNameWithSuffix("kube-cert-agent") @)
|
|
||||||
labels: (@= json.encode(labels()).rstrip() @)
|
|
||||||
kubeCertAgent:
|
|
||||||
namePrefix: (@= defaultResourceNameWithSuffix("kube-cert-agent-") @)
|
|
||||||
(@ if data.values.kube_cert_agent_image: @)
|
|
||||||
image: (@= data.values.kube_cert_agent_image @)
|
|
||||||
(@ else: @)
|
|
||||||
(@ if data.values.image_digest: @)
|
|
||||||
image: (@= data.values.image_repo + "@" + data.values.image_digest @)
|
|
||||||
(@ else: @)
|
|
||||||
image: (@= data.values.image_repo + ":" + data.values.image_tag @)
|
|
||||||
(@ end @)
|
|
||||||
(@ end @)
|
|
||||||
(@ if data.values.image_pull_dockerconfigjson: @)
|
|
||||||
imagePullSecrets:
|
|
||||||
- image-pull-secret
|
|
||||||
(@ end @)
|
|
||||||
(@ if data.values.log_level or data.values.deprecated_log_format: @)
|
|
||||||
log:
|
|
||||||
(@ if data.values.log_level: @)
|
|
||||||
level: (@= getAndValidateLogLevel() @)
|
|
||||||
(@ end @)
|
|
||||||
(@ if data.values.deprecated_log_format: @)
|
|
||||||
format: (@= data.values.deprecated_log_format @)
|
|
||||||
(@ end @)
|
|
||||||
(@ end @)
|
|
||||||
---
|
|
||||||
#@ 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
|
|
||||||
---
|
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: #@ defaultResourceName()
|
|
||||||
namespace: #@ namespace()
|
|
||||||
labels: #@ labels()
|
|
||||||
spec:
|
|
||||||
replicas: #@ data.values.replicas
|
|
||||||
selector:
|
|
||||||
#! In hindsight, this should have been deploymentPodLabel(), but this field is immutable so changing it would break upgrades.
|
|
||||||
matchLabels: #@ defaultLabel()
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
#! This has always included defaultLabel(), which is used by this Deployment's selector.
|
|
||||||
_: #@ template.replace(defaultLabel())
|
|
||||||
#! More recently added the more unique deploymentPodLabel() so Services can select these Pods more specifically
|
|
||||||
#! without accidentally selecting any other Deployment's Pods, especially the kube cert agent Deployment's Pods.
|
|
||||||
_: #@ template.replace(deploymentPodLabel())
|
|
||||||
spec:
|
|
||||||
securityContext:
|
|
||||||
runAsUser: #@ data.values.run_as_user
|
|
||||||
runAsGroup: #@ data.values.run_as_group
|
|
||||||
serviceAccountName: #@ defaultResourceName()
|
|
||||||
#@ if data.values.image_pull_dockerconfigjson and data.values.image_pull_dockerconfigjson != "":
|
|
||||||
imagePullSecrets:
|
|
||||||
- name: image-pull-secret
|
|
||||||
#@ end
|
|
||||||
containers:
|
|
||||||
- name: #@ defaultResourceName()
|
|
||||||
#@ if data.values.image_digest:
|
|
||||||
image: #@ data.values.image_repo + "@" + data.values.image_digest
|
|
||||||
#@ else:
|
|
||||||
image: #@ data.values.image_repo + ":" + data.values.image_tag
|
|
||||||
#@ end
|
|
||||||
imagePullPolicy: IfNotPresent
|
|
||||||
securityContext:
|
|
||||||
readOnlyRootFilesystem: true
|
|
||||||
runAsNonRoot: true
|
|
||||||
allowPrivilegeEscalation: false
|
|
||||||
capabilities:
|
|
||||||
drop: [ "ALL" ]
|
|
||||||
#! seccompProfile was introduced in Kube v1.19. Using it on an older Kube version will result in a
|
|
||||||
#! kubectl validation error when installing via `kubectl apply`, which can be ignored using kubectl's
|
|
||||||
#! `--validate=false` flag. Note that installing via `kapp` does not complain about this validation error.
|
|
||||||
seccompProfile:
|
|
||||||
type: "RuntimeDefault"
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
cpu: "100m"
|
|
||||||
memory: "128Mi"
|
|
||||||
limits:
|
|
||||||
cpu: "100m"
|
|
||||||
memory: "128Mi"
|
|
||||||
command:
|
|
||||||
- pinniped-concierge
|
|
||||||
- --config=/etc/config/pinniped.yaml
|
|
||||||
- --downward-api-path=/etc/podinfo
|
|
||||||
volumeMounts:
|
|
||||||
- name: tmp
|
|
||||||
mountPath: /tmp
|
|
||||||
- name: config-volume
|
|
||||||
mountPath: /etc/config
|
|
||||||
readOnly: true
|
|
||||||
- name: podinfo
|
|
||||||
mountPath: /etc/podinfo
|
|
||||||
readOnly: true
|
|
||||||
- name: impersonation-proxy
|
|
||||||
mountPath: /var/run/secrets/impersonation-proxy.concierge.pinniped.dev/serviceaccount
|
|
||||||
readOnly: true
|
|
||||||
env:
|
|
||||||
#@ if data.values.https_proxy:
|
|
||||||
- name: HTTPS_PROXY
|
|
||||||
value: #@ data.values.https_proxy
|
|
||||||
#@ end
|
|
||||||
#@ if data.values.https_proxy and data.values.no_proxy:
|
|
||||||
- name: NO_PROXY
|
|
||||||
value: #@ data.values.no_proxy
|
|
||||||
#@ end
|
|
||||||
livenessProbe:
|
|
||||||
httpGet:
|
|
||||||
path: /healthz
|
|
||||||
port: 10250
|
|
||||||
scheme: HTTPS
|
|
||||||
initialDelaySeconds: 2
|
|
||||||
timeoutSeconds: 15
|
|
||||||
periodSeconds: 10
|
|
||||||
failureThreshold: 5
|
|
||||||
readinessProbe:
|
|
||||||
httpGet:
|
|
||||||
path: /healthz
|
|
||||||
port: 10250
|
|
||||||
scheme: HTTPS
|
|
||||||
initialDelaySeconds: 2
|
|
||||||
timeoutSeconds: 3
|
|
||||||
periodSeconds: 10
|
|
||||||
failureThreshold: 3
|
|
||||||
volumes:
|
|
||||||
- name: tmp
|
|
||||||
emptyDir:
|
|
||||||
medium: Memory
|
|
||||||
sizeLimit: 100Mi
|
|
||||||
- name: config-volume
|
|
||||||
configMap:
|
|
||||||
name: #@ defaultResourceNameWithSuffix("config")
|
|
||||||
- name: impersonation-proxy
|
|
||||||
secret:
|
|
||||||
secretName: #@ defaultResourceNameWithSuffix("impersonation-proxy")
|
|
||||||
items: #! make sure our pod does not start until the token controller has a chance to populate the secret
|
|
||||||
- key: token
|
|
||||||
path: token
|
|
||||||
- name: podinfo
|
|
||||||
downwardAPI:
|
|
||||||
items:
|
|
||||||
- path: "labels"
|
|
||||||
fieldRef:
|
|
||||||
fieldPath: metadata.labels
|
|
||||||
- path: "name"
|
|
||||||
fieldRef:
|
|
||||||
fieldPath: metadata.name
|
|
||||||
- path: "namespace"
|
|
||||||
fieldRef:
|
|
||||||
fieldPath: metadata.namespace
|
|
||||||
tolerations:
|
|
||||||
- key: CriticalAddonsOnly
|
|
||||||
operator: Exists
|
|
||||||
- key: node-role.kubernetes.io/master #! Allow running on master nodes too (name deprecated by kubernetes 1.20).
|
|
||||||
effect: NoSchedule
|
|
||||||
- key: node-role.kubernetes.io/control-plane #! The new name for these nodes as of Kubernetes 1.24.
|
|
||||||
effect: NoSchedule
|
|
||||||
#! This will help make sure our multiple pods run on different nodes, making
|
|
||||||
#! our deployment "more" "HA".
|
|
||||||
affinity:
|
|
||||||
podAntiAffinity:
|
|
||||||
preferredDuringSchedulingIgnoredDuringExecution:
|
|
||||||
- weight: 50
|
|
||||||
podAffinityTerm:
|
|
||||||
labelSelector:
|
|
||||||
matchLabels: #@ deploymentPodLabel()
|
|
||||||
topologyKey: kubernetes.io/hostname
|
|
||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
#! If name is changed, must also change names.apiService in the ConfigMap above and spec.service.name in the APIService below.
|
|
||||||
name: #@ defaultResourceNameWithSuffix("api")
|
|
||||||
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:
|
|
||||||
- protocol: TCP
|
|
||||||
port: 443
|
|
||||||
targetPort: 10250
|
|
||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: #@ defaultResourceNameWithSuffix("proxy")
|
|
||||||
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:
|
|
||||||
- protocol: TCP
|
|
||||||
port: 443
|
|
||||||
targetPort: 8444
|
|
||||||
---
|
|
||||||
apiVersion: apiregistration.k8s.io/v1
|
|
||||||
kind: APIService
|
|
||||||
metadata:
|
|
||||||
name: #@ pinnipedDevAPIGroupWithPrefix("v1alpha1.login.concierge")
|
|
||||||
labels: #@ labels()
|
|
||||||
spec:
|
|
||||||
version: v1alpha1
|
|
||||||
group: #@ pinnipedDevAPIGroupWithPrefix("login.concierge")
|
|
||||||
groupPriorityMinimum: 9900
|
|
||||||
versionPriority: 15
|
|
||||||
#! caBundle: Do not include this key here. Starts out null, will be updated/owned by the golang code.
|
|
||||||
service:
|
|
||||||
name: #@ defaultResourceNameWithSuffix("api")
|
|
||||||
namespace: #@ namespace()
|
|
||||||
port: 443
|
|
||||||
---
|
|
||||||
apiVersion: apiregistration.k8s.io/v1
|
|
||||||
kind: APIService
|
|
||||||
metadata:
|
|
||||||
name: #@ pinnipedDevAPIGroupWithPrefix("v1alpha1.identity.concierge")
|
|
||||||
labels: #@ labels()
|
|
||||||
spec:
|
|
||||||
version: v1alpha1
|
|
||||||
group: #@ pinnipedDevAPIGroupWithPrefix("identity.concierge")
|
|
||||||
groupPriorityMinimum: 9900
|
|
||||||
versionPriority: 15
|
|
||||||
#! caBundle: Do not include this key here. Starts out null, will be updated/owned by the golang code.
|
|
||||||
service:
|
|
||||||
name: #@ defaultResourceNameWithSuffix("api")
|
|
||||||
namespace: #@ namespace()
|
|
||||||
port: 443
|
|
||||||
---
|
|
||||||
apiVersion: #@ pinnipedDevAPIGroupWithPrefix("config.concierge") + "/v1alpha1"
|
|
||||||
kind: CredentialIssuer
|
|
||||||
metadata:
|
|
||||||
name: #@ defaultResourceNameWithSuffix("config")
|
|
||||||
labels: #@ labels()
|
|
||||||
spec:
|
|
||||||
impersonationProxy:
|
|
||||||
mode: #@ data.values.impersonation_proxy_spec.mode
|
|
||||||
#@ if data.values.impersonation_proxy_spec.external_endpoint:
|
|
||||||
externalEndpoint: #@ data.values.impersonation_proxy_spec.external_endpoint
|
|
||||||
#@ end
|
|
||||||
service:
|
|
||||||
type: #@ data.values.impersonation_proxy_spec.service.type
|
|
||||||
#@ if data.values.impersonation_proxy_spec.service.load_balancer_ip:
|
|
||||||
loadBalancerIP: #@ data.values.impersonation_proxy_spec.service.load_balancer_ip
|
|
||||||
#@ end
|
|
||||||
annotations: #@ data.values.impersonation_proxy_spec.service.annotations
|
|
||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Secret
|
|
||||||
metadata:
|
|
||||||
name: #@ defaultResourceNameWithSuffix("impersonation-proxy")
|
|
||||||
namespace: #@ namespace()
|
|
||||||
labels: #@ labels()
|
|
||||||
annotations:
|
|
||||||
#! wait until the SA exists to create this secret so that the token controller does not delete it
|
|
||||||
#! we have this secret at the end so that kubectl will create the service account first
|
|
||||||
kapp.k14s.io/change-rule: "upsert after upserting impersonation-proxy.concierge.pinniped.dev/serviceaccount"
|
|
||||||
kubernetes.io/service-account.name: #@ defaultResourceNameWithSuffix("impersonation-proxy")
|
|
||||||
type: kubernetes.io/service-account-token
|
|
@ -1,47 +0,0 @@
|
|||||||
#! Copyright 2020-2021 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():
|
|
||||||
#! Note that the name of this label's key is also assumed by kubecertagent.go and impersonator_config.go
|
|
||||||
app: #@ data.values.app_name
|
|
||||||
#@ end
|
|
||||||
|
|
||||||
#@ def deploymentPodLabel():
|
|
||||||
deployment.pinniped.dev: concierge
|
|
||||||
#@ 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
|
|
@ -1,296 +0,0 @@
|
|||||||
#! Copyright 2020-2021 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 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 ]
|
|
||||||
- apiGroups: [ security.openshift.io ]
|
|
||||||
resources: [ securitycontextconstraints ]
|
|
||||||
verbs: [ use ]
|
|
||||||
resourceNames: [ nonroot ]
|
|
||||||
- apiGroups: [ "" ]
|
|
||||||
resources: [ nodes ]
|
|
||||||
verbs: [ list ]
|
|
||||||
- apiGroups:
|
|
||||||
- #@ pinnipedDevAPIGroupWithPrefix("config.concierge")
|
|
||||||
resources: [ credentialissuers ]
|
|
||||||
verbs: [ get, list, watch, create ]
|
|
||||||
- apiGroups:
|
|
||||||
- #@ pinnipedDevAPIGroupWithPrefix("config.concierge")
|
|
||||||
resources: [ credentialissuers/status ]
|
|
||||||
verbs: [ get, patch, update ]
|
|
||||||
- apiGroups:
|
|
||||||
- #@ pinnipedDevAPIGroupWithPrefix("authentication.concierge")
|
|
||||||
resources: [ jwtauthenticators, webhookauthenticators ]
|
|
||||||
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
|
|
||||||
|
|
||||||
#! Give minimal permissions to impersonation proxy service account
|
|
||||||
---
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: ClusterRole
|
|
||||||
metadata:
|
|
||||||
name: #@ defaultResourceNameWithSuffix("impersonation-proxy")
|
|
||||||
labels: #@ labels()
|
|
||||||
rules:
|
|
||||||
- apiGroups: [ "" ]
|
|
||||||
resources: [ "users", "groups", "serviceaccounts" ]
|
|
||||||
verbs: [ "impersonate" ]
|
|
||||||
- apiGroups: [ "authentication.k8s.io" ]
|
|
||||||
resources: [ "*" ] #! What we really want is userextras/* but the RBAC authorizer only supports */subresource, not resource/*
|
|
||||||
verbs: [ "impersonate" ]
|
|
||||||
---
|
|
||||||
kind: ClusterRoleBinding
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
metadata:
|
|
||||||
name: #@ defaultResourceNameWithSuffix("impersonation-proxy")
|
|
||||||
labels: #@ labels()
|
|
||||||
subjects:
|
|
||||||
- kind: ServiceAccount
|
|
||||||
name: #@ defaultResourceNameWithSuffix("impersonation-proxy")
|
|
||||||
namespace: #@ namespace()
|
|
||||||
roleRef:
|
|
||||||
kind: ClusterRole
|
|
||||||
name: #@ defaultResourceNameWithSuffix("impersonation-proxy")
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
||||||
|
|
||||||
#! Give permission to the kube-cert-agent Pod to run privileged.
|
|
||||||
---
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: Role
|
|
||||||
metadata:
|
|
||||||
name: #@ defaultResourceNameWithSuffix("kube-cert-agent")
|
|
||||||
namespace: #@ namespace()
|
|
||||||
labels: #@ labels()
|
|
||||||
rules:
|
|
||||||
- apiGroups: [ policy ]
|
|
||||||
resources: [ podsecuritypolicies ]
|
|
||||||
verbs: [ use ]
|
|
||||||
---
|
|
||||||
kind: RoleBinding
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
metadata:
|
|
||||||
name: #@ defaultResourceNameWithSuffix("kube-cert-agent")
|
|
||||||
namespace: #@ namespace()
|
|
||||||
labels: #@ labels()
|
|
||||||
subjects:
|
|
||||||
- kind: ServiceAccount
|
|
||||||
name: #@ defaultResourceNameWithSuffix("kube-cert-agent")
|
|
||||||
namespace: #@ namespace()
|
|
||||||
roleRef:
|
|
||||||
kind: Role
|
|
||||||
name: #@ defaultResourceNameWithSuffix("kube-cert-agent")
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
||||||
|
|
||||||
#! Give permission to various objects within the app's own namespace
|
|
||||||
---
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: Role
|
|
||||||
metadata:
|
|
||||||
name: #@ defaultResourceNameWithSuffix("aggregated-api-server")
|
|
||||||
namespace: #@ namespace()
|
|
||||||
labels: #@ labels()
|
|
||||||
rules:
|
|
||||||
- apiGroups: [ "" ]
|
|
||||||
resources: [ services ]
|
|
||||||
verbs: [ create, get, list, patch, update, watch, delete ]
|
|
||||||
- apiGroups: [ "" ]
|
|
||||||
resources: [ secrets ]
|
|
||||||
verbs: [ create, get, list, patch, update, watch, delete ]
|
|
||||||
#! We need to be able to watch pods in our namespace so we can find the kube-cert-agent pods.
|
|
||||||
- apiGroups: [ "" ]
|
|
||||||
resources: [ pods ]
|
|
||||||
verbs: [ get, list, watch ]
|
|
||||||
#! We need to be able to exec into pods in our namespace so we can grab the API server's private key
|
|
||||||
- apiGroups: [ "" ]
|
|
||||||
resources: [ pods/exec ]
|
|
||||||
verbs: [ create ]
|
|
||||||
#! We need to be able to delete pods in our namespace so we can clean up legacy kube-cert-agent pods.
|
|
||||||
- apiGroups: [ "" ]
|
|
||||||
resources: [ pods ]
|
|
||||||
verbs: [ delete ]
|
|
||||||
#! We need to be able to create and update deployments in our namespace so we can manage the kube-cert-agent Deployment.
|
|
||||||
- apiGroups: [ apps ]
|
|
||||||
resources: [ deployments ]
|
|
||||||
verbs: [ create, get, list, patch, update, watch, delete ]
|
|
||||||
#! We need to be able to get replicasets so we can form the correct owner references on our generated objects.
|
|
||||||
- apiGroups: [ apps ]
|
|
||||||
resources: [ replicasets ]
|
|
||||||
verbs: [ get ]
|
|
||||||
- apiGroups: [ "" ]
|
|
||||||
resources: [ configmaps ]
|
|
||||||
verbs: [ list, get, watch ]
|
|
||||||
- apiGroups: [ coordination.k8s.io ]
|
|
||||||
resources: [ leases ]
|
|
||||||
verbs: [ create, get, update ]
|
|
||||||
---
|
|
||||||
kind: RoleBinding
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
metadata:
|
|
||||||
name: #@ defaultResourceNameWithSuffix("aggregated-api-server")
|
|
||||||
namespace: #@ namespace()
|
|
||||||
labels: #@ labels()
|
|
||||||
subjects:
|
|
||||||
- kind: ServiceAccount
|
|
||||||
name: #@ defaultResourceName()
|
|
||||||
namespace: #@ namespace()
|
|
||||||
roleRef:
|
|
||||||
kind: Role
|
|
||||||
name: #@ defaultResourceNameWithSuffix("aggregated-api-server")
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
||||||
|
|
||||||
#! Give permission to read pods in the kube-system namespace so we can find the API server's private key
|
|
||||||
---
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: Role
|
|
||||||
metadata:
|
|
||||||
name: #@ defaultResourceNameWithSuffix("kube-system-pod-read")
|
|
||||||
namespace: kube-system
|
|
||||||
labels: #@ labels()
|
|
||||||
rules:
|
|
||||||
- apiGroups: [ "" ]
|
|
||||||
resources: [ pods ]
|
|
||||||
verbs: [ get, list, watch ]
|
|
||||||
---
|
|
||||||
kind: RoleBinding
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
metadata:
|
|
||||||
name: #@ defaultResourceNameWithSuffix("kube-system-pod-read")
|
|
||||||
namespace: kube-system
|
|
||||||
labels: #@ labels()
|
|
||||||
subjects:
|
|
||||||
- kind: ServiceAccount
|
|
||||||
name: #@ defaultResourceName()
|
|
||||||
namespace: #@ namespace()
|
|
||||||
roleRef:
|
|
||||||
kind: Role
|
|
||||||
name: #@ defaultResourceNameWithSuffix("kube-system-pod-read")
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
||||||
|
|
||||||
#! Allow both authenticated and unauthenticated TokenCredentialRequests (i.e. allow all requests)
|
|
||||||
---
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: ClusterRole
|
|
||||||
metadata:
|
|
||||||
name: #@ defaultResourceNameWithSuffix("pre-authn-apis")
|
|
||||||
labels: #@ labels()
|
|
||||||
rules:
|
|
||||||
- apiGroups:
|
|
||||||
- #@ pinnipedDevAPIGroupWithPrefix("login.concierge")
|
|
||||||
resources: [ tokencredentialrequests ]
|
|
||||||
verbs: [ create, list ]
|
|
||||||
- apiGroups:
|
|
||||||
- #@ pinnipedDevAPIGroupWithPrefix("identity.concierge")
|
|
||||||
resources: [ whoamirequests ]
|
|
||||||
verbs: [ create, list ]
|
|
||||||
---
|
|
||||||
kind: ClusterRoleBinding
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
metadata:
|
|
||||||
name: #@ defaultResourceNameWithSuffix("pre-authn-apis")
|
|
||||||
labels: #@ labels()
|
|
||||||
subjects:
|
|
||||||
- kind: Group
|
|
||||||
name: system:authenticated
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
||||||
- kind: Group
|
|
||||||
name: system:unauthenticated
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
||||||
roleRef:
|
|
||||||
kind: ClusterRole
|
|
||||||
name: #@ defaultResourceNameWithSuffix("pre-authn-apis")
|
|
||||||
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 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 permission to list and watch ConfigMaps in kube-public
|
|
||||||
---
|
|
||||||
kind: Role
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
metadata:
|
|
||||||
name: #@ defaultResourceNameWithSuffix("cluster-info-lister-watcher")
|
|
||||||
namespace: kube-public
|
|
||||||
labels: #@ labels()
|
|
||||||
rules:
|
|
||||||
- apiGroups: [ "" ]
|
|
||||||
resources: [ configmaps ]
|
|
||||||
verbs: [ list, watch ]
|
|
||||||
---
|
|
||||||
kind: RoleBinding
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
metadata:
|
|
||||||
name: #@ defaultResourceNameWithSuffix("cluster-info-lister-watcher")
|
|
||||||
namespace: kube-public
|
|
||||||
labels: #@ labels()
|
|
||||||
subjects:
|
|
||||||
- kind: ServiceAccount
|
|
||||||
name: #@ defaultResourceName()
|
|
||||||
namespace: #@ namespace()
|
|
||||||
roleRef:
|
|
||||||
kind: Role
|
|
||||||
name: #@ defaultResourceNameWithSuffix("cluster-info-lister-watcher")
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
@ -1,137 +0,0 @@
|
|||||||
#! Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
|
||||||
#! SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
#@data/values-schema
|
|
||||||
---
|
|
||||||
#@schema/desc "Name of pinniped-concierge."
|
|
||||||
app_name: pinniped-concierge
|
|
||||||
|
|
||||||
#@schema/desc "Creates a new namespace statically in yaml with the given name and installs the app into that namespace."
|
|
||||||
namespace: pinniped-concierge
|
|
||||||
#@ into_namespace_desc = "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."
|
|
||||||
#@schema/desc into_namespace_desc
|
|
||||||
#@schema/nullable
|
|
||||||
into_namespace: my-preexisting-namespace
|
|
||||||
|
|
||||||
#@ custom_labels_desc = "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."
|
|
||||||
#@schema/desc custom_labels_desc
|
|
||||||
#@schema/type any=True
|
|
||||||
custom_labels: {} #! {myCustomLabelName: myCustomLabelValue, otherCustomLabelName: otherCustomLabelValue}
|
|
||||||
|
|
||||||
#@schema/desc "Specify how many replicas of the Pinniped server to run."
|
|
||||||
replicas: 2
|
|
||||||
|
|
||||||
#@schema/desc "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
|
|
||||||
#@schema/desc "Specify either an image_digest or an image_tag. If both are given, only image_digest will be used."
|
|
||||||
#@schema/nullable
|
|
||||||
image_digest: sha256:f3c4fdfd3ef865d4b97a1fd295d94acc3f0c654c46b6f27ffad5cf80216903c8
|
|
||||||
#@schema/desc "Specify either an image_digest or an image_tag. If both are given, only image_digest will be used."
|
|
||||||
image_tag: latest
|
|
||||||
|
|
||||||
#@ kube_cert_agent_image = "Optionally specify a different image for the 'kube-cert-agent' pod which is scheduled \
|
|
||||||
#@ on the control plane. This image needs only to include `sleep` and `cat` binaries. \
|
|
||||||
#@ By default, the same image specified for image_repo/image_digest/image_tag will be re-used."
|
|
||||||
#@schema/desc kube_cert_agent_image
|
|
||||||
#@schema/nullable
|
|
||||||
kube_cert_agent_image: projects.registry.vmware.com/pinniped/pinniped-server
|
|
||||||
|
|
||||||
#@ image_pull_dockerconfigjson_desc = "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."
|
|
||||||
#@schema/desc image_pull_dockerconfigjson_desc
|
|
||||||
#@schema/nullable
|
|
||||||
image_pull_dockerconfigjson: {"auths":{"https://registry.example.com":{"username":"USERNAME","password":"PASSWORD","auth":"BASE64_ENCODED_USERNAME_COLON_PASSWORD"}}}
|
|
||||||
|
|
||||||
#@schema/desc "Pinniped will try to guess the right K8s API URL for sharing that information with potential clients. This setting allows the guess to be overridden."
|
|
||||||
#@schema/nullable
|
|
||||||
discovery_url: https://example.com
|
|
||||||
|
|
||||||
|
|
||||||
#@ api_serving_certificate_desc = "Specify the duration and renewal interval for the API serving certificate. \
|
|
||||||
#@ The defaults are set to expire the cert about every 30 days, and to rotate it \
|
|
||||||
#@ about every 25 days."
|
|
||||||
#@schema/desc api_serving_certificate_desc
|
|
||||||
api_serving_certificate_duration_seconds: 2592000
|
|
||||||
#@schema/desc api_serving_certificate_desc
|
|
||||||
api_serving_certificate_renew_before_seconds: 2160000
|
|
||||||
|
|
||||||
#! 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.
|
|
||||||
#@schema/desc "default, when this value is left unset, only warnings and errors are printed. There is no way to suppress warning and error logs."
|
|
||||||
#@schema/nullable
|
|
||||||
log_level: info
|
|
||||||
#@ deprecated_log_format_desc = "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."
|
|
||||||
#@schema/desc deprecated_log_format_desc
|
|
||||||
#@schema/nullable
|
|
||||||
deprecated_log_format: json
|
|
||||||
|
|
||||||
#@schema/desc "run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice"
|
|
||||||
run_as_user: 65532
|
|
||||||
#@schema/desc "run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice"
|
|
||||||
run_as_group: 65532
|
|
||||||
|
|
||||||
#@ api_group_suffix_desc = "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."
|
|
||||||
#@schema/desc api_group_suffix_desc
|
|
||||||
api_group_suffix: pinniped.dev
|
|
||||||
|
|
||||||
|
|
||||||
#@schema/desc "Customize CredentialIssuer.spec.impersonationProxy to change how the concierge handles impersonation."
|
|
||||||
impersonation_proxy_spec:
|
|
||||||
#! options are "auto", "disabled" or "enabled".
|
|
||||||
#! If auto, the impersonation proxy will run only if the cluster signing key is not available
|
|
||||||
#! and the other strategy does not work.
|
|
||||||
#! If disabled, the impersonation proxy will never run, which could mean that the concierge
|
|
||||||
#! doesn't work at all.
|
|
||||||
#! If enabled, the impersonation proxy will always run regardless of other strategies available.
|
|
||||||
#@schema/desc "If enabled, the impersonation proxy will always run regardless of other strategies available."
|
|
||||||
mode: auto
|
|
||||||
#@ external_endpoint_desc = "The endpoint which the client should use to connect to the impersonation proxy. \
|
|
||||||
#@ If left unset, the client will default to connecting based on the ClusterIP or LoadBalancer endpoint."
|
|
||||||
#@schema/desc external_endpoint_desc
|
|
||||||
#@schema/nullable
|
|
||||||
external_endpoint: 1.2.3.4:5678
|
|
||||||
#@schema/desc "The impersonation proxy service configuration"
|
|
||||||
service:
|
|
||||||
#! Options are "LoadBalancer", "ClusterIP" and "None".
|
|
||||||
#! LoadBalancer automatically provisions a Service of type LoadBalancer pointing at
|
|
||||||
#! the impersonation proxy. Some cloud providers will allocate
|
|
||||||
#! a public IP address by default even on private clusters.
|
|
||||||
#! ClusterIP automatically provisions a Service of type ClusterIP pointing at the
|
|
||||||
#! impersonation proxy.
|
|
||||||
#! None does not provision either and assumes that you have set the external_endpoint
|
|
||||||
#! and set up your own ingress to connect to the impersonation proxy.
|
|
||||||
#@schema/desc "Options are 'LoadBalancer', 'ClusterIP' and 'None'."
|
|
||||||
#@schema/nullable
|
|
||||||
type: LoadBalancer
|
|
||||||
#@schema/desc "The annotations that should be set on the ClusterIP or LoadBalancer Service."
|
|
||||||
#@schema/nullable
|
|
||||||
annotations:
|
|
||||||
{service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: "4000"}
|
|
||||||
#@schema/desc "When mode LoadBalancer is set, this will set the LoadBalancer Service's Spec.LoadBalancerIP."
|
|
||||||
#@schema/nullable
|
|
||||||
load_balancer_ip: 1.2.3.4:5678
|
|
||||||
|
|
||||||
#@ https_proxy_desc = "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."
|
|
||||||
#@schema/desc https_proxy_desc
|
|
||||||
#@schema/nullable
|
|
||||||
https_proxy: http://proxy.example.com
|
|
||||||
#@schema/desc "do not proxy Kubernetes endpoints"
|
|
||||||
no_proxy: "$(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.cluster.local" #! do not proxy Kubernetes endpoints
|
|
@ -1,33 +0,0 @@
|
|||||||
#! Copyright 2020-2021 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":"credentialissuers.config.concierge.pinniped.dev"}}), expects=1
|
|
||||||
---
|
|
||||||
metadata:
|
|
||||||
#@overlay/match missing_ok=True
|
|
||||||
labels: #@ labels()
|
|
||||||
name: #@ pinnipedDevAPIGroupWithPrefix("credentialissuers.config.concierge")
|
|
||||||
spec:
|
|
||||||
group: #@ pinnipedDevAPIGroupWithPrefix("config.concierge")
|
|
||||||
|
|
||||||
#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"webhookauthenticators.authentication.concierge.pinniped.dev"}}), expects=1
|
|
||||||
---
|
|
||||||
metadata:
|
|
||||||
#@overlay/match missing_ok=True
|
|
||||||
labels: #@ labels()
|
|
||||||
name: #@ pinnipedDevAPIGroupWithPrefix("webhookauthenticators.authentication.concierge")
|
|
||||||
spec:
|
|
||||||
group: #@ pinnipedDevAPIGroupWithPrefix("authentication.concierge")
|
|
||||||
|
|
||||||
#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"jwtauthenticators.authentication.concierge.pinniped.dev"}}), expects=1
|
|
||||||
---
|
|
||||||
metadata:
|
|
||||||
#@overlay/match missing_ok=True
|
|
||||||
labels: #@ labels()
|
|
||||||
name: #@ pinnipedDevAPIGroupWithPrefix("jwtauthenticators.authentication.concierge")
|
|
||||||
spec:
|
|
||||||
group: #@ pinnipedDevAPIGroupWithPrefix("authentication.concierge")
|
|
7
deploy_carvel/concierge/vendir.lock.yml
Normal file
7
deploy_carvel/concierge/vendir.lock.yml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
apiVersion: vendir.k14s.io/v1alpha1
|
||||||
|
directories:
|
||||||
|
- contents:
|
||||||
|
- directory: {}
|
||||||
|
path: .
|
||||||
|
path: config
|
||||||
|
kind: LockConfig
|
8
deploy_carvel/concierge/vendir.yml
Normal file
8
deploy_carvel/concierge/vendir.yml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
apiVersion: vendir.k14s.io/v1alpha1
|
||||||
|
kind: Config
|
||||||
|
directories:
|
||||||
|
- path: config
|
||||||
|
contents:
|
||||||
|
- path: .
|
||||||
|
directory:
|
||||||
|
path: ../../deploy/concierge
|
1
deploy_carvel/local-user-authenticator/.gitignore
vendored
Normal file
1
deploy_carvel/local-user-authenticator/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
config/
|
@ -1,163 +0,0 @@
|
|||||||
# Deploying local-user-authenticator
|
|
||||||
|
|
||||||
## What is local-user-authenticator?
|
|
||||||
|
|
||||||
The local-user-authenticator app is an identity provider used for integration testing and demos.
|
|
||||||
If you would like to demo Pinniped, but you don't have a compatible identity provider handy,
|
|
||||||
you can use Pinniped's local-user-authenticator identity provider. Note that this is not recommended for
|
|
||||||
production use.
|
|
||||||
|
|
||||||
The local-user-authenticator is a Kubernetes Deployment which runs a webhook server that implements the Kubernetes
|
|
||||||
[Webhook Token Authentication interface](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#webhook-token-authentication).
|
|
||||||
|
|
||||||
User accounts can be created and edited dynamically using `kubectl` commands (see below).
|
|
||||||
|
|
||||||
## Installing the Latest Version with Default Options
|
|
||||||
|
|
||||||
```bash
|
|
||||||
kubectl apply -f https://get.pinniped.dev/latest/install-local-user-authenticator.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
## Installing a Specific Version with Default Options
|
|
||||||
|
|
||||||
Choose your preferred [release](https://github.com/vmware-tanzu/pinniped/releases) version number
|
|
||||||
and use it to replace the version number in the URL below.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Replace v0.4.1 with your preferred version in the URL below
|
|
||||||
kubectl apply -f https://get.pinniped.dev/v0.4.1/install-local-user-authenticator.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
## Installing with Custom Options
|
|
||||||
|
|
||||||
Creating your own deployment YAML file requires `ytt` from [Carvel](https://carvel.dev/) to template the YAML files
|
|
||||||
in the `deploy/local-user-authenticator` directory.
|
|
||||||
Either [install `ytt`](https://get-ytt.io/) or use the [container image from Dockerhub](https://hub.docker.com/r/k14s/image/tags).
|
|
||||||
|
|
||||||
1. `git clone` this repo and `git checkout` the release version tag of the release that you would like to deploy.
|
|
||||||
1. The configuration options are in [deploy/local-user-authenticator/values.yml](values.yaml).
|
|
||||||
Fill in the values in that file, or override those values using additional `ytt` command-line options in
|
|
||||||
the command below. Use the release version tag as the `image_tag` value.
|
|
||||||
2. In a terminal, cd to this `deploy/local-user-authenticator` directory
|
|
||||||
3. To generate the final YAML files, run `ytt --file .`
|
|
||||||
4. Deploy the generated YAML using your preferred deployment tool, such as `kubectl` or [`kapp`](https://get-kapp.io/).
|
|
||||||
For example: `ytt --file . | kapp deploy --yes --app local-user-authenticator --diff-changes --file -`
|
|
||||||
|
|
||||||
## Configuring After Installing
|
|
||||||
|
|
||||||
### Create Users
|
|
||||||
|
|
||||||
Use `kubectl` to create, edit, and delete user accounts by creating a `Secret` for each user account in the same
|
|
||||||
namespace where local-user-authenticator is deployed. The name of the `Secret` resource is the username.
|
|
||||||
Store the user's group membership and `bcrypt` encrypted password as the contents of the `Secret`.
|
|
||||||
For example, to create a user named `pinny-the-seal` with the password `password123`
|
|
||||||
who belongs to the groups `group1` and `group2`, use:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
kubectl create secret generic pinny-the-seal \
|
|
||||||
--namespace local-user-authenticator \
|
|
||||||
--from-literal=groups=group1,group2 \
|
|
||||||
--from-literal=passwordHash=$(htpasswd -nbBC 10 x password123 | sed -e "s/^x://")
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that the above command requires a tool capable of generating a `bcrypt` hash. It uses `htpasswd`,
|
|
||||||
which is installed on most macOS systems, and can be
|
|
||||||
installed on some Linux systems via the `apache2-utils` package (e.g., `apt-get install apache2-utils`).
|
|
||||||
|
|
||||||
### Get the local-user-authenticator App's Auto-Generated Certificate Authority Bundle
|
|
||||||
|
|
||||||
Fetch the auto-generated CA bundle for the local-user-authenticator's HTTP TLS endpoint.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
kubectl get secret local-user-authenticator-tls-serving-certificate --namespace local-user-authenticator \
|
|
||||||
-o jsonpath={.data.caCertificate} \
|
|
||||||
| base64 -d \
|
|
||||||
| tee /tmp/local-user-authenticator-ca
|
|
||||||
```
|
|
||||||
|
|
||||||
### Configuring Pinniped to Use local-user-authenticator as an Identity Provider
|
|
||||||
|
|
||||||
When installing Pinniped on the same cluster, configure local-user-authenticator as an Identity Provider for Pinniped
|
|
||||||
using the webhook URL `https://local-user-authenticator.local-user-authenticator.svc/authenticate`
|
|
||||||
along with the CA bundle fetched by the above command. See [demo](https://pinniped.dev/docs/demo/) for an example.
|
|
||||||
|
|
||||||
## Optional: Manually Testing the Webhook Endpoint After Installing
|
|
||||||
|
|
||||||
The following steps demonstrate the API of the local-user-authenticator app. Typically, a user would not need to
|
|
||||||
interact with this API directly. Pinniped will automatically integrate with this API if the local-user-authenticator
|
|
||||||
is configured as an identity provider for Pinniped.
|
|
||||||
|
|
||||||
1. Start a pod from which you can curl the endpoint from inside the cluster.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
kubectl run curlpod --image=curlimages/curl --command -- /bin/sh -c "while true; do echo hi; sleep 120; done"
|
|
||||||
```
|
|
||||||
|
|
||||||
1. Copy the CA bundle that was fetched above onto the new pod.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
kubectl cp /tmp/local-user-authenticator-ca curlpod:/tmp/local-user-authenticator-ca
|
|
||||||
```
|
|
||||||
|
|
||||||
1. Run a `curl` command to try to authenticate as the user created above.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
kubectl -it exec curlpod -- curl https://local-user-authenticator.local-user-authenticator.svc/authenticate \
|
|
||||||
--cacert /tmp/local-user-authenticator-ca \
|
|
||||||
-H 'Content-Type: application/json' -H 'Accept: application/json' -d '
|
|
||||||
{
|
|
||||||
"apiVersion": "authentication.k8s.io/v1beta1",
|
|
||||||
"kind": "TokenReview",
|
|
||||||
"spec": {
|
|
||||||
"token": "pinny-the-seal:password123"
|
|
||||||
}
|
|
||||||
}'
|
|
||||||
```
|
|
||||||
|
|
||||||
When authentication is successful the above command should return some JSON similar to the following.
|
|
||||||
Note that the value of `authenticated` is `true` to indicate a successful authentication.
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"kind": "TokenReview",
|
|
||||||
"apiVersion": "authentication.k8s.io/v1beta1",
|
|
||||||
"metadata": {
|
|
||||||
"creationTimestamp": null
|
|
||||||
},
|
|
||||||
"spec": {},
|
|
||||||
"status": {
|
|
||||||
"authenticated": true,
|
|
||||||
"user": {
|
|
||||||
"username": "pinny-the-seal",
|
|
||||||
"uid": "19c433ec-8f58-44ca-9ef0-2d1081ccb876",
|
|
||||||
"groups": [
|
|
||||||
"group1",
|
|
||||||
"group2"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Trying the above `curl` command again with the wrong username or password in the body of the request
|
|
||||||
should result in a JSON response which indicates that the authentication failed.
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"kind": "TokenReview",
|
|
||||||
"apiVersion": "authentication.k8s.io/v1beta1",
|
|
||||||
"metadata": {
|
|
||||||
"creationTimestamp": null
|
|
||||||
},
|
|
||||||
"spec": {},
|
|
||||||
"status": {
|
|
||||||
"user": {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
1. Remove the curl pod.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
kubectl delete pod curlpod
|
|
||||||
```
|
|
@ -1,97 +0,0 @@
|
|||||||
#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
|
||||||
#! SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
#@ load("@ytt:data", "data")
|
|
||||||
|
|
||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Namespace
|
|
||||||
metadata:
|
|
||||||
name: local-user-authenticator
|
|
||||||
labels:
|
|
||||||
name: local-user-authenticator
|
|
||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: ServiceAccount
|
|
||||||
metadata:
|
|
||||||
name: local-user-authenticator
|
|
||||||
namespace: local-user-authenticator
|
|
||||||
---
|
|
||||||
#@ if data.values.image_pull_dockerconfigjson and data.values.image_pull_dockerconfigjson != "":
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Secret
|
|
||||||
metadata:
|
|
||||||
name: image-pull-secret
|
|
||||||
namespace: local-user-authenticator
|
|
||||||
labels:
|
|
||||||
app: local-user-authenticator
|
|
||||||
type: kubernetes.io/dockerconfigjson
|
|
||||||
data:
|
|
||||||
.dockerconfigjson: #@ data.values.image_pull_dockerconfigjson
|
|
||||||
#@ end
|
|
||||||
---
|
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: local-user-authenticator
|
|
||||||
namespace: local-user-authenticator
|
|
||||||
labels:
|
|
||||||
app: local-user-authenticator
|
|
||||||
spec:
|
|
||||||
replicas: 1
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: local-user-authenticator
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: local-user-authenticator
|
|
||||||
spec:
|
|
||||||
securityContext:
|
|
||||||
runAsUser: #@ data.values.run_as_user
|
|
||||||
runAsGroup: #@ data.values.run_as_group
|
|
||||||
serviceAccountName: local-user-authenticator
|
|
||||||
#@ if data.values.image_pull_dockerconfigjson and data.values.image_pull_dockerconfigjson != "":
|
|
||||||
imagePullSecrets:
|
|
||||||
- name: image-pull-secret
|
|
||||||
#@ end
|
|
||||||
containers:
|
|
||||||
- name: local-user-authenticator
|
|
||||||
#@ if data.values.image_digest:
|
|
||||||
image: #@ data.values.image_repo + "@" + data.values.image_digest
|
|
||||||
#@ else:
|
|
||||||
image: #@ data.values.image_repo + ":" + data.values.image_tag
|
|
||||||
#@ end
|
|
||||||
imagePullPolicy: IfNotPresent
|
|
||||||
command:
|
|
||||||
- local-user-authenticator
|
|
||||||
securityContext:
|
|
||||||
readOnlyRootFilesystem: true
|
|
||||||
runAsNonRoot: true
|
|
||||||
allowPrivilegeEscalation: false
|
|
||||||
capabilities:
|
|
||||||
drop: [ "ALL" ]
|
|
||||||
#! seccompProfile was introduced in Kube v1.19. Using it on an older Kube version will result in a
|
|
||||||
#! kubectl validation error when installing via `kubectl apply`, which can be ignored using kubectl's
|
|
||||||
#! `--validate=false` flag. Note that installing via `kapp` does not complain about this validation error.
|
|
||||||
seccompProfile:
|
|
||||||
type: "RuntimeDefault"
|
|
||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: local-user-authenticator
|
|
||||||
namespace: local-user-authenticator
|
|
||||||
labels:
|
|
||||||
app: local-user-authenticator
|
|
||||||
#! 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:
|
|
||||||
app: local-user-authenticator
|
|
||||||
ports:
|
|
||||||
- protocol: TCP
|
|
||||||
port: 443
|
|
||||||
targetPort: 8443
|
|
@ -1,30 +0,0 @@
|
|||||||
#! Copyright 2020 the Pinniped contributors. All Rights Reserved.
|
|
||||||
#! SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
#@ load("@ytt:data", "data")
|
|
||||||
|
|
||||||
#! Give permission to various objects within the app's own namespace
|
|
||||||
---
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: Role
|
|
||||||
metadata:
|
|
||||||
name: local-user-authenticator
|
|
||||||
namespace: local-user-authenticator
|
|
||||||
rules:
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources: [secrets]
|
|
||||||
verbs: [create, get, list, patch, update, watch]
|
|
||||||
---
|
|
||||||
kind: RoleBinding
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
metadata:
|
|
||||||
name: local-user-authenticator
|
|
||||||
namespace: local-user-authenticator
|
|
||||||
subjects:
|
|
||||||
- kind: ServiceAccount
|
|
||||||
name: local-user-authenticator
|
|
||||||
namespace: local-user-authenticator
|
|
||||||
roleRef:
|
|
||||||
kind: Role
|
|
||||||
name: local-user-authenticator
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
@ -1,26 +0,0 @@
|
|||||||
#! Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
|
||||||
#! SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
#@data/values-schema
|
|
||||||
---
|
|
||||||
|
|
||||||
#@schema/desc "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
|
|
||||||
#@schema/desc "Specify either an image_digest or an image_tag. If both are given, only image_digest will be used."
|
|
||||||
#@schema/nullable
|
|
||||||
image_digest: sha256:f3c4fdfd3ef865d4b97a1fd295d94acc3f0c654c46b6f27ffad5cf80216903c8
|
|
||||||
#@schema/desc "Specify either an image_digest or an image_tag. If both are given, only image_digest will be used."
|
|
||||||
image_tag: latest
|
|
||||||
|
|
||||||
#@ image_pull_dockerconfigjson_desc = "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."
|
|
||||||
#@schema/desc image_pull_dockerconfigjson_desc
|
|
||||||
#@schema/nullable
|
|
||||||
image_pull_dockerconfigjson: {"auths":{"https://registry.example.com":{"username":"USERNAME","password":"PASSWORD","auth":"BASE64_ENCODED_USERNAME_COLON_PASSWORD"}}}
|
|
||||||
|
|
||||||
#@schema/desc "run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice"
|
|
||||||
run_as_user: 65532
|
|
||||||
#@schema/desc "run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice"
|
|
||||||
run_as_group: 65532
|
|
7
deploy_carvel/local-user-authenticator/vendir.lock.yml
Normal file
7
deploy_carvel/local-user-authenticator/vendir.lock.yml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
apiVersion: vendir.k14s.io/v1alpha1
|
||||||
|
directories:
|
||||||
|
- contents:
|
||||||
|
- directory: {}
|
||||||
|
path: .
|
||||||
|
path: config
|
||||||
|
kind: LockConfig
|
8
deploy_carvel/local-user-authenticator/vendir.yml
Normal file
8
deploy_carvel/local-user-authenticator/vendir.yml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
apiVersion: vendir.k14s.io/v1alpha1
|
||||||
|
kind: Config
|
||||||
|
directories:
|
||||||
|
- path: config
|
||||||
|
contents:
|
||||||
|
- path: .
|
||||||
|
directory:
|
||||||
|
path: ../../deploy/local-user-authenticator
|
1
deploy_carvel/supervisor/.gitignore
vendored
Normal file
1
deploy_carvel/supervisor/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
config/
|
@ -1,3 +0,0 @@
|
|||||||
# Pinniped Supervisor Deployment
|
|
||||||
|
|
||||||
See [the how-to guide for details](https://pinniped.dev/docs/howto/install-supervisor/).
|
|
@ -1,488 +0,0 @@
|
|||||||
---
|
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
|
||||||
kind: CustomResourceDefinition
|
|
||||||
metadata:
|
|
||||||
annotations:
|
|
||||||
controller-gen.kubebuilder.io/version: v0.13.0
|
|
||||||
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.phase
|
|
||||||
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:
|
|
||||||
identityProviders:
|
|
||||||
description: "IdentityProviders is the list of identity providers
|
|
||||||
available for use by this FederationDomain. \n An identity provider
|
|
||||||
CR (e.g. OIDCIdentityProvider or LDAPIdentityProvider) describes
|
|
||||||
how to connect to a server, how to talk in a specific protocol for
|
|
||||||
authentication, and how to use the schema of that server/protocol
|
|
||||||
to extract a normalized user identity. Normalized user identities
|
|
||||||
include a username and a list of group names. In contrast, IdentityProviders
|
|
||||||
describes how to use that normalized identity in those Kubernetes
|
|
||||||
clusters which belong to this FederationDomain. Each entry in IdentityProviders
|
|
||||||
can be configured with arbitrary transformations on that normalized
|
|
||||||
identity. For example, a transformation can add a prefix to all
|
|
||||||
usernames to help avoid accidental conflicts when multiple identity
|
|
||||||
providers have different users with the same username (e.g. \"idp1:ryan\"
|
|
||||||
versus \"idp2:ryan\"). Each entry in IdentityProviders can also
|
|
||||||
implement arbitrary authentication rejection policies. Even though
|
|
||||||
a user was able to authenticate with the identity provider, a policy
|
|
||||||
can disallow the authentication to the Kubernetes clusters that
|
|
||||||
belong to this FederationDomain. For example, a policy could disallow
|
|
||||||
the authentication unless the user belongs to a specific group in
|
|
||||||
the identity provider. \n For backwards compatibility with versions
|
|
||||||
of Pinniped which predate support for multiple identity providers,
|
|
||||||
an empty IdentityProviders list will cause the FederationDomain
|
|
||||||
to use all available identity providers which exist in the same
|
|
||||||
namespace, but also to reject all authentication requests when there
|
|
||||||
is more than one identity provider currently defined. In this backwards
|
|
||||||
compatibility mode, the name of the identity provider resource (e.g.
|
|
||||||
the Name of an OIDCIdentityProvider resource) will be used as the
|
|
||||||
name of the identity provider in this FederationDomain. This mode
|
|
||||||
is provided to make upgrading from older versions easier. However,
|
|
||||||
instead of relying on this backwards compatibility mode, please
|
|
||||||
consider this mode to be deprecated and please instead explicitly
|
|
||||||
list the identity provider using this IdentityProviders field."
|
|
||||||
items:
|
|
||||||
description: FederationDomainIdentityProvider describes how an identity
|
|
||||||
provider is made available in this FederationDomain.
|
|
||||||
properties:
|
|
||||||
displayName:
|
|
||||||
description: DisplayName is the name of this identity provider
|
|
||||||
as it will appear to clients. This name ends up in the kubeconfig
|
|
||||||
of end users, so changing the name of an identity provider
|
|
||||||
that is in use by end users will be a disruptive change for
|
|
||||||
those users.
|
|
||||||
minLength: 1
|
|
||||||
type: string
|
|
||||||
objectRef:
|
|
||||||
description: ObjectRef is a reference to a Pinniped identity
|
|
||||||
provider resource. A valid reference is required. If the reference
|
|
||||||
cannot be resolved then the identity provider will not be
|
|
||||||
made available. Must refer to a resource of one of the Pinniped
|
|
||||||
identity provider types, e.g. OIDCIdentityProvider, LDAPIdentityProvider,
|
|
||||||
ActiveDirectoryIdentityProvider.
|
|
||||||
properties:
|
|
||||||
apiGroup:
|
|
||||||
description: APIGroup is the group for the resource being
|
|
||||||
referenced. If APIGroup is not specified, the specified
|
|
||||||
Kind must be in the core API group. For any other third-party
|
|
||||||
types, APIGroup is required.
|
|
||||||
type: string
|
|
||||||
kind:
|
|
||||||
description: Kind is the type of resource being referenced
|
|
||||||
type: string
|
|
||||||
name:
|
|
||||||
description: Name is the name of resource being referenced
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- kind
|
|
||||||
- name
|
|
||||||
type: object
|
|
||||||
x-kubernetes-map-type: atomic
|
|
||||||
transforms:
|
|
||||||
description: Transforms is an optional way to specify transformations
|
|
||||||
to be applied during user authentication and session refresh.
|
|
||||||
properties:
|
|
||||||
constants:
|
|
||||||
description: Constants defines constant variables and their
|
|
||||||
values which will be made available to the transform expressions.
|
|
||||||
items:
|
|
||||||
description: FederationDomainTransformsConstant defines
|
|
||||||
a constant variable and its value which will be made
|
|
||||||
available to the transform expressions. This is a union
|
|
||||||
type, and Type is the discriminator field.
|
|
||||||
properties:
|
|
||||||
name:
|
|
||||||
description: Name determines the name of the constant.
|
|
||||||
It must be a valid identifier name.
|
|
||||||
maxLength: 64
|
|
||||||
minLength: 1
|
|
||||||
pattern: ^[a-zA-Z][_a-zA-Z0-9]*$
|
|
||||||
type: string
|
|
||||||
stringListValue:
|
|
||||||
description: StringListValue should hold the value
|
|
||||||
when Type is "stringList", and is otherwise ignored.
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
type: array
|
|
||||||
stringValue:
|
|
||||||
description: StringValue should hold the value when
|
|
||||||
Type is "string", and is otherwise ignored.
|
|
||||||
type: string
|
|
||||||
type:
|
|
||||||
description: Type determines the type of the constant,
|
|
||||||
and indicates which other field should be non-empty.
|
|
||||||
enum:
|
|
||||||
- string
|
|
||||||
- stringList
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- name
|
|
||||||
- type
|
|
||||||
type: object
|
|
||||||
type: array
|
|
||||||
x-kubernetes-list-map-keys:
|
|
||||||
- name
|
|
||||||
x-kubernetes-list-type: map
|
|
||||||
examples:
|
|
||||||
description: Examples can optionally be used to ensure that
|
|
||||||
the sequence of transformation expressions are working
|
|
||||||
as expected. Examples define sample input identities which
|
|
||||||
are then run through the expression list, and the results
|
|
||||||
are compared to the expected results. If any example in
|
|
||||||
this list fails, then this identity provider will not
|
|
||||||
be available for use within this FederationDomain, and
|
|
||||||
the error(s) will be added to the FederationDomain status.
|
|
||||||
This can be used to help guard against programming mistakes
|
|
||||||
in the expressions, and also act as living documentation
|
|
||||||
for other administrators to better understand the expressions.
|
|
||||||
items:
|
|
||||||
description: FederationDomainTransformsExample defines
|
|
||||||
a transform example.
|
|
||||||
properties:
|
|
||||||
expects:
|
|
||||||
description: Expects is the expected output of the
|
|
||||||
entire sequence of transforms when they are run
|
|
||||||
against the input Username and Groups.
|
|
||||||
properties:
|
|
||||||
groups:
|
|
||||||
description: Groups is the expected list of group
|
|
||||||
names after the transformations have been applied.
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
type: array
|
|
||||||
message:
|
|
||||||
description: Message is the expected error message
|
|
||||||
of the transforms. When Rejected is true, then
|
|
||||||
Message is the expected message for the policy
|
|
||||||
which rejected the authentication attempt. When
|
|
||||||
Rejected is true and Message is blank, then
|
|
||||||
Message will be treated as the default error
|
|
||||||
message for authentication attempts which are
|
|
||||||
rejected by a policy. When Rejected is false,
|
|
||||||
then Message is the expected error message for
|
|
||||||
some other non-policy transformation error,
|
|
||||||
such as a runtime error. When Rejected is false,
|
|
||||||
there is no default expected Message.
|
|
||||||
type: string
|
|
||||||
rejected:
|
|
||||||
description: Rejected is a boolean that indicates
|
|
||||||
whether authentication is expected to be rejected
|
|
||||||
by a policy expression after the transformations
|
|
||||||
have been applied. True means that it is expected
|
|
||||||
that the authentication would be rejected. The
|
|
||||||
default value of false means that it is expected
|
|
||||||
that the authentication would not be rejected
|
|
||||||
by any policy expression.
|
|
||||||
type: boolean
|
|
||||||
username:
|
|
||||||
description: Username is the expected username
|
|
||||||
after the transformations have been applied.
|
|
||||||
type: string
|
|
||||||
type: object
|
|
||||||
groups:
|
|
||||||
description: Groups is the input list of group names.
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
type: array
|
|
||||||
username:
|
|
||||||
description: Username is the input username.
|
|
||||||
minLength: 1
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- expects
|
|
||||||
- username
|
|
||||||
type: object
|
|
||||||
type: array
|
|
||||||
expressions:
|
|
||||||
description: "Expressions are an optional list of transforms
|
|
||||||
and policies to be executed in the order given during
|
|
||||||
every authentication attempt, including during every session
|
|
||||||
refresh. Each is a CEL expression. It may use the basic
|
|
||||||
CEL language as defined in https://github.com/google/cel-spec/blob/master/doc/langdef.md
|
|
||||||
plus the CEL string extensions defined in https://github.com/google/cel-go/tree/master/ext#strings.
|
|
||||||
\n The username and groups extracted from the identity
|
|
||||||
provider, and the constants defined in this CR, are available
|
|
||||||
as variables in all expressions. The username is provided
|
|
||||||
via a variable called `username` and the list of group
|
|
||||||
names is provided via a variable called `groups` (which
|
|
||||||
may be an empty list). Each user-provided constants is
|
|
||||||
provided via a variable named `strConst.varName` for string
|
|
||||||
constants and `strListConst.varName` for string list constants.
|
|
||||||
\n The only allowed types for expressions are currently
|
|
||||||
policy/v1, username/v1, and groups/v1. Each policy/v1
|
|
||||||
must return a boolean, and when it returns false, no more
|
|
||||||
expressions from the list are evaluated and the authentication
|
|
||||||
attempt is rejected. Transformations of type policy/v1
|
|
||||||
do not return usernames or group names, and therefore
|
|
||||||
cannot change the username or group names. Each username/v1
|
|
||||||
transform must return the new username (a string), which
|
|
||||||
can be the same as the old username. Transformations of
|
|
||||||
type username/v1 do not return group names, and therefore
|
|
||||||
cannot change the group names. Each groups/v1 transform
|
|
||||||
must return the new groups list (list of strings), which
|
|
||||||
can be the same as the old groups list. Transformations
|
|
||||||
of type groups/v1 do not return usernames, and therefore
|
|
||||||
cannot change the usernames. After each expression, the
|
|
||||||
new (potentially changed) username or groups get passed
|
|
||||||
to the following expression. \n Any compilation or static
|
|
||||||
type-checking failure of any expression will cause an
|
|
||||||
error status on the FederationDomain. During an authentication
|
|
||||||
attempt, any unexpected runtime evaluation errors (e.g.
|
|
||||||
division by zero) cause the authentication attempt to
|
|
||||||
fail. When all expressions evaluate successfully, then
|
|
||||||
the (potentially changed) username and group names have
|
|
||||||
been decided for that authentication attempt."
|
|
||||||
items:
|
|
||||||
description: FederationDomainTransformsExpression defines
|
|
||||||
a transform expression.
|
|
||||||
properties:
|
|
||||||
expression:
|
|
||||||
description: Expression is a CEL expression that will
|
|
||||||
be evaluated based on the Type during an authentication.
|
|
||||||
minLength: 1
|
|
||||||
type: string
|
|
||||||
message:
|
|
||||||
description: Message is only used when Type is policy/v1.
|
|
||||||
It defines an error message to be used when the
|
|
||||||
policy rejects an authentication attempt. When empty,
|
|
||||||
a default message will be used.
|
|
||||||
type: string
|
|
||||||
type:
|
|
||||||
description: Type determines the type of the expression.
|
|
||||||
It must be one of the supported types.
|
|
||||||
enum:
|
|
||||||
- policy/v1
|
|
||||||
- username/v1
|
|
||||||
- groups/v1
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- expression
|
|
||||||
- type
|
|
||||||
type: object
|
|
||||||
type: array
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- displayName
|
|
||||||
- objectRef
|
|
||||||
type: object
|
|
||||||
type: array
|
|
||||||
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 specifies a secret which will contain Transport Layer
|
|
||||||
Security (TLS) configuration for the FederationDomain.
|
|
||||||
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:
|
|
||||||
conditions:
|
|
||||||
description: Conditions represent the observations of an FederationDomain's
|
|
||||||
current state.
|
|
||||||
items:
|
|
||||||
description: "Condition contains details for one aspect of the current
|
|
||||||
state of this API Resource. --- This struct is intended for direct
|
|
||||||
use as an array at the field path .status.conditions. For example,
|
|
||||||
\n type FooStatus struct{ // Represents the observations of a
|
|
||||||
foo's current state. // Known .status.conditions.type are: \"Available\",
|
|
||||||
\"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
|
|
||||||
// +listType=map // +listMapKey=type Conditions []metav1.Condition
|
|
||||||
`json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
|
|
||||||
protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
|
|
||||||
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 FederationDomain.
|
|
||||||
enum:
|
|
||||||
- Pending
|
|
||||||
- Ready
|
|
||||||
- Error
|
|
||||||
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
|
|
||||||
x-kubernetes-map-type: atomic
|
|
||||||
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
|
|
||||||
x-kubernetes-map-type: atomic
|
|
||||||
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
|
|
||||||
x-kubernetes-map-type: atomic
|
|
||||||
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
|
|
||||||
x-kubernetes-map-type: atomic
|
|
||||||
type: object
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- spec
|
|
||||||
type: object
|
|
||||||
served: true
|
|
||||||
storage: true
|
|
||||||
subresources:
|
|
||||||
status: {}
|
|
@ -1,220 +0,0 @@
|
|||||||
---
|
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
|
||||||
kind: CustomResourceDefinition
|
|
||||||
metadata:
|
|
||||||
annotations:
|
|
||||||
controller-gen.kubebuilder.io/version: v0.13.0
|
|
||||||
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 contains details for one aspect of the current
|
|
||||||
state of this API Resource. --- This struct is intended for direct
|
|
||||||
use as an array at the field path .status.conditions. For example,
|
|
||||||
\n type FooStatus struct{ // Represents the observations of a
|
|
||||||
foo's current state. // Known .status.conditions.type are: \"Available\",
|
|
||||||
\"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
|
|
||||||
// +listType=map // +listMapKey=type Conditions []metav1.Condition
|
|
||||||
`json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
|
|
||||||
protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
|
|
||||||
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: {}
|
|
@ -1,236 +0,0 @@
|
|||||||
#! 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
|
|
||||||
---
|
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: #@ defaultResourceName()
|
|
||||||
namespace: #@ namespace()
|
|
||||||
labels: #@ labels()
|
|
||||||
spec:
|
|
||||||
replicas: #@ data.values.replicas
|
|
||||||
selector:
|
|
||||||
#! In hindsight, this should have been deploymentPodLabel(), but this field is immutable so changing it would break upgrades.
|
|
||||||
matchLabels: #@ defaultLabel()
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
#! This has always included defaultLabel(), which is used by this Deployment's selector.
|
|
||||||
_: #@ template.replace(defaultLabel())
|
|
||||||
#! More recently added the more unique deploymentPodLabel() so Services can select these Pods more specifically
|
|
||||||
#! without accidentally selecting pods from any future Deployments which might also want to use the defaultLabel().
|
|
||||||
_: #@ template.replace(deploymentPodLabel())
|
|
||||||
spec:
|
|
||||||
securityContext:
|
|
||||||
runAsUser: #@ data.values.run_as_user
|
|
||||||
runAsGroup: #@ data.values.run_as_group
|
|
||||||
serviceAccountName: #@ defaultResourceName()
|
|
||||||
#@ if data.values.image_pull_dockerconfigjson and data.values.image_pull_dockerconfigjson != "":
|
|
||||||
imagePullSecrets:
|
|
||||||
- name: image-pull-secret
|
|
||||||
#@ end
|
|
||||||
containers:
|
|
||||||
- name: #@ defaultResourceName()
|
|
||||||
#@ if data.values.image_digest:
|
|
||||||
image: #@ data.values.image_repo + "@" + data.values.image_digest
|
|
||||||
#@ else:
|
|
||||||
image: #@ data.values.image_repo + ":" + data.values.image_tag
|
|
||||||
#@ end
|
|
||||||
imagePullPolicy: IfNotPresent
|
|
||||||
command:
|
|
||||||
- pinniped-supervisor
|
|
||||||
- /etc/podinfo
|
|
||||||
- /etc/config/pinniped.yaml
|
|
||||||
securityContext:
|
|
||||||
readOnlyRootFilesystem: true
|
|
||||||
runAsNonRoot: true
|
|
||||||
allowPrivilegeEscalation: false
|
|
||||||
capabilities:
|
|
||||||
drop: [ "ALL" ]
|
|
||||||
#! seccompProfile was introduced in Kube v1.19. Using it on an older Kube version will result in a
|
|
||||||
#! kubectl validation error when installing via `kubectl apply`, which can be ignored using kubectl's
|
|
||||||
#! `--validate=false` flag. Note that installing via `kapp` does not complain about this validation error.
|
|
||||||
seccompProfile:
|
|
||||||
type: "RuntimeDefault"
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
#! If OIDCClient CRs are being used, then the Supervisor needs enough CPU to run expensive bcrypt
|
|
||||||
#! operations inside the implementation of the token endpoint for any authcode flows performed by those
|
|
||||||
#! clients, so for that use case administrators may wish to increase the requests.cpu value to more
|
|
||||||
#! closely align with their anticipated needs. Increasing this value will cause Kubernetes to give more
|
|
||||||
#! available CPU to this process during times of high CPU contention. By default, don't ask for too much
|
|
||||||
#! because that would make it impossible to install the Pinniped Supervisor on small clusters.
|
|
||||||
#! Aside from performing bcrypts at the token endpoint for those clients, the Supervisor is not a
|
|
||||||
#! particularly CPU-intensive process.
|
|
||||||
cpu: "100m" #! by default, request one-tenth of a CPU
|
|
||||||
memory: "128Mi"
|
|
||||||
limits:
|
|
||||||
#! By declaring a CPU limit that is not equal to the CPU request value, the Supervisor will be classified
|
|
||||||
#! by Kubernetes to have "burstable" quality of service.
|
|
||||||
#! See https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/#create-a-pod-that-gets-assigned-a-qos-class-of-burstable
|
|
||||||
#! If OIDCClient CRs are being used, and lots of simultaneous users have active sessions, then it is hard
|
|
||||||
#! pre-determine what the CPU limit should be for that use case. Guessing too low would cause the
|
|
||||||
#! pod's CPU usage to be throttled, resulting in poor performance. Guessing too high would allow clients
|
|
||||||
#! to cause the usage of lots of CPU resources. Administrators who have a good sense of anticipated usage
|
|
||||||
#! patterns may choose to set the requests.cpu and limits.cpu differently from these defaults.
|
|
||||||
cpu: "1000m" #! by default, throttle each pod's usage at 1 CPU
|
|
||||||
memory: "128Mi"
|
|
||||||
volumeMounts:
|
|
||||||
- name: config-volume
|
|
||||||
mountPath: /etc/config
|
|
||||||
readOnly: true
|
|
||||||
- name: podinfo
|
|
||||||
mountPath: /etc/podinfo
|
|
||||||
readOnly: true
|
|
||||||
#@ if hasUnixNetworkEndpoint():
|
|
||||||
- name: socket
|
|
||||||
mountPath: /pinniped_socket
|
|
||||||
readOnly: false #! writable to allow for socket use
|
|
||||||
#@ end
|
|
||||||
ports:
|
|
||||||
- containerPort: 8443
|
|
||||||
protocol: TCP
|
|
||||||
env:
|
|
||||||
#@ if data.values.https_proxy:
|
|
||||||
- name: HTTPS_PROXY
|
|
||||||
value: #@ data.values.https_proxy
|
|
||||||
#@ end
|
|
||||||
#@ if data.values.https_proxy and data.values.no_proxy:
|
|
||||||
- name: NO_PROXY
|
|
||||||
value: #@ data.values.no_proxy
|
|
||||||
#@ end
|
|
||||||
livenessProbe:
|
|
||||||
httpGet:
|
|
||||||
path: /healthz
|
|
||||||
port: 8443
|
|
||||||
scheme: HTTPS
|
|
||||||
initialDelaySeconds: 2
|
|
||||||
timeoutSeconds: 15
|
|
||||||
periodSeconds: 10
|
|
||||||
failureThreshold: 5
|
|
||||||
readinessProbe:
|
|
||||||
httpGet:
|
|
||||||
path: /healthz
|
|
||||||
port: 8443
|
|
||||||
scheme: HTTPS
|
|
||||||
initialDelaySeconds: 2
|
|
||||||
timeoutSeconds: 3
|
|
||||||
periodSeconds: 10
|
|
||||||
failureThreshold: 3
|
|
||||||
volumes:
|
|
||||||
- name: config-volume
|
|
||||||
configMap:
|
|
||||||
name: #@ defaultResourceNameWithSuffix("static-config")
|
|
||||||
- name: podinfo
|
|
||||||
downwardAPI:
|
|
||||||
items:
|
|
||||||
- path: "labels"
|
|
||||||
fieldRef:
|
|
||||||
fieldPath: metadata.labels
|
|
||||||
- path: "namespace"
|
|
||||||
fieldRef:
|
|
||||||
fieldPath: metadata.namespace
|
|
||||||
- path: "name"
|
|
||||||
fieldRef:
|
|
||||||
fieldPath: metadata.name
|
|
||||||
#@ if hasUnixNetworkEndpoint():
|
|
||||||
- name: socket
|
|
||||||
emptyDir: {}
|
|
||||||
#@ end
|
|
||||||
#! This will help make sure our multiple pods run on different nodes, making
|
|
||||||
#! our deployment "more" "HA".
|
|
||||||
affinity:
|
|
||||||
podAntiAffinity:
|
|
||||||
preferredDuringSchedulingIgnoredDuringExecution:
|
|
||||||
- weight: 50
|
|
||||||
podAffinityTerm:
|
|
||||||
labelSelector:
|
|
||||||
matchLabels: #@ deploymentPodLabel()
|
|
||||||
topologyKey: kubernetes.io/hostname
|
|
||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
#! If name is changed, must also change names.apiService in the ConfigMap above and spec.service.name in the APIService below.
|
|
||||||
name: #@ defaultResourceNameWithSuffix("api")
|
|
||||||
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:
|
|
||||||
- protocol: TCP
|
|
||||||
port: 443
|
|
||||||
targetPort: 10250
|
|
||||||
---
|
|
||||||
apiVersion: apiregistration.k8s.io/v1
|
|
||||||
kind: APIService
|
|
||||||
metadata:
|
|
||||||
name: #@ pinnipedDevAPIGroupWithPrefix("v1alpha1.clientsecret.supervisor")
|
|
||||||
labels: #@ labels()
|
|
||||||
spec:
|
|
||||||
version: v1alpha1
|
|
||||||
group: #@ pinnipedDevAPIGroupWithPrefix("clientsecret.supervisor")
|
|
||||||
groupPriorityMinimum: 9900
|
|
||||||
versionPriority: 15
|
|
||||||
#! caBundle: Do not include this key here. Starts out null, will be updated/owned by the golang code.
|
|
||||||
service:
|
|
||||||
name: #@ defaultResourceNameWithSuffix("api")
|
|
||||||
namespace: #@ namespace()
|
|
||||||
port: 443
|
|
@ -1,88 +0,0 @@
|
|||||||
#! 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
|
|
@ -1,318 +0,0 @@
|
|||||||
---
|
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
|
||||||
kind: CustomResourceDefinition
|
|
||||||
metadata:
|
|
||||||
annotations:
|
|
||||||
controller-gen.kubebuilder.io/version: v0.13.0
|
|
||||||
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 contains details for one aspect of the current
|
|
||||||
state of this API Resource. --- This struct is intended for direct
|
|
||||||
use as an array at the field path .status.conditions. For example,
|
|
||||||
\n type FooStatus struct{ // Represents the observations of a
|
|
||||||
foo's current state. // Known .status.conditions.type are: \"Available\",
|
|
||||||
\"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
|
|
||||||
// +listType=map // +listMapKey=type Conditions []metav1.Condition
|
|
||||||
`json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
|
|
||||||
protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
|
|
||||||
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: {}
|
|
@ -1,315 +0,0 @@
|
|||||||
---
|
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
|
||||||
kind: CustomResourceDefinition
|
|
||||||
metadata:
|
|
||||||
annotations:
|
|
||||||
controller-gen.kubebuilder.io/version: v0.13.0
|
|
||||||
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 contains details for one aspect of the current
|
|
||||||
state of this API Resource. --- This struct is intended for direct
|
|
||||||
use as an array at the field path .status.conditions. For example,
|
|
||||||
\n type FooStatus struct{ // Represents the observations of a
|
|
||||||
foo's current state. // Known .status.conditions.type are: \"Available\",
|
|
||||||
\"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
|
|
||||||
// +listType=map // +listMapKey=type Conditions []metav1.Condition
|
|
||||||
`json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
|
|
||||||
protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
|
|
||||||
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: {}
|
|
@ -1,345 +0,0 @@
|
|||||||
---
|
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
|
||||||
kind: CustomResourceDefinition
|
|
||||||
metadata:
|
|
||||||
annotations:
|
|
||||||
controller-gen.kubebuilder.io/version: v0.13.0
|
|
||||||
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 contains details for one aspect of the current
|
|
||||||
state of this API Resource. --- This struct is intended for direct
|
|
||||||
use as an array at the field path .status.conditions. For example,
|
|
||||||
\n type FooStatus struct{ // Represents the observations of a
|
|
||||||
foo's current state. // Known .status.conditions.type are: \"Available\",
|
|
||||||
\"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
|
|
||||||
// +listType=map // +listMapKey=type Conditions []metav1.Condition
|
|
||||||
`json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
|
|
||||||
protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
|
|
||||||
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: {}
|
|
@ -1,152 +0,0 @@
|
|||||||
#! 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
|
|
@ -1,115 +0,0 @@
|
|||||||
#! 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
|
|
@ -1,175 +0,0 @@
|
|||||||
#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
|
||||||
#! SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
#@data/values-schema
|
|
||||||
---
|
|
||||||
#@schema/desc "Name of pinniped-supervisor."
|
|
||||||
app_name: pinniped-supervisor
|
|
||||||
|
|
||||||
#@schema/desc "Creates a new namespace statically in yaml with the given name and installs the app into that namespace."
|
|
||||||
namespace: pinniped-supervisor
|
|
||||||
#@ into_namespace_desc = "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."
|
|
||||||
#@schema/desc into_namespace_desc
|
|
||||||
#@schema/nullable
|
|
||||||
into_namespace: my-preexisting-namespace
|
|
||||||
|
|
||||||
#@ custom_labels_desc = "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."
|
|
||||||
#@schema/desc custom_labels_desc
|
|
||||||
#@schema/type any=True
|
|
||||||
custom_labels: {} #! {myCustomLabelName: myCustomLabelValue, otherCustomLabelName: otherCustomLabelValue}
|
|
||||||
|
|
||||||
#@schema/desc "Specify how many replicas of the Pinniped server to run."
|
|
||||||
replicas: 2
|
|
||||||
|
|
||||||
#@schema/desc "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
|
|
||||||
#@schema/desc "Specify either an image_digest or an image_tag. If both are given, only image_digest will be used."
|
|
||||||
#@schema/nullable
|
|
||||||
image_digest: sha256:f3c4fdfd3ef865d4b97a1fd295d94acc3f0c654c46b6f27ffad5cf80216903c8
|
|
||||||
#@schema/desc "Specify either an image_digest or an image_tag. If both are given, only image_digest will be used."
|
|
||||||
image_tag: latest
|
|
||||||
|
|
||||||
#@ image_pull_dockerconfigjson_desc = "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."
|
|
||||||
#@schema/desc image_pull_dockerconfigjson_desc
|
|
||||||
#@schema/nullable
|
|
||||||
image_pull_dockerconfigjson: {"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.
|
|
||||||
#@schema/desc "will be removed in a future release; when specified, creates a NodePort Service with this `port` value, with port 8080 as its `targetPort`"
|
|
||||||
#@schema/nullable
|
|
||||||
deprecated_service_http_nodeport_port: 31234
|
|
||||||
#@schema/desc "will be removed in a future release; the `nodePort` value of the NodePort Service, optional when `deprecated_service_http_nodeport_port` is specified"
|
|
||||||
#@schema/nullable
|
|
||||||
deprecated_service_http_nodeport_nodeport: 31234
|
|
||||||
#@schema/desc "will be removed in a future release; when specified, creates a LoadBalancer Service with this `port` value, with port 8080 as its `targetPort`"
|
|
||||||
#@schema/nullable
|
|
||||||
deprecated_service_http_loadbalancer_port: 8443
|
|
||||||
#@schema/desc "#! will be removed in a future release; when specified, creates a ClusterIP Service with this `port` value, with port 8080 as its `targetPort`"
|
|
||||||
#@schema/nullable
|
|
||||||
deprecated_service_http_clusterip_port: 8443
|
|
||||||
#@schema/desc "#! when specified, creates a NodePort Service with this `port` value, with port 8443 as its `targetPort`"
|
|
||||||
#@schema/nullable
|
|
||||||
service_https_nodeport_port: 31243
|
|
||||||
#@schema/desc "#! the `nodePort` value of the NodePort Service, optional when `service_https_nodeport_port` is specified"
|
|
||||||
#@schema/nullable
|
|
||||||
service_https_nodeport_nodeport: 31243
|
|
||||||
#@schema/desc "#! when specified, creates a LoadBalancer Service with this `port` value, with port 8443 as its `targetPort`"
|
|
||||||
#@schema/nullable
|
|
||||||
service_https_loadbalancer_port: 8443
|
|
||||||
#@schema/desc "#! when specified, creates a ClusterIP Service with this `port` value, with port 8443 as its `targetPort`"
|
|
||||||
#@schema/nullable
|
|
||||||
service_https_clusterip_port: 8443
|
|
||||||
#@ service_loadbalancer_ip_desc="The `loadBalancerIP` value of the LoadBalancer Service. \
|
|
||||||
#@ Ignored unless service_https_loadbalancer_port is provided."
|
|
||||||
#@schema/desc service_loadbalancer_ip_desc
|
|
||||||
#@schema/nullable
|
|
||||||
service_loadbalancer_ip: 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.
|
|
||||||
#@schema/desc "default, when this value is left unset, only warnings and errors are printed. There is no way to suppress warning and error logs."
|
|
||||||
#@schema/nullable
|
|
||||||
log_level: info
|
|
||||||
#@ deprecated_log_format_desc = "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."
|
|
||||||
#@schema/desc deprecated_log_format_desc
|
|
||||||
#@schema/nullable
|
|
||||||
deprecated_log_format: json
|
|
||||||
|
|
||||||
#@schema/desc "run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice"
|
|
||||||
run_as_user: 65532
|
|
||||||
#@schema/desc "run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice"
|
|
||||||
run_as_group: 65532
|
|
||||||
|
|
||||||
#@ api_group_suffix_desc = "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."
|
|
||||||
#@schema/desc api_group_suffix_desc
|
|
||||||
api_group_suffix: pinniped.dev
|
|
||||||
|
|
||||||
#@ https_proxy_desc = "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."
|
|
||||||
#@schema/desc https_proxy_desc
|
|
||||||
#@schema/nullable
|
|
||||||
https_proxy: http://proxy.example.com
|
|
||||||
#@schema/desc "do not proxy Kubernetes endpoints"
|
|
||||||
no_proxy: "$(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.cluster.local"
|
|
||||||
|
|
||||||
#! 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.
|
|
||||||
#!
|
|
||||||
#@schema/desc "Control the HTTP and HTTPS listeners of the Supervisor."
|
|
||||||
#@schema/nullable
|
|
||||||
endpoints:
|
|
||||||
https:
|
|
||||||
network: tcp
|
|
||||||
address: 1.2.3.4:5678
|
|
||||||
|
|
||||||
#! deprecated_insecure_accept_external_unencrypted_http_requests_desc = "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."
|
|
||||||
#@schema/desc https_proxy_desc
|
|
||||||
deprecated_insecure_accept_external_unencrypted_http_requests: false
|
|
@ -1,63 +0,0 @@
|
|||||||
#! 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
|
|
7
deploy_carvel/supervisor/vendir.lock.yml
Normal file
7
deploy_carvel/supervisor/vendir.lock.yml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
apiVersion: vendir.k14s.io/v1alpha1
|
||||||
|
directories:
|
||||||
|
- contents:
|
||||||
|
- directory: {}
|
||||||
|
path: .
|
||||||
|
path: config
|
||||||
|
kind: LockConfig
|
8
deploy_carvel/supervisor/vendir.yml
Normal file
8
deploy_carvel/supervisor/vendir.yml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
apiVersion: vendir.k14s.io/v1alpha1
|
||||||
|
kind: Config
|
||||||
|
directories:
|
||||||
|
- path: config
|
||||||
|
contents:
|
||||||
|
- path: .
|
||||||
|
directory:
|
||||||
|
path: ../../deploy/supervisor
|
@ -90,11 +90,11 @@ do
|
|||||||
resource_config_source_dir="deploy/${resource_name}"
|
resource_config_source_dir="deploy/${resource_name}"
|
||||||
resource_config_destination_dir="deploy_carvel/${resource_name}/config"
|
resource_config_destination_dir="deploy_carvel/${resource_name}/config"
|
||||||
|
|
||||||
# this must be real files, not symlinks
|
# these must be real files, not symlinks
|
||||||
log_note "Copy deploy directory for ${resource_name} to package bundle..."
|
log_note "Vendir sync deploy directory for ${resource_name} to package bundle..."
|
||||||
echo "cp -aRf ${resource_config_source_dir} ${resource_config_destination_dir}"
|
pushd "${resource_config_destination_dir}" > /dev/null
|
||||||
rm -rf "${resource_config_destination_dir}" # clean
|
vendir sync
|
||||||
cp -r "${resource_config_source_dir}" "${resource_config_destination_dir}"
|
popd > /dev/null
|
||||||
|
|
||||||
log_note "Generating OpenAPI v3 schema for ${resource_name}..."
|
log_note "Generating OpenAPI v3 schema for ${resource_name}..."
|
||||||
ytt \
|
ytt \
|
||||||
|
Loading…
Reference in New Issue
Block a user