WIP: hack in a deploy_carvel/concierge directory, but strip out the deployment for simplicity
This commit is contained in:
parent
7002e4dd13
commit
e7824bf714
3
deploy_carvel/concierge/config/README.md
Normal file
3
deploy_carvel/concierge/config/README.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Pinniped Concierge Deployment
|
||||||
|
|
||||||
|
See [the how-to guide for details](https://pinniped.dev/docs/howto/install-concierge/).
|
@ -0,0 +1,176 @@
|
|||||||
|
---
|
||||||
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
|
kind: CustomResourceDefinition
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
controller-gen.kubebuilder.io/version: v0.8.0
|
||||||
|
creationTimestamp: null
|
||||||
|
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 status of a resource (mirrored from the metav1.Condition
|
||||||
|
type added in Kubernetes 1.19). In a future API version we can
|
||||||
|
switch to using the upstream type. See https://github.com/kubernetes/apimachinery/blob/v0.19.0/pkg/apis/meta/v1/types.go#L1353-L1413.
|
||||||
|
properties:
|
||||||
|
lastTransitionTime:
|
||||||
|
description: lastTransitionTime is the last time the condition
|
||||||
|
transitioned from one status to another. This should be when
|
||||||
|
the underlying condition changed. If that is not known, then
|
||||||
|
using the time when the API field changed is acceptable.
|
||||||
|
format: date-time
|
||||||
|
type: string
|
||||||
|
message:
|
||||||
|
description: message is a human readable message indicating
|
||||||
|
details about the transition. This may be an empty string.
|
||||||
|
maxLength: 32768
|
||||||
|
type: string
|
||||||
|
observedGeneration:
|
||||||
|
description: observedGeneration represents the .metadata.generation
|
||||||
|
that the condition was set based upon. For instance, if .metadata.generation
|
||||||
|
is currently 12, but the .status.conditions[x].observedGeneration
|
||||||
|
is 9, the condition is out of date with respect to the current
|
||||||
|
state of the instance.
|
||||||
|
format: int64
|
||||||
|
minimum: 0
|
||||||
|
type: integer
|
||||||
|
reason:
|
||||||
|
description: reason contains a programmatic identifier indicating
|
||||||
|
the reason for the condition's last transition. Producers
|
||||||
|
of specific condition types may define expected values and
|
||||||
|
meanings for this field, and whether the values are considered
|
||||||
|
a guaranteed API. The value should be a CamelCase string.
|
||||||
|
This field may not be empty.
|
||||||
|
maxLength: 1024
|
||||||
|
minLength: 1
|
||||||
|
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
||||||
|
type: string
|
||||||
|
status:
|
||||||
|
description: status of the condition, one of True, False, Unknown.
|
||||||
|
enum:
|
||||||
|
- "True"
|
||||||
|
- "False"
|
||||||
|
- Unknown
|
||||||
|
type: string
|
||||||
|
type:
|
||||||
|
description: type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||||
|
--- Many .condition.type values are consistent across resources
|
||||||
|
like Available, but because arbitrary conditions can be useful
|
||||||
|
(see .node.status.conditions), the ability to deconflict is
|
||||||
|
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
|
||||||
|
maxLength: 316
|
||||||
|
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- lastTransitionTime
|
||||||
|
- message
|
||||||
|
- reason
|
||||||
|
- status
|
||||||
|
- type
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
x-kubernetes-list-map-keys:
|
||||||
|
- type
|
||||||
|
x-kubernetes-list-type: map
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- spec
|
||||||
|
type: object
|
||||||
|
served: true
|
||||||
|
storage: true
|
||||||
|
subresources:
|
||||||
|
status: {}
|
||||||
|
status:
|
||||||
|
acceptedNames:
|
||||||
|
kind: ""
|
||||||
|
plural: ""
|
||||||
|
conditions: []
|
||||||
|
storedVersions: []
|
@ -0,0 +1,149 @@
|
|||||||
|
---
|
||||||
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
|
kind: CustomResourceDefinition
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
controller-gen.kubebuilder.io/version: v0.8.0
|
||||||
|
creationTimestamp: null
|
||||||
|
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 status of a resource (mirrored from the metav1.Condition
|
||||||
|
type added in Kubernetes 1.19). In a future API version we can
|
||||||
|
switch to using the upstream type. See https://github.com/kubernetes/apimachinery/blob/v0.19.0/pkg/apis/meta/v1/types.go#L1353-L1413.
|
||||||
|
properties:
|
||||||
|
lastTransitionTime:
|
||||||
|
description: lastTransitionTime is the last time the condition
|
||||||
|
transitioned from one status to another. This should be when
|
||||||
|
the underlying condition changed. If that is not known, then
|
||||||
|
using the time when the API field changed is acceptable.
|
||||||
|
format: date-time
|
||||||
|
type: string
|
||||||
|
message:
|
||||||
|
description: message is a human readable message indicating
|
||||||
|
details about the transition. This may be an empty string.
|
||||||
|
maxLength: 32768
|
||||||
|
type: string
|
||||||
|
observedGeneration:
|
||||||
|
description: observedGeneration represents the .metadata.generation
|
||||||
|
that the condition was set based upon. For instance, if .metadata.generation
|
||||||
|
is currently 12, but the .status.conditions[x].observedGeneration
|
||||||
|
is 9, the condition is out of date with respect to the current
|
||||||
|
state of the instance.
|
||||||
|
format: int64
|
||||||
|
minimum: 0
|
||||||
|
type: integer
|
||||||
|
reason:
|
||||||
|
description: reason contains a programmatic identifier indicating
|
||||||
|
the reason for the condition's last transition. Producers
|
||||||
|
of specific condition types may define expected values and
|
||||||
|
meanings for this field, and whether the values are considered
|
||||||
|
a guaranteed API. The value should be a CamelCase string.
|
||||||
|
This field may not be empty.
|
||||||
|
maxLength: 1024
|
||||||
|
minLength: 1
|
||||||
|
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
||||||
|
type: string
|
||||||
|
status:
|
||||||
|
description: status of the condition, one of True, False, Unknown.
|
||||||
|
enum:
|
||||||
|
- "True"
|
||||||
|
- "False"
|
||||||
|
- Unknown
|
||||||
|
type: string
|
||||||
|
type:
|
||||||
|
description: type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||||
|
--- Many .condition.type values are consistent across resources
|
||||||
|
like Available, but because arbitrary conditions can be useful
|
||||||
|
(see .node.status.conditions), the ability to deconflict is
|
||||||
|
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
|
||||||
|
maxLength: 316
|
||||||
|
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- lastTransitionTime
|
||||||
|
- message
|
||||||
|
- reason
|
||||||
|
- status
|
||||||
|
- type
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
x-kubernetes-list-map-keys:
|
||||||
|
- type
|
||||||
|
x-kubernetes-list-type: map
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- spec
|
||||||
|
type: object
|
||||||
|
served: true
|
||||||
|
storage: true
|
||||||
|
subresources:
|
||||||
|
status: {}
|
||||||
|
status:
|
||||||
|
acceptedNames:
|
||||||
|
kind: ""
|
||||||
|
plural: ""
|
||||||
|
conditions: []
|
||||||
|
storedVersions: []
|
@ -0,0 +1,264 @@
|
|||||||
|
---
|
||||||
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
|
kind: CustomResourceDefinition
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
controller-gen.kubebuilder.io/version: v0.8.0
|
||||||
|
creationTimestamp: null
|
||||||
|
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: {}
|
||||||
|
status:
|
||||||
|
acceptedNames:
|
||||||
|
kind: ""
|
||||||
|
plural: ""
|
||||||
|
conditions: []
|
||||||
|
storedVersions: []
|
177
deploy_carvel/concierge/config/deployment-HACKED.yaml
Normal file
177
deploy_carvel/concierge/config/deployment-HACKED.yaml
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
#! Copyright 2020-2022 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
|
||||||
|
---
|
||||||
|
#! THE DEPLOYMENT IS GONE!!!
|
||||||
|
#! THE DEPLOYMENT IS GONE!!!
|
||||||
|
#! THE DEPLOYMENT IS GONE!!! For initial prototype, just installing some simple things.
|
||||||
|
#! THE DEPLOYMENT IS GONE!!!
|
||||||
|
#! THE DEPLOYMENT IS GONE!!!
|
||||||
|
---
|
||||||
|
#! THE SERVICE IS GONE!!!
|
||||||
|
#! THE SERVICE IS GONE!!!
|
||||||
|
#! THE SERVICE IS GONE!!! For initial prototype, just installing some simple things.
|
||||||
|
#! THE SERVICE IS GONE!!!
|
||||||
|
#! THE SERVICE IS GONE!!!
|
||||||
|
---
|
||||||
|
#! THE SECOND SERVICE IS GONE!!!
|
||||||
|
#! THE SECOND SERVICE IS GONE!!!
|
||||||
|
#! THE SECOND SERVICE IS GONE!!! For initial prototype, just installing some simple things.
|
||||||
|
#! THE SECOND SERVICE IS GONE!!!
|
||||||
|
#! THE SECOND SERVICE IS GONE!!!
|
||||||
|
---
|
||||||
|
#! THE API SERVICE IS GONE!!!
|
||||||
|
#! THE API SERVICE IS GONE!!!
|
||||||
|
#! THE API SERVICE IS GONE!!! For initial prototype, just installing some simple things.
|
||||||
|
#! THE API SERVICE IS GONE!!!
|
||||||
|
#! THE API SERVICE IS GONE!!!
|
||||||
|
---
|
||||||
|
#! THE SECOND API SERVICE IS GONE!!!
|
||||||
|
#! THE SECOND API SERVICE IS GONE!!!
|
||||||
|
#! THE SECOND API SERVICE IS GONE!!! For initial prototype, just installing some simple things.
|
||||||
|
#! THE SECOND API SERVICE IS GONE!!!
|
||||||
|
#! THE SECOND API SERVICE IS GONE!!!
|
||||||
|
---
|
||||||
|
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
|
47
deploy_carvel/concierge/config/helpers.lib.yaml
Normal file
47
deploy_carvel/concierge/config/helpers.lib.yaml
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#! 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
|
296
deploy_carvel/concierge/config/rbac.yaml
Normal file
296
deploy_carvel/concierge/config/rbac.yaml
Normal file
@ -0,0 +1,296 @@
|
|||||||
|
#! 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
|
107
deploy_carvel/concierge/config/values.yaml
Normal file
107
deploy_carvel/concierge/config/values.yaml
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
#! Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||||
|
#! SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
#@data/values-schema
|
||||||
|
---
|
||||||
|
|
||||||
|
app_name: pinniped-concierge
|
||||||
|
|
||||||
|
#! Creates a new namespace statically in yaml with the given name and installs the app into that namespace.
|
||||||
|
namespace: pinniped-concierge
|
||||||
|
#! If specified, assumes that a namespace of the given name already exists and installs the app into that namespace.
|
||||||
|
#! If both `namespace` and `into_namespace` are specified, then only `into_namespace` is used.
|
||||||
|
into_namespace: #! e.g. my-preexisting-namespace
|
||||||
|
|
||||||
|
#! All resources created statically by yaml at install-time and all resources created dynamically
|
||||||
|
#! by controllers at runtime will be labelled with `app: $app_name` and also with the labels
|
||||||
|
#! specified here. The value of `custom_labels` must be a map of string keys to string values.
|
||||||
|
#! The app can be uninstalled either by:
|
||||||
|
#! 1. Deleting the static install-time yaml resources including the static namespace, which will cascade and also delete
|
||||||
|
#! resources that were dynamically created by controllers at runtime
|
||||||
|
#! 2. Or, deleting all resources by label, which does not assume that there was a static install-time yaml namespace.
|
||||||
|
custom_labels: {} #! e.g. {myCustomLabelName: myCustomLabelValue, otherCustomLabelName: otherCustomLabelValue}
|
||||||
|
|
||||||
|
#! Specify how many replicas of the Pinniped server to run.
|
||||||
|
replicas: 2
|
||||||
|
|
||||||
|
#! Specify either an image_digest or an image_tag. If both are given, only image_digest will be used.
|
||||||
|
image_repo: projects.registry.vmware.com/pinniped/pinniped-server
|
||||||
|
image_digest: #! e.g. sha256:f3c4fdfd3ef865d4b97a1fd295d94acc3f0c654c46b6f27ffad5cf80216903c8
|
||||||
|
image_tag: latest
|
||||||
|
|
||||||
|
#! 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.
|
||||||
|
kube_cert_agent_image:
|
||||||
|
|
||||||
|
#! Specifies a secret to be used when pulling the above `image_repo` container image.
|
||||||
|
#! Can be used when the above image_repo is a private registry.
|
||||||
|
#! Typically the value would be the output of: kubectl create secret docker-registry x --docker-server=https://example.io --docker-username="USERNAME" --docker-password="PASSWORD" --dry-run=client -o json | jq -r '.data[".dockerconfigjson"]'
|
||||||
|
#! Optional.
|
||||||
|
image_pull_dockerconfigjson: #! e.g. {"auths":{"https://registry.example.com":{"username":"USERNAME","password":"PASSWORD","auth":"BASE64_ENCODED_USERNAME_COLON_PASSWORD"}}}
|
||||||
|
|
||||||
|
#! 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.
|
||||||
|
#! Optional.
|
||||||
|
discovery_url: #! e.g., https://example.com
|
||||||
|
|
||||||
|
#! 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.
|
||||||
|
api_serving_certificate_duration_seconds: 2592000
|
||||||
|
api_serving_certificate_renew_before_seconds: 2160000
|
||||||
|
|
||||||
|
#! Specify the verbosity of logging: info ("nice to know" information), debug (developer
|
||||||
|
#! information), trace (timing information), all (kitchen sink).
|
||||||
|
log_level: #! By default, when this value is left unset, only warnings and errors are printed. There is no way to suppress warning and error logs.
|
||||||
|
#! Specify the format of logging: json (for machine parsable logs) and text (for legacy klog formatted logs).
|
||||||
|
#! By default, when this value is left unset, logs are formatted in json.
|
||||||
|
#! This configuration is deprecated and will be removed in a future release at which point logs will always be formatted as json.
|
||||||
|
deprecated_log_format:
|
||||||
|
|
||||||
|
run_as_user: 65532 #! run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice
|
||||||
|
run_as_group: 65532 #! run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice
|
||||||
|
|
||||||
|
#! Specify the API group suffix for all Pinniped API groups. By default, this is set to
|
||||||
|
#! pinniped.dev, so Pinniped API groups will look like foo.pinniped.dev,
|
||||||
|
#! authentication.concierge.pinniped.dev, etc. As an example, if this is set to tuna.io, then
|
||||||
|
#! Pinniped API groups will look like foo.tuna.io. authentication.concierge.tuna.io, etc.
|
||||||
|
api_group_suffix: pinniped.dev
|
||||||
|
|
||||||
|
#! 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.
|
||||||
|
mode: auto
|
||||||
|
#! 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.
|
||||||
|
external_endpoint:
|
||||||
|
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.
|
||||||
|
type: LoadBalancer
|
||||||
|
#! The annotations that should be set on the ClusterIP or LoadBalancer Service.
|
||||||
|
annotations:
|
||||||
|
{service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: "4000"}
|
||||||
|
#! When mode LoadBalancer is set, this will set the LoadBalancer Service's Spec.LoadBalancerIP.
|
||||||
|
load_balancer_ip:
|
||||||
|
|
||||||
|
#! Set the standard golang HTTPS_PROXY and NO_PROXY environment variables on the Concierge containers.
|
||||||
|
#! These will be used when the Concierge makes backend-to-backend calls to authenticators using HTTPS,
|
||||||
|
#! e.g. when the Concierge fetches discovery documents, JWKS keys, and POSTs to token webhooks.
|
||||||
|
#! The Concierge never makes insecure HTTP calls, so there is no reason to set HTTP_PROXY.
|
||||||
|
#! Optional.
|
||||||
|
https_proxy: #! e.g. http://proxy.example.com
|
||||||
|
no_proxy: "$(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.cluster.local" #! do not proxy Kubernetes endpoints
|
33
deploy_carvel/concierge/config/z0_crd_overlay.yaml
Normal file
33
deploy_carvel/concierge/config/z0_crd_overlay.yaml
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#! 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")
|
Loading…
Reference in New Issue
Block a user