Merge pull request #555 from vmware-tanzu/initial_ldap
Initial `LDAPIdentityProvider` support for the Supervisor and CLI
This commit is contained in:
commit
14b8fcc472
@ -32,6 +32,8 @@ func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&OIDCIdentityProvider{},
|
||||
&OIDCIdentityProviderList{},
|
||||
&LDAPIdentityProvider{},
|
||||
&LDAPIdentityProviderList{},
|
||||
)
|
||||
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
|
132
apis/supervisor/idp/v1alpha1/types_ldapidentityprovider.go.tmpl
Normal file
132
apis/supervisor/idp/v1alpha1/types_ldapidentityprovider.go.tmpl
Normal file
@ -0,0 +1,132 @@
|
||||
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
type LDAPIdentityProviderPhase string
|
||||
|
||||
const (
|
||||
// LDAPPhasePending is the default phase for newly-created LDAPIdentityProvider resources.
|
||||
LDAPPhasePending LDAPIdentityProviderPhase = "Pending"
|
||||
|
||||
// LDAPPhaseReady is the phase for an LDAPIdentityProvider resource in a healthy state.
|
||||
LDAPPhaseReady LDAPIdentityProviderPhase = "Ready"
|
||||
|
||||
// LDAPPhaseError is the phase for an LDAPIdentityProvider in an unhealthy state.
|
||||
LDAPPhaseError LDAPIdentityProviderPhase = "Error"
|
||||
)
|
||||
|
||||
// Status of an LDAP identity provider.
|
||||
type LDAPIdentityProviderStatus struct {
|
||||
// Phase summarizes the overall status of the LDAPIdentityProvider.
|
||||
// +kubebuilder:default=Pending
|
||||
// +kubebuilder:validation:Enum=Pending;Ready;Error
|
||||
Phase LDAPIdentityProviderPhase `json:"phase,omitempty"`
|
||||
|
||||
// Represents the observations of an identity provider's current state.
|
||||
// +patchMergeKey=type
|
||||
// +patchStrategy=merge
|
||||
// +listType=map
|
||||
// +listMapKey=type
|
||||
Conditions []Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
|
||||
}
|
||||
|
||||
type LDAPIdentityProviderBind struct {
|
||||
// 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 of your bind account, e.g. "cn=bind-account,ou=users,dc=example,dc=com".
|
||||
// The password must be non-empty.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
SecretName string `json:"secretName"`
|
||||
}
|
||||
|
||||
type LDAPIdentityProviderUserSearchAttributes struct {
|
||||
// Username specifies the name of attribute in the LDAP entry which 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.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
Username string `json:"username,omitempty"`
|
||||
|
||||
// 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".
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
UID string `json:"uid,omitempty"`
|
||||
}
|
||||
|
||||
type LDAPIdentityProviderUserSearch struct {
|
||||
// Base is the DN that should be used as the search base when searching for users. E.g. "ou=users,dc=example,dc=com".
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
Base string `json:"base,omitempty"`
|
||||
|
||||
// Filter is the LDAP search filter which should be applied when searching for users. The pattern "{}" must occur
|
||||
// in the filter 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.
|
||||
// +optional
|
||||
Filter string `json:"filter,omitempty"`
|
||||
|
||||
// Attributes specifies how the user's information should be read from the LDAP entry which was found as
|
||||
// the result of the user search.
|
||||
// +optional
|
||||
Attributes LDAPIdentityProviderUserSearchAttributes `json:"attributes,omitempty"`
|
||||
}
|
||||
|
||||
// Spec for configuring an LDAP identity provider.
|
||||
type LDAPIdentityProviderSpec struct {
|
||||
// Host is the hostname of this LDAP identity provider, i.e., where to connect. For example: ldap.example.com:636.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
Host string `json:"host"`
|
||||
|
||||
// TLS contains the connection settings for how to establish the connection to the Host.
|
||||
TLS *TLSSpec `json:"tls,omitempty"`
|
||||
|
||||
// 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.
|
||||
Bind LDAPIdentityProviderBind `json:"bind,omitempty"`
|
||||
|
||||
// UserSearch contains the configuration for searching for a user by name in the LDAP provider.
|
||||
UserSearch LDAPIdentityProviderUserSearch `json:"userSearch,omitempty"`
|
||||
}
|
||||
|
||||
// LDAPIdentityProvider describes the configuration of an upstream Lightweight Directory Access
|
||||
// Protocol (LDAP) identity provider.
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +kubebuilder:resource:categories=pinniped;pinniped-idp;pinniped-idps
|
||||
// +kubebuilder:printcolumn:name="Host",type=string,JSONPath=`.spec.host`
|
||||
// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.phase`
|
||||
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
|
||||
// +kubebuilder:subresource:status
|
||||
type LDAPIdentityProvider struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Spec for configuring the identity provider.
|
||||
Spec LDAPIdentityProviderSpec `json:"spec"`
|
||||
|
||||
// Status of the identity provider.
|
||||
Status LDAPIdentityProviderStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// List of LDAPIdentityProvider objects.
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type LDAPIdentityProviderList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
Items []LDAPIdentityProvider `json:"items"`
|
||||
}
|
@ -32,7 +32,8 @@ import (
|
||||
"go.pinniped.dev/internal/config/supervisor"
|
||||
"go.pinniped.dev/internal/controller/supervisorconfig"
|
||||
"go.pinniped.dev/internal/controller/supervisorconfig/generator"
|
||||
"go.pinniped.dev/internal/controller/supervisorconfig/upstreamwatcher"
|
||||
"go.pinniped.dev/internal/controller/supervisorconfig/ldapupstreamwatcher"
|
||||
"go.pinniped.dev/internal/controller/supervisorconfig/oidcupstreamwatcher"
|
||||
"go.pinniped.dev/internal/controller/supervisorstorage"
|
||||
"go.pinniped.dev/internal/controllerlib"
|
||||
"go.pinniped.dev/internal/deploymentref"
|
||||
@ -233,7 +234,7 @@ func startControllers(
|
||||
singletonWorker,
|
||||
).
|
||||
WithController(
|
||||
upstreamwatcher.New(
|
||||
oidcupstreamwatcher.New(
|
||||
dynamicUpstreamIDPProvider,
|
||||
pinnipedClient,
|
||||
pinnipedInformers.IDP().V1alpha1().OIDCIdentityProviders(),
|
||||
@ -241,6 +242,15 @@ func startControllers(
|
||||
klogr.New(),
|
||||
controllerlib.WithInformer,
|
||||
),
|
||||
singletonWorker).
|
||||
WithController(
|
||||
ldapupstreamwatcher.New(
|
||||
dynamicUpstreamIDPProvider,
|
||||
pinnipedClient,
|
||||
pinnipedInformers.IDP().V1alpha1().LDAPIdentityProviders(),
|
||||
secretInformer,
|
||||
controllerlib.WithInformer,
|
||||
),
|
||||
singletonWorker)
|
||||
|
||||
kubeInformers.Start(ctx.Done())
|
||||
|
@ -8,8 +8,10 @@ import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
@ -26,6 +28,7 @@ import (
|
||||
_ "k8s.io/client-go/plugin/pkg/client/auth" // Adds handlers for various dynamic auth plugins in client-go
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||
"k8s.io/client-go/transport"
|
||||
|
||||
conciergev1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1"
|
||||
configv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
|
||||
@ -62,6 +65,8 @@ type getKubeconfigOIDCParams struct {
|
||||
debugSessionCache bool
|
||||
caBundle caBundleFlag
|
||||
requestAudience string
|
||||
upstreamIDPName string
|
||||
upstreamIDPType string
|
||||
}
|
||||
|
||||
type getKubeconfigConciergeParams struct {
|
||||
@ -91,6 +96,23 @@ type getKubeconfigParams struct {
|
||||
credentialCachePathSet bool
|
||||
}
|
||||
|
||||
type supervisorOIDCDiscoveryResponseWithV1Alpha1 struct {
|
||||
SupervisorDiscovery SupervisorDiscoveryResponseV1Alpha1 `json:"discovery.supervisor.pinniped.dev/v1alpha1"`
|
||||
}
|
||||
|
||||
type SupervisorDiscoveryResponseV1Alpha1 struct {
|
||||
PinnipedIDPsEndpoint string `json:"pinniped_identity_providers_endpoint"`
|
||||
}
|
||||
|
||||
type supervisorIDPsDiscoveryResponseV1Alpha1 struct {
|
||||
PinnipedIDPs []pinnipedIDPResponse `json:"pinniped_identity_providers"`
|
||||
}
|
||||
|
||||
type pinnipedIDPResponse struct {
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
func kubeconfigCommand(deps kubeconfigDeps) *cobra.Command {
|
||||
var (
|
||||
cmd = &cobra.Command{
|
||||
@ -128,6 +150,8 @@ func kubeconfigCommand(deps kubeconfigDeps) *cobra.Command {
|
||||
f.Var(&flags.oidc.caBundle, "oidc-ca-bundle", "Path to TLS certificate authority bundle (PEM format, optional, can be repeated)")
|
||||
f.BoolVar(&flags.oidc.debugSessionCache, "oidc-debug-session-cache", false, "Print debug logs related to the OpenID Connect session cache")
|
||||
f.StringVar(&flags.oidc.requestAudience, "oidc-request-audience", "", "Request a token with an alternate audience using RFC8693 token exchange")
|
||||
f.StringVar(&flags.oidc.upstreamIDPName, "upstream-identity-provider-name", "", "The name of the upstream identity provider used during login with a Supervisor")
|
||||
f.StringVar(&flags.oidc.upstreamIDPType, "upstream-identity-provider-type", "", "The type of the upstream identity provider used during login with a Supervisor (e.g. 'oidc', 'ldap')")
|
||||
f.StringVar(&flags.kubeconfigPath, "kubeconfig", os.Getenv("KUBECONFIG"), "Path to kubeconfig file")
|
||||
f.StringVar(&flags.kubeconfigContextOverride, "kubeconfig-context", "", "Kubeconfig context name (default: current active context)")
|
||||
f.BoolVar(&flags.skipValidate, "skip-validation", false, "Skip final validation of the kubeconfig (default: false)")
|
||||
@ -165,19 +189,6 @@ func runGetKubeconfig(ctx context.Context, out io.Writer, deps kubeconfigDeps, f
|
||||
return fmt.Errorf("invalid API group suffix: %w", err)
|
||||
}
|
||||
|
||||
execConfig := clientcmdapi.ExecConfig{
|
||||
APIVersion: clientauthenticationv1beta1.SchemeGroupVersion.String(),
|
||||
Args: []string{},
|
||||
Env: []clientcmdapi.ExecEnvVar{},
|
||||
}
|
||||
|
||||
var err error
|
||||
execConfig.Command, err = deps.getPathToSelf()
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not determine the Pinniped executable path: %w", err)
|
||||
}
|
||||
execConfig.ProvideClusterInfo = true
|
||||
|
||||
clientConfig := newClientConfig(flags.kubeconfigPath, flags.kubeconfigContextOverride)
|
||||
currentKubeConfig, err := clientConfig.RawConfig()
|
||||
if err != nil {
|
||||
@ -221,6 +232,47 @@ func runGetKubeconfig(ctx context.Context, out io.Writer, deps kubeconfigDeps, f
|
||||
if err := discoverAuthenticatorParams(authenticator, &flags, deps.log); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Point kubectl at the concierge endpoint.
|
||||
cluster.Server = flags.concierge.endpoint
|
||||
cluster.CertificateAuthorityData = flags.concierge.caBundle
|
||||
}
|
||||
|
||||
// If there is an issuer, and if both upstream flags are not already set, then try to discover Supervisor upstream IDP.
|
||||
if len(flags.oidc.issuer) > 0 && (flags.oidc.upstreamIDPType == "" || flags.oidc.upstreamIDPName == "") {
|
||||
if err := discoverSupervisorUpstreamIDP(ctx, &flags); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
execConfig, err := newExecConfig(deps, flags)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
kubeconfig := newExecKubeconfig(cluster, execConfig, newKubeconfigNames)
|
||||
if err := validateKubeconfig(ctx, flags, kubeconfig, deps.log); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return writeConfigAsYAML(out, kubeconfig)
|
||||
}
|
||||
|
||||
func newExecConfig(deps kubeconfigDeps, flags getKubeconfigParams) (*clientcmdapi.ExecConfig, error) {
|
||||
execConfig := &clientcmdapi.ExecConfig{
|
||||
APIVersion: clientauthenticationv1beta1.SchemeGroupVersion.String(),
|
||||
Args: []string{},
|
||||
Env: []clientcmdapi.ExecEnvVar{},
|
||||
ProvideClusterInfo: true,
|
||||
}
|
||||
|
||||
var err error
|
||||
execConfig.Command, err = deps.getPathToSelf()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not determine the Pinniped executable path: %w", err)
|
||||
}
|
||||
|
||||
if !flags.concierge.disabled {
|
||||
// Append the flags to configure the Concierge credential exchange at runtime.
|
||||
execConfig.Args = append(execConfig.Args,
|
||||
"--enable-concierge",
|
||||
@ -230,10 +282,6 @@ func runGetKubeconfig(ctx context.Context, out io.Writer, deps kubeconfigDeps, f
|
||||
"--concierge-endpoint="+flags.concierge.endpoint,
|
||||
"--concierge-ca-bundle-data="+base64.StdEncoding.EncodeToString(flags.concierge.caBundle),
|
||||
)
|
||||
|
||||
// Point kubectl at the concierge endpoint.
|
||||
cluster.Server = flags.concierge.endpoint
|
||||
cluster.CertificateAuthorityData = flags.concierge.caBundle
|
||||
}
|
||||
|
||||
// If --credential-cache is set, pass it through.
|
||||
@ -244,7 +292,7 @@ func runGetKubeconfig(ctx context.Context, out io.Writer, deps kubeconfigDeps, f
|
||||
// If one of the --static-* flags was passed, output a config that runs `pinniped login static`.
|
||||
if flags.staticToken != "" || flags.staticTokenEnvName != "" {
|
||||
if flags.staticToken != "" && flags.staticTokenEnvName != "" {
|
||||
return fmt.Errorf("only one of --static-token and --static-token-env can be specified")
|
||||
return nil, fmt.Errorf("only one of --static-token and --static-token-env can be specified")
|
||||
}
|
||||
execConfig.Args = append([]string{"login", "static"}, execConfig.Args...)
|
||||
if flags.staticToken != "" {
|
||||
@ -253,18 +301,13 @@ func runGetKubeconfig(ctx context.Context, out io.Writer, deps kubeconfigDeps, f
|
||||
if flags.staticTokenEnvName != "" {
|
||||
execConfig.Args = append(execConfig.Args, "--token-env="+flags.staticTokenEnvName)
|
||||
}
|
||||
|
||||
kubeconfig := newExecKubeconfig(cluster, &execConfig, newKubeconfigNames)
|
||||
if err := validateKubeconfig(ctx, flags, kubeconfig, deps.log); err != nil {
|
||||
return err
|
||||
}
|
||||
return writeConfigAsYAML(out, kubeconfig)
|
||||
return execConfig, nil
|
||||
}
|
||||
|
||||
// Otherwise continue to parse the OIDC-related flags and output a config that runs `pinniped login oidc`.
|
||||
execConfig.Args = append([]string{"login", "oidc"}, execConfig.Args...)
|
||||
if flags.oidc.issuer == "" {
|
||||
return fmt.Errorf("could not autodiscover --oidc-issuer and none was provided")
|
||||
return nil, fmt.Errorf("could not autodiscover --oidc-issuer and none was provided")
|
||||
}
|
||||
execConfig.Args = append(execConfig.Args,
|
||||
"--issuer="+flags.oidc.issuer,
|
||||
@ -289,11 +332,14 @@ func runGetKubeconfig(ctx context.Context, out io.Writer, deps kubeconfigDeps, f
|
||||
if flags.oidc.requestAudience != "" {
|
||||
execConfig.Args = append(execConfig.Args, "--request-audience="+flags.oidc.requestAudience)
|
||||
}
|
||||
kubeconfig := newExecKubeconfig(cluster, &execConfig, newKubeconfigNames)
|
||||
if err := validateKubeconfig(ctx, flags, kubeconfig, deps.log); err != nil {
|
||||
return err
|
||||
if flags.oidc.upstreamIDPName != "" {
|
||||
execConfig.Args = append(execConfig.Args, "--upstream-identity-provider-name="+flags.oidc.upstreamIDPName)
|
||||
}
|
||||
return writeConfigAsYAML(out, kubeconfig)
|
||||
if flags.oidc.upstreamIDPType != "" {
|
||||
execConfig.Args = append(execConfig.Args, "--upstream-identity-provider-type="+flags.oidc.upstreamIDPType)
|
||||
}
|
||||
|
||||
return execConfig, nil
|
||||
}
|
||||
|
||||
type kubeconfigNames struct{ ContextName, UserName, ClusterName string }
|
||||
@ -688,3 +734,151 @@ func hasPendingStrategy(credentialIssuer *configv1alpha1.CredentialIssuer) bool
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func discoverSupervisorUpstreamIDP(ctx context.Context, flags *getKubeconfigParams) error {
|
||||
httpClient, err := newDiscoveryHTTPClient(flags.oidc.caBundle)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pinnipedIDPsEndpoint, err := discoverIDPsDiscoveryEndpointURL(ctx, flags.oidc.issuer, httpClient)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if pinnipedIDPsEndpoint == "" {
|
||||
// The issuer is not advertising itself as a Pinniped Supervisor which supports upstream IDP discovery.
|
||||
return nil
|
||||
}
|
||||
|
||||
upstreamIDPs, err := discoverAllAvailableSupervisorUpstreamIDPs(ctx, pinnipedIDPsEndpoint, httpClient)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(upstreamIDPs) == 1 {
|
||||
flags.oidc.upstreamIDPName = upstreamIDPs[0].Name
|
||||
flags.oidc.upstreamIDPType = upstreamIDPs[0].Type
|
||||
} else if len(upstreamIDPs) > 1 {
|
||||
idpName, idpType, err := selectUpstreamIDP(upstreamIDPs, flags.oidc.upstreamIDPName, flags.oidc.upstreamIDPType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
flags.oidc.upstreamIDPName = idpName
|
||||
flags.oidc.upstreamIDPType = idpType
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func newDiscoveryHTTPClient(caBundleFlag caBundleFlag) (*http.Client, error) {
|
||||
t := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{MinVersion: tls.VersionTLS12},
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
}
|
||||
httpClient := &http.Client{Transport: t}
|
||||
if caBundleFlag != nil {
|
||||
rootCAs := x509.NewCertPool()
|
||||
ok := rootCAs.AppendCertsFromPEM(caBundleFlag)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unable to fetch OIDC discovery data from issuer: could not parse CA bundle")
|
||||
}
|
||||
t.TLSClientConfig.RootCAs = rootCAs
|
||||
}
|
||||
httpClient.Transport = transport.DebugWrappers(httpClient.Transport)
|
||||
return httpClient, nil
|
||||
}
|
||||
|
||||
func discoverIDPsDiscoveryEndpointURL(ctx context.Context, issuer string, httpClient *http.Client) (string, error) {
|
||||
discoveredProvider, err := oidc.NewProvider(oidc.ClientContext(ctx, httpClient), issuer)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("while fetching OIDC discovery data from issuer: %w", err)
|
||||
}
|
||||
|
||||
var body supervisorOIDCDiscoveryResponseWithV1Alpha1
|
||||
err = discoveredProvider.Claims(&body)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("while fetching OIDC discovery data from issuer: %w", err)
|
||||
}
|
||||
|
||||
return body.SupervisorDiscovery.PinnipedIDPsEndpoint, nil
|
||||
}
|
||||
|
||||
func discoverAllAvailableSupervisorUpstreamIDPs(ctx context.Context, pinnipedIDPsEndpoint string, httpClient *http.Client) ([]pinnipedIDPResponse, error) {
|
||||
request, err := http.NewRequestWithContext(ctx, http.MethodGet, pinnipedIDPsEndpoint, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("while forming request to IDP discovery URL: %w", err)
|
||||
}
|
||||
|
||||
response, err := httpClient.Do(request)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to fetch IDP discovery data from issuer: %w", err)
|
||||
}
|
||||
defer func() {
|
||||
_ = response.Body.Close()
|
||||
}()
|
||||
if response.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("unable to fetch IDP discovery data from issuer: unexpected http response status: %s", response.Status)
|
||||
}
|
||||
|
||||
rawBody, err := ioutil.ReadAll(response.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to fetch IDP discovery data from issuer: could not read response body: %w", err)
|
||||
}
|
||||
|
||||
var body supervisorIDPsDiscoveryResponseV1Alpha1
|
||||
err = json.Unmarshal(rawBody, &body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to fetch IDP discovery data from issuer: could not parse response JSON: %w", err)
|
||||
}
|
||||
|
||||
return body.PinnipedIDPs, nil
|
||||
}
|
||||
|
||||
func selectUpstreamIDP(pinnipedIDPs []pinnipedIDPResponse, idpName, idpType string) (string, string, error) {
|
||||
pinnipedIDPsString, _ := json.Marshal(pinnipedIDPs)
|
||||
switch {
|
||||
case idpType != "":
|
||||
discoveredName := ""
|
||||
for _, idp := range pinnipedIDPs {
|
||||
if idp.Type == idpType {
|
||||
if discoveredName != "" {
|
||||
return "", "", fmt.Errorf(
|
||||
"multiple Supervisor upstream identity providers of type \"%s\" were found,"+
|
||||
" so the --upstream-identity-provider-name flag must be specified. "+
|
||||
"Found these upstreams: %s",
|
||||
idpType, pinnipedIDPsString)
|
||||
}
|
||||
discoveredName = idp.Name
|
||||
}
|
||||
}
|
||||
if discoveredName == "" {
|
||||
return "", "", fmt.Errorf(
|
||||
"no Supervisor upstream identity providers of type \"%s\" were found."+
|
||||
" Found these upstreams: %s", idpType, pinnipedIDPsString)
|
||||
}
|
||||
return discoveredName, idpType, nil
|
||||
case idpName != "":
|
||||
discoveredType := ""
|
||||
for _, idp := range pinnipedIDPs {
|
||||
if idp.Name == idpName {
|
||||
if discoveredType != "" {
|
||||
return "", "", fmt.Errorf(
|
||||
"multiple Supervisor upstream identity providers with name \"%s\" were found,"+
|
||||
" so the --upstream-identity-provider-type flag must be specified. Found these upstreams: %s",
|
||||
idpName, pinnipedIDPsString)
|
||||
}
|
||||
discoveredType = idp.Type
|
||||
}
|
||||
}
|
||||
if discoveredType == "" {
|
||||
return "", "", fmt.Errorf(
|
||||
"no Supervisor upstream identity providers with name \"%s\" were found."+
|
||||
" Found these upstreams: %s", idpName, pinnipedIDPsString)
|
||||
}
|
||||
return idpName, discoveredType, nil
|
||||
default:
|
||||
return "", "", fmt.Errorf(
|
||||
"multiple Supervisor upstream identity providers were found,"+
|
||||
" so the --upstream-identity-provider-name/--upstream-identity-provider-type flags must be specified."+
|
||||
" Found these upstreams: %s",
|
||||
pinnipedIDPsString)
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package cmd
|
||||
|
@ -54,23 +54,25 @@ func oidcLoginCommandRealDeps() oidcLoginCommandDeps {
|
||||
}
|
||||
|
||||
type oidcLoginFlags struct {
|
||||
issuer string
|
||||
clientID string
|
||||
listenPort uint16
|
||||
scopes []string
|
||||
skipBrowser bool
|
||||
sessionCachePath string
|
||||
caBundlePaths []string
|
||||
caBundleData []string
|
||||
debugSessionCache bool
|
||||
requestAudience string
|
||||
conciergeEnabled bool
|
||||
conciergeAuthenticatorType string
|
||||
conciergeAuthenticatorName string
|
||||
conciergeEndpoint string
|
||||
conciergeCABundle string
|
||||
conciergeAPIGroupSuffix string
|
||||
credentialCachePath string
|
||||
issuer string
|
||||
clientID string
|
||||
listenPort uint16
|
||||
scopes []string
|
||||
skipBrowser bool
|
||||
sessionCachePath string
|
||||
caBundlePaths []string
|
||||
caBundleData []string
|
||||
debugSessionCache bool
|
||||
requestAudience string
|
||||
conciergeEnabled bool
|
||||
conciergeAuthenticatorType string
|
||||
conciergeAuthenticatorName string
|
||||
conciergeEndpoint string
|
||||
conciergeCABundle string
|
||||
conciergeAPIGroupSuffix string
|
||||
credentialCachePath string
|
||||
upstreamIdentityProviderName string
|
||||
upstreamIdentityProviderType string
|
||||
}
|
||||
|
||||
func oidcLoginCommand(deps oidcLoginCommandDeps) *cobra.Command {
|
||||
@ -102,6 +104,8 @@ func oidcLoginCommand(deps oidcLoginCommandDeps) *cobra.Command {
|
||||
cmd.Flags().StringVar(&flags.conciergeCABundle, "concierge-ca-bundle-data", "", "CA bundle to use when connecting to the Concierge")
|
||||
cmd.Flags().StringVar(&flags.conciergeAPIGroupSuffix, "concierge-api-group-suffix", groupsuffix.PinnipedDefaultSuffix, "Concierge API group suffix")
|
||||
cmd.Flags().StringVar(&flags.credentialCachePath, "credential-cache", filepath.Join(mustGetConfigDir(), "credentials.yaml"), "Path to cluster-specific credentials cache (\"\" disables the cache)")
|
||||
cmd.Flags().StringVar(&flags.upstreamIdentityProviderName, "upstream-identity-provider-name", "", "The name of the upstream identity provider used during login with a Supervisor")
|
||||
cmd.Flags().StringVar(&flags.upstreamIdentityProviderType, "upstream-identity-provider-type", "oidc", "The type of the upstream identity provider used during login with a Supervisor (e.g. 'oidc', 'ldap')")
|
||||
|
||||
mustMarkHidden(cmd, "debug-session-cache")
|
||||
mustMarkRequired(cmd, "issuer")
|
||||
@ -113,7 +117,7 @@ func oidcLoginCommand(deps oidcLoginCommandDeps) *cobra.Command {
|
||||
return cmd
|
||||
}
|
||||
|
||||
func runOIDCLogin(cmd *cobra.Command, deps oidcLoginCommandDeps, flags oidcLoginFlags) error {
|
||||
func runOIDCLogin(cmd *cobra.Command, deps oidcLoginCommandDeps, flags oidcLoginFlags) error { //nolint:funlen
|
||||
pLogger, err := SetLogLevel(deps.lookupEnv)
|
||||
if err != nil {
|
||||
plog.WarningErr("Received error while setting log level", err)
|
||||
@ -147,6 +151,23 @@ func runOIDCLogin(cmd *cobra.Command, deps oidcLoginCommandDeps, flags oidcLogin
|
||||
opts = append(opts, oidcclient.WithRequestAudience(flags.requestAudience))
|
||||
}
|
||||
|
||||
if flags.upstreamIdentityProviderName != "" {
|
||||
opts = append(opts, oidcclient.WithUpstreamIdentityProvider(
|
||||
flags.upstreamIdentityProviderName, flags.upstreamIdentityProviderType))
|
||||
}
|
||||
|
||||
switch flags.upstreamIdentityProviderType {
|
||||
case "oidc":
|
||||
// this is the default, so don't need to do anything
|
||||
case "ldap":
|
||||
opts = append(opts, oidcclient.WithCLISendingCredentials())
|
||||
default:
|
||||
// Surprisingly cobra does not support this kind of flag validation. See https://github.com/spf13/pflag/issues/236
|
||||
return fmt.Errorf(
|
||||
"--upstream-identity-provider-type value not recognized: %s (supported values: oidc, ldap)",
|
||||
flags.upstreamIdentityProviderType)
|
||||
}
|
||||
|
||||
var concierge *conciergeclient.Client
|
||||
if flags.conciergeEnabled {
|
||||
var err error
|
||||
|
@ -60,23 +60,25 @@ func TestLoginOIDCCommand(t *testing.T) {
|
||||
oidc --issuer ISSUER [flags]
|
||||
|
||||
Flags:
|
||||
--ca-bundle strings Path to TLS certificate authority bundle (PEM format, optional, can be repeated)
|
||||
--ca-bundle-data strings Base64 encoded TLS certificate authority bundle (base64 encoded PEM format, optional, can be repeated)
|
||||
--client-id string OpenID Connect client ID (default "pinniped-cli")
|
||||
--concierge-api-group-suffix string Concierge API group suffix (default "pinniped.dev")
|
||||
--concierge-authenticator-name string Concierge authenticator name
|
||||
--concierge-authenticator-type string Concierge authenticator type (e.g., 'webhook', 'jwt')
|
||||
--concierge-ca-bundle-data string CA bundle to use when connecting to the Concierge
|
||||
--concierge-endpoint string API base for the Concierge endpoint
|
||||
--credential-cache string Path to cluster-specific credentials cache ("" disables the cache) (default "` + cfgDir + `/credentials.yaml")
|
||||
--enable-concierge Use the Concierge to login
|
||||
-h, --help help for oidc
|
||||
--issuer string OpenID Connect issuer URL
|
||||
--listen-port uint16 TCP port for localhost listener (authorization code flow only)
|
||||
--request-audience string Request a token with an alternate audience using RFC8693 token exchange
|
||||
--scopes strings OIDC scopes to request during login (default [offline_access,openid,pinniped:request-audience])
|
||||
--session-cache string Path to session cache file (default "` + cfgDir + `/sessions.yaml")
|
||||
--skip-browser Skip opening the browser (just print the URL)
|
||||
--ca-bundle strings Path to TLS certificate authority bundle (PEM format, optional, can be repeated)
|
||||
--ca-bundle-data strings Base64 encoded TLS certificate authority bundle (base64 encoded PEM format, optional, can be repeated)
|
||||
--client-id string OpenID Connect client ID (default "pinniped-cli")
|
||||
--concierge-api-group-suffix string Concierge API group suffix (default "pinniped.dev")
|
||||
--concierge-authenticator-name string Concierge authenticator name
|
||||
--concierge-authenticator-type string Concierge authenticator type (e.g., 'webhook', 'jwt')
|
||||
--concierge-ca-bundle-data string CA bundle to use when connecting to the Concierge
|
||||
--concierge-endpoint string API base for the Concierge endpoint
|
||||
--credential-cache string Path to cluster-specific credentials cache ("" disables the cache) (default "` + cfgDir + `/credentials.yaml")
|
||||
--enable-concierge Use the Concierge to login
|
||||
-h, --help help for oidc
|
||||
--issuer string OpenID Connect issuer URL
|
||||
--listen-port uint16 TCP port for localhost listener (authorization code flow only)
|
||||
--request-audience string Request a token with an alternate audience using RFC8693 token exchange
|
||||
--scopes strings OIDC scopes to request during login (default [offline_access,openid,pinniped:request-audience])
|
||||
--session-cache string Path to session cache file (default "` + cfgDir + `/sessions.yaml")
|
||||
--skip-browser Skip opening the browser (just print the URL)
|
||||
--upstream-identity-provider-name string The name of the upstream identity provider used during login with a Supervisor
|
||||
--upstream-identity-provider-type string The type of the upstream identity provider used during login with a Supervisor (e.g. 'oidc', 'ldap') (default "oidc")
|
||||
`),
|
||||
},
|
||||
{
|
||||
@ -138,11 +140,45 @@ func TestLoginOIDCCommand(t *testing.T) {
|
||||
Error: invalid Concierge parameters: invalid API group suffix: a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')
|
||||
`),
|
||||
},
|
||||
{
|
||||
name: "invalid upstream type",
|
||||
args: []string{
|
||||
"--issuer", "test-issuer",
|
||||
"--upstream-identity-provider-type", "invalid",
|
||||
},
|
||||
wantError: true,
|
||||
wantStderr: here.Doc(`
|
||||
Error: --upstream-identity-provider-type value not recognized: invalid (supported values: oidc, ldap)
|
||||
`),
|
||||
},
|
||||
{
|
||||
name: "oidc upstream type is allowed",
|
||||
args: []string{
|
||||
"--issuer", "test-issuer",
|
||||
"--client-id", "test-client-id",
|
||||
"--upstream-identity-provider-type", "oidc",
|
||||
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
|
||||
},
|
||||
wantOptionsCount: 4,
|
||||
wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{},"status":{"expirationTimestamp":"3020-10-12T13:14:15Z","token":"test-id-token"}}` + "\n",
|
||||
},
|
||||
{
|
||||
name: "ldap upstream type is allowed",
|
||||
args: []string{
|
||||
"--issuer", "test-issuer",
|
||||
"--client-id", "test-client-id",
|
||||
"--upstream-identity-provider-type", "ldap",
|
||||
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
|
||||
},
|
||||
wantOptionsCount: 5,
|
||||
wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{},"status":{"expirationTimestamp":"3020-10-12T13:14:15Z","token":"test-id-token"}}` + "\n",
|
||||
},
|
||||
{
|
||||
name: "login error",
|
||||
args: []string{
|
||||
"--client-id", "test-client-id",
|
||||
"--issuer", "test-issuer",
|
||||
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
|
||||
},
|
||||
loginErr: fmt.Errorf("some login error"),
|
||||
wantOptionsCount: 4,
|
||||
@ -160,6 +196,7 @@ func TestLoginOIDCCommand(t *testing.T) {
|
||||
"--concierge-authenticator-type", "jwt",
|
||||
"--concierge-authenticator-name", "test-authenticator",
|
||||
"--concierge-endpoint", "https://127.0.0.1:1234/",
|
||||
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
|
||||
},
|
||||
conciergeErr: fmt.Errorf("some concierge error"),
|
||||
wantOptionsCount: 4,
|
||||
@ -173,6 +210,7 @@ func TestLoginOIDCCommand(t *testing.T) {
|
||||
args: []string{
|
||||
"--client-id", "test-client-id",
|
||||
"--issuer", "test-issuer",
|
||||
"--credential-cache", "", // must specify --credential-cache or else the cache file on disk causes test pollution
|
||||
},
|
||||
env: map[string]string{"PINNIPED_DEBUG": "true"},
|
||||
wantOptionsCount: 4,
|
||||
@ -180,7 +218,6 @@ func TestLoginOIDCCommand(t *testing.T) {
|
||||
wantLogs: []string{
|
||||
"\"level\"=0 \"msg\"=\"Pinniped login: Performing OIDC login\" \"client id\"=\"test-client-id\" \"issuer\"=\"test-issuer\"",
|
||||
"\"level\"=0 \"msg\"=\"Pinniped login: No concierge configured, skipping token credential exchange\"",
|
||||
"\"level\"=0 \"msg\"=\"Pinniped login: caching cluster credential for future use.\"",
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -200,10 +237,12 @@ func TestLoginOIDCCommand(t *testing.T) {
|
||||
"--concierge-endpoint", "https://127.0.0.1:1234/",
|
||||
"--concierge-ca-bundle-data", base64.StdEncoding.EncodeToString(testCA.Bundle()),
|
||||
"--concierge-api-group-suffix", "some.suffix.com",
|
||||
"--credential-cache", testutil.TempDir(t) + "/credentials.yaml",
|
||||
"--credential-cache", testutil.TempDir(t) + "/credentials.yaml", // must specify --credential-cache or else the cache file on disk causes test pollution
|
||||
"--upstream-identity-provider-name", "some-upstream-name",
|
||||
"--upstream-identity-provider-type", "ldap",
|
||||
},
|
||||
env: map[string]string{"PINNIPED_DEBUG": "true"},
|
||||
wantOptionsCount: 8,
|
||||
wantOptionsCount: 10,
|
||||
wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{},"status":{"token":"exchanged-token"}}` + "\n",
|
||||
wantLogs: []string{
|
||||
"\"level\"=0 \"msg\"=\"Pinniped login: Performing OIDC login\" \"client id\"=\"test-client-id\" \"issuer\"=\"test-issuer\"",
|
||||
|
@ -0,0 +1,234 @@
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.4.0
|
||||
creationTimestamp: null
|
||||
name: ldapidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
names:
|
||||
categories:
|
||||
- pinniped
|
||||
- pinniped-idp
|
||||
- pinniped-idps
|
||||
kind: LDAPIdentityProvider
|
||||
listKind: LDAPIdentityProviderList
|
||||
plural: ldapidentityproviders
|
||||
singular: ldapidentityprovider
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .spec.host
|
||||
name: Host
|
||||
type: string
|
||||
- jsonPath: .status.phase
|
||||
name: Status
|
||||
type: string
|
||||
- jsonPath: .metadata.creationTimestamp
|
||||
name: Age
|
||||
type: date
|
||||
name: v1alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: LDAPIdentityProvider describes the configuration of an upstream
|
||||
Lightweight Directory Access Protocol (LDAP) identity provider.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: Spec for configuring the identity provider.
|
||||
properties:
|
||||
bind:
|
||||
description: Bind contains the configuration for how to provide access
|
||||
credentials during an initial bind to the LDAP server to be allowed
|
||||
to perform searches and binds to validate a user's credentials during
|
||||
a user's authentication attempt.
|
||||
properties:
|
||||
secretName:
|
||||
description: SecretName contains the name of a namespace-local
|
||||
Secret object that provides the username and password for an
|
||||
LDAP bind user. This account will be used to perform LDAP searches.
|
||||
The Secret should be of type "kubernetes.io/basic-auth" which
|
||||
includes "username" and "password" keys. The username value
|
||||
should be the full DN 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
|
||||
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 attribute in the
|
||||
LDAP entry which 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 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 and will be dynamically replaced by the username
|
||||
for which the search is being run. E.g. "mail={}" or "&(objectClass=person)(uid={})".
|
||||
For more information about LDAP filters, see https://ldap.com/ldap-filters.
|
||||
Note that the dn (distinguished name) is not an attribute of
|
||||
an entry, so "dn={}" cannot be used. Optional. When not specified,
|
||||
the default will act as if the Filter were specified as the
|
||||
value from Attributes.Username appended by "={}". When the Attributes.Username
|
||||
is set to "dn" then the Filter must be explicitly specified,
|
||||
since the default value of "dn={}" would not work.
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- host
|
||||
type: object
|
||||
status:
|
||||
description: Status of the identity provider.
|
||||
properties:
|
||||
conditions:
|
||||
description: Represents the observations of an identity provider's
|
||||
current state.
|
||||
items:
|
||||
description: Condition status of a resource (mirrored from the metav1.Condition
|
||||
type added in Kubernetes 1.19). In a future API version we can
|
||||
switch to using the upstream type. See https://github.com/kubernetes/apimachinery/blob/v0.19.0/pkg/apis/meta/v1/types.go#L1353-L1413.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: lastTransitionTime is the last time the condition
|
||||
transitioned from one status to another. This should be when
|
||||
the underlying condition changed. If that is not known, then
|
||||
using the time when the API field changed is acceptable.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: message is a human readable message indicating
|
||||
details about the transition. This may be an empty string.
|
||||
maxLength: 32768
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: observedGeneration represents the .metadata.generation
|
||||
that the condition was set based upon. For instance, if .metadata.generation
|
||||
is currently 12, but the .status.conditions[x].observedGeneration
|
||||
is 9, the condition is out of date with respect to the current
|
||||
state of the instance.
|
||||
format: int64
|
||||
minimum: 0
|
||||
type: integer
|
||||
reason:
|
||||
description: reason contains a programmatic identifier indicating
|
||||
the reason for the condition's last transition. Producers
|
||||
of specific condition types may define expected values and
|
||||
meanings for this field, and whether the values are considered
|
||||
a guaranteed API. The value should be a CamelCase string.
|
||||
This field may not be empty.
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
||||
type: string
|
||||
status:
|
||||
description: status of the condition, one of True, False, Unknown.
|
||||
enum:
|
||||
- "True"
|
||||
- "False"
|
||||
- Unknown
|
||||
type: string
|
||||
type:
|
||||
description: type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||
--- Many .condition.type values are consistent across resources
|
||||
like Available, but because arbitrary conditions can be useful
|
||||
(see .node.status.conditions), the ability to deconflict is
|
||||
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- message
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
x-kubernetes-list-map-keys:
|
||||
- type
|
||||
x-kubernetes-list-type: map
|
||||
phase:
|
||||
default: Pending
|
||||
description: Phase summarizes the overall status of the LDAPIdentityProvider.
|
||||
enum:
|
||||
- Pending
|
||||
- Ready
|
||||
- Error
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- spec
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
@ -32,6 +32,14 @@ rules:
|
||||
- #@ 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]
|
||||
#! 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: [""]
|
||||
|
@ -22,3 +22,12 @@ metadata:
|
||||
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")
|
||||
|
132
generated/1.17/README.adoc
generated
132
generated/1.17/README.adoc
generated
@ -669,10 +669,11 @@ Package v1alpha1 is the v1alpha1 version of the Pinniped supervisor identity pro
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-condition"]
|
||||
==== Condition
|
||||
|
||||
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.
|
||||
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-ldapidentityproviderstatus[$$LDAPIdentityProviderStatus$$]
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-oidcidentityproviderstatus[$$OIDCIdentityProviderStatus$$]
|
||||
****
|
||||
|
||||
@ -688,6 +689,132 @@ Condition status of a resource (mirrored from the metav1.Condition type added in
|
||||
|===
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-conditionstatus"]
|
||||
==== ConditionStatus (string)
|
||||
|
||||
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-condition[$$Condition$$]
|
||||
****
|
||||
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-ldapidentityprovider"]
|
||||
==== LDAPIdentityProvider
|
||||
|
||||
LDAPIdentityProvider describes the configuration of an upstream Lightweight Directory Access Protocol (LDAP) identity provider.
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-ldapidentityproviderlist[$$LDAPIdentityProviderList$$]
|
||||
****
|
||||
|
||||
[cols="25a,75a", options="header"]
|
||||
|===
|
||||
| Field | Description
|
||||
| *`metadata`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#objectmeta-v1-meta[$$ObjectMeta$$]__ | Refer to Kubernetes API documentation for fields of `metadata`.
|
||||
|
||||
| *`spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-ldapidentityproviderspec[$$LDAPIdentityProviderSpec$$]__ | Spec for configuring the identity provider.
|
||||
| *`status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-ldapidentityproviderstatus[$$LDAPIdentityProviderStatus$$]__ | Status of the identity provider.
|
||||
|===
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-ldapidentityproviderbind"]
|
||||
==== LDAPIdentityProviderBind
|
||||
|
||||
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-ldapidentityproviderspec[$$LDAPIdentityProviderSpec$$]
|
||||
****
|
||||
|
||||
[cols="25a,75a", options="header"]
|
||||
|===
|
||||
| Field | Description
|
||||
| *`secretName`* __string__ | 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 of your bind account, e.g. "cn=bind-account,ou=users,dc=example,dc=com". The password must be non-empty.
|
||||
|===
|
||||
|
||||
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-ldapidentityproviderspec"]
|
||||
==== LDAPIdentityProviderSpec
|
||||
|
||||
Spec for configuring an LDAP identity provider.
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-ldapidentityprovider[$$LDAPIdentityProvider$$]
|
||||
****
|
||||
|
||||
[cols="25a,75a", options="header"]
|
||||
|===
|
||||
| Field | Description
|
||||
| *`host`* __string__ | Host is the hostname of this LDAP identity provider, i.e., where to connect. For example: ldap.example.com:636.
|
||||
| *`tls`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-tlsspec[$$TLSSpec$$]__ | TLS contains the connection settings for how to establish the connection to the Host.
|
||||
| *`bind`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-ldapidentityproviderbind[$$LDAPIdentityProviderBind$$]__ | 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.
|
||||
| *`userSearch`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-ldapidentityproviderusersearch[$$LDAPIdentityProviderUserSearch$$]__ | UserSearch contains the configuration for searching for a user by name in the LDAP provider.
|
||||
|===
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-ldapidentityproviderstatus"]
|
||||
==== LDAPIdentityProviderStatus
|
||||
|
||||
Status of an LDAP identity provider.
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-ldapidentityprovider[$$LDAPIdentityProvider$$]
|
||||
****
|
||||
|
||||
[cols="25a,75a", options="header"]
|
||||
|===
|
||||
| Field | Description
|
||||
| *`phase`* __LDAPIdentityProviderPhase__ | Phase summarizes the overall status of the LDAPIdentityProvider.
|
||||
| *`conditions`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-condition[$$Condition$$] array__ | Represents the observations of an identity provider's current state.
|
||||
|===
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-ldapidentityproviderusersearch"]
|
||||
==== LDAPIdentityProviderUserSearch
|
||||
|
||||
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-ldapidentityproviderspec[$$LDAPIdentityProviderSpec$$]
|
||||
****
|
||||
|
||||
[cols="25a,75a", options="header"]
|
||||
|===
|
||||
| Field | Description
|
||||
| *`base`* __string__ | Base is the DN that should be used as the search base when searching for users. E.g. "ou=users,dc=example,dc=com".
|
||||
| *`filter`* __string__ | Filter is the LDAP search filter which should be applied when searching for users. The pattern "{}" must occur in the filter 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.
|
||||
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-ldapidentityproviderusersearchattributes[$$LDAPIdentityProviderUserSearchAttributes$$]__ | Attributes specifies how the user's information should be read from the LDAP entry which was found as the result of the user search.
|
||||
|===
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-ldapidentityproviderusersearchattributes"]
|
||||
==== LDAPIdentityProviderUserSearchAttributes
|
||||
|
||||
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-ldapidentityproviderusersearch[$$LDAPIdentityProviderUserSearch$$]
|
||||
****
|
||||
|
||||
[cols="25a,75a", options="header"]
|
||||
|===
|
||||
| Field | Description
|
||||
| *`username`* __string__ | Username specifies the name of attribute in the LDAP entry which 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.
|
||||
| *`uid`* __string__ | 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".
|
||||
|===
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-oidcauthorizationconfig"]
|
||||
==== OIDCAuthorizationConfig
|
||||
|
||||
@ -797,7 +924,7 @@ Status of an OIDC identity provider.
|
||||
|===
|
||||
| Field | Description
|
||||
| *`phase`* __OIDCIdentityProviderPhase__ | Phase summarizes the overall status of the OIDCIdentityProvider.
|
||||
| *`conditions`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-condition[$$Condition$$]__ | Represents the observations of an identity provider's current state.
|
||||
| *`conditions`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-condition[$$Condition$$] array__ | Represents the observations of an identity provider's current state.
|
||||
|===
|
||||
|
||||
|
||||
@ -808,6 +935,7 @@ Status of an OIDC identity provider.
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-ldapidentityproviderspec[$$LDAPIdentityProviderSpec$$]
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-supervisor-idp-v1alpha1-oidcidentityproviderspec[$$OIDCIdentityProviderSpec$$]
|
||||
****
|
||||
|
||||
|
@ -32,6 +32,8 @@ func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&OIDCIdentityProvider{},
|
||||
&OIDCIdentityProviderList{},
|
||||
&LDAPIdentityProvider{},
|
||||
&LDAPIdentityProviderList{},
|
||||
)
|
||||
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
|
132
generated/1.17/apis/supervisor/idp/v1alpha1/types_ldapidentityprovider.go
generated
Normal file
132
generated/1.17/apis/supervisor/idp/v1alpha1/types_ldapidentityprovider.go
generated
Normal file
@ -0,0 +1,132 @@
|
||||
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
type LDAPIdentityProviderPhase string
|
||||
|
||||
const (
|
||||
// LDAPPhasePending is the default phase for newly-created LDAPIdentityProvider resources.
|
||||
LDAPPhasePending LDAPIdentityProviderPhase = "Pending"
|
||||
|
||||
// LDAPPhaseReady is the phase for an LDAPIdentityProvider resource in a healthy state.
|
||||
LDAPPhaseReady LDAPIdentityProviderPhase = "Ready"
|
||||
|
||||
// LDAPPhaseError is the phase for an LDAPIdentityProvider in an unhealthy state.
|
||||
LDAPPhaseError LDAPIdentityProviderPhase = "Error"
|
||||
)
|
||||
|
||||
// Status of an LDAP identity provider.
|
||||
type LDAPIdentityProviderStatus struct {
|
||||
// Phase summarizes the overall status of the LDAPIdentityProvider.
|
||||
// +kubebuilder:default=Pending
|
||||
// +kubebuilder:validation:Enum=Pending;Ready;Error
|
||||
Phase LDAPIdentityProviderPhase `json:"phase,omitempty"`
|
||||
|
||||
// Represents the observations of an identity provider's current state.
|
||||
// +patchMergeKey=type
|
||||
// +patchStrategy=merge
|
||||
// +listType=map
|
||||
// +listMapKey=type
|
||||
Conditions []Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
|
||||
}
|
||||
|
||||
type LDAPIdentityProviderBind struct {
|
||||
// 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 of your bind account, e.g. "cn=bind-account,ou=users,dc=example,dc=com".
|
||||
// The password must be non-empty.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
SecretName string `json:"secretName"`
|
||||
}
|
||||
|
||||
type LDAPIdentityProviderUserSearchAttributes struct {
|
||||
// Username specifies the name of attribute in the LDAP entry which 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.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
Username string `json:"username,omitempty"`
|
||||
|
||||
// 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".
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
UID string `json:"uid,omitempty"`
|
||||
}
|
||||
|
||||
type LDAPIdentityProviderUserSearch struct {
|
||||
// Base is the DN that should be used as the search base when searching for users. E.g. "ou=users,dc=example,dc=com".
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
Base string `json:"base,omitempty"`
|
||||
|
||||
// Filter is the LDAP search filter which should be applied when searching for users. The pattern "{}" must occur
|
||||
// in the filter 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.
|
||||
// +optional
|
||||
Filter string `json:"filter,omitempty"`
|
||||
|
||||
// Attributes specifies how the user's information should be read from the LDAP entry which was found as
|
||||
// the result of the user search.
|
||||
// +optional
|
||||
Attributes LDAPIdentityProviderUserSearchAttributes `json:"attributes,omitempty"`
|
||||
}
|
||||
|
||||
// Spec for configuring an LDAP identity provider.
|
||||
type LDAPIdentityProviderSpec struct {
|
||||
// Host is the hostname of this LDAP identity provider, i.e., where to connect. For example: ldap.example.com:636.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
Host string `json:"host"`
|
||||
|
||||
// TLS contains the connection settings for how to establish the connection to the Host.
|
||||
TLS *TLSSpec `json:"tls,omitempty"`
|
||||
|
||||
// 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.
|
||||
Bind LDAPIdentityProviderBind `json:"bind,omitempty"`
|
||||
|
||||
// UserSearch contains the configuration for searching for a user by name in the LDAP provider.
|
||||
UserSearch LDAPIdentityProviderUserSearch `json:"userSearch,omitempty"`
|
||||
}
|
||||
|
||||
// LDAPIdentityProvider describes the configuration of an upstream Lightweight Directory Access
|
||||
// Protocol (LDAP) identity provider.
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +kubebuilder:resource:categories=pinniped;pinniped-idp;pinniped-idps
|
||||
// +kubebuilder:printcolumn:name="Host",type=string,JSONPath=`.spec.host`
|
||||
// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.phase`
|
||||
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
|
||||
// +kubebuilder:subresource:status
|
||||
type LDAPIdentityProvider struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Spec for configuring the identity provider.
|
||||
Spec LDAPIdentityProviderSpec `json:"spec"`
|
||||
|
||||
// Status of the identity provider.
|
||||
Status LDAPIdentityProviderStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// List of LDAPIdentityProvider objects.
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type LDAPIdentityProviderList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
Items []LDAPIdentityProvider `json:"items"`
|
||||
}
|
@ -28,6 +28,162 @@ func (in *Condition) DeepCopy() *Condition {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LDAPIdentityProvider) DeepCopyInto(out *LDAPIdentityProvider) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LDAPIdentityProvider.
|
||||
func (in *LDAPIdentityProvider) DeepCopy() *LDAPIdentityProvider {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LDAPIdentityProvider)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *LDAPIdentityProvider) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LDAPIdentityProviderBind) DeepCopyInto(out *LDAPIdentityProviderBind) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LDAPIdentityProviderBind.
|
||||
func (in *LDAPIdentityProviderBind) DeepCopy() *LDAPIdentityProviderBind {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LDAPIdentityProviderBind)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LDAPIdentityProviderList) DeepCopyInto(out *LDAPIdentityProviderList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]LDAPIdentityProvider, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LDAPIdentityProviderList.
|
||||
func (in *LDAPIdentityProviderList) DeepCopy() *LDAPIdentityProviderList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LDAPIdentityProviderList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *LDAPIdentityProviderList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LDAPIdentityProviderSpec) DeepCopyInto(out *LDAPIdentityProviderSpec) {
|
||||
*out = *in
|
||||
if in.TLS != nil {
|
||||
in, out := &in.TLS, &out.TLS
|
||||
*out = new(TLSSpec)
|
||||
**out = **in
|
||||
}
|
||||
out.Bind = in.Bind
|
||||
out.UserSearch = in.UserSearch
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LDAPIdentityProviderSpec.
|
||||
func (in *LDAPIdentityProviderSpec) DeepCopy() *LDAPIdentityProviderSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LDAPIdentityProviderSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LDAPIdentityProviderStatus) DeepCopyInto(out *LDAPIdentityProviderStatus) {
|
||||
*out = *in
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = make([]Condition, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LDAPIdentityProviderStatus.
|
||||
func (in *LDAPIdentityProviderStatus) DeepCopy() *LDAPIdentityProviderStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LDAPIdentityProviderStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LDAPIdentityProviderUserSearch) DeepCopyInto(out *LDAPIdentityProviderUserSearch) {
|
||||
*out = *in
|
||||
out.Attributes = in.Attributes
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LDAPIdentityProviderUserSearch.
|
||||
func (in *LDAPIdentityProviderUserSearch) DeepCopy() *LDAPIdentityProviderUserSearch {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LDAPIdentityProviderUserSearch)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LDAPIdentityProviderUserSearchAttributes) DeepCopyInto(out *LDAPIdentityProviderUserSearchAttributes) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LDAPIdentityProviderUserSearchAttributes.
|
||||
func (in *LDAPIdentityProviderUserSearchAttributes) DeepCopy() *LDAPIdentityProviderUserSearchAttributes {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LDAPIdentityProviderUserSearchAttributes)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *OIDCAuthorizationConfig) DeepCopyInto(out *OIDCAuthorizationConfig) {
|
||||
*out = *in
|
||||
|
@ -15,6 +15,10 @@ type FakeIDPV1alpha1 struct {
|
||||
*testing.Fake
|
||||
}
|
||||
|
||||
func (c *FakeIDPV1alpha1) LDAPIdentityProviders(namespace string) v1alpha1.LDAPIdentityProviderInterface {
|
||||
return &FakeLDAPIdentityProviders{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeIDPV1alpha1) OIDCIdentityProviders(namespace string) v1alpha1.OIDCIdentityProviderInterface {
|
||||
return &FakeOIDCIdentityProviders{c, namespace}
|
||||
}
|
||||
|
@ -0,0 +1,127 @@
|
||||
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
v1alpha1 "go.pinniped.dev/generated/1.17/apis/supervisor/idp/v1alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
// FakeLDAPIdentityProviders implements LDAPIdentityProviderInterface
|
||||
type FakeLDAPIdentityProviders struct {
|
||||
Fake *FakeIDPV1alpha1
|
||||
ns string
|
||||
}
|
||||
|
||||
var ldapidentityprovidersResource = schema.GroupVersionResource{Group: "idp.supervisor.pinniped.dev", Version: "v1alpha1", Resource: "ldapidentityproviders"}
|
||||
|
||||
var ldapidentityprovidersKind = schema.GroupVersionKind{Group: "idp.supervisor.pinniped.dev", Version: "v1alpha1", Kind: "LDAPIdentityProvider"}
|
||||
|
||||
// Get takes name of the lDAPIdentityProvider, and returns the corresponding lDAPIdentityProvider object, and an error if there is any.
|
||||
func (c *FakeLDAPIdentityProviders) Get(name string, options v1.GetOptions) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewGetAction(ldapidentityprovidersResource, c.ns, name), &v1alpha1.LDAPIdentityProvider{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.LDAPIdentityProvider), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of LDAPIdentityProviders that match those selectors.
|
||||
func (c *FakeLDAPIdentityProviders) List(opts v1.ListOptions) (result *v1alpha1.LDAPIdentityProviderList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewListAction(ldapidentityprovidersResource, ldapidentityprovidersKind, c.ns, opts), &v1alpha1.LDAPIdentityProviderList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1alpha1.LDAPIdentityProviderList{ListMeta: obj.(*v1alpha1.LDAPIdentityProviderList).ListMeta}
|
||||
for _, item := range obj.(*v1alpha1.LDAPIdentityProviderList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested lDAPIdentityProviders.
|
||||
func (c *FakeLDAPIdentityProviders) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewWatchAction(ldapidentityprovidersResource, c.ns, opts))
|
||||
|
||||
}
|
||||
|
||||
// Create takes the representation of a lDAPIdentityProvider and creates it. Returns the server's representation of the lDAPIdentityProvider, and an error, if there is any.
|
||||
func (c *FakeLDAPIdentityProviders) Create(lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewCreateAction(ldapidentityprovidersResource, c.ns, lDAPIdentityProvider), &v1alpha1.LDAPIdentityProvider{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.LDAPIdentityProvider), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a lDAPIdentityProvider and updates it. Returns the server's representation of the lDAPIdentityProvider, and an error, if there is any.
|
||||
func (c *FakeLDAPIdentityProviders) Update(lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateAction(ldapidentityprovidersResource, c.ns, lDAPIdentityProvider), &v1alpha1.LDAPIdentityProvider{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.LDAPIdentityProvider), err
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *FakeLDAPIdentityProviders) UpdateStatus(lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider) (*v1alpha1.LDAPIdentityProvider, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateSubresourceAction(ldapidentityprovidersResource, "status", c.ns, lDAPIdentityProvider), &v1alpha1.LDAPIdentityProvider{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.LDAPIdentityProvider), err
|
||||
}
|
||||
|
||||
// Delete takes name of the lDAPIdentityProvider and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeLDAPIdentityProviders) Delete(name string, options *v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewDeleteAction(ldapidentityprovidersResource, c.ns, name), &v1alpha1.LDAPIdentityProvider{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakeLDAPIdentityProviders) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
||||
action := testing.NewDeleteCollectionAction(ldapidentityprovidersResource, c.ns, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1alpha1.LDAPIdentityProviderList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched lDAPIdentityProvider.
|
||||
func (c *FakeLDAPIdentityProviders) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewPatchSubresourceAction(ldapidentityprovidersResource, c.ns, name, pt, data, subresources...), &v1alpha1.LDAPIdentityProvider{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.LDAPIdentityProvider), err
|
||||
}
|
@ -5,4 +5,6 @@
|
||||
|
||||
package v1alpha1
|
||||
|
||||
type LDAPIdentityProviderExpansion interface{}
|
||||
|
||||
type OIDCIdentityProviderExpansion interface{}
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
|
||||
type IDPV1alpha1Interface interface {
|
||||
RESTClient() rest.Interface
|
||||
LDAPIdentityProvidersGetter
|
||||
OIDCIdentityProvidersGetter
|
||||
}
|
||||
|
||||
@ -21,6 +22,10 @@ type IDPV1alpha1Client struct {
|
||||
restClient rest.Interface
|
||||
}
|
||||
|
||||
func (c *IDPV1alpha1Client) LDAPIdentityProviders(namespace string) LDAPIdentityProviderInterface {
|
||||
return newLDAPIdentityProviders(c, namespace)
|
||||
}
|
||||
|
||||
func (c *IDPV1alpha1Client) OIDCIdentityProviders(namespace string) OIDCIdentityProviderInterface {
|
||||
return newOIDCIdentityProviders(c, namespace)
|
||||
}
|
||||
|
178
generated/1.17/client/supervisor/clientset/versioned/typed/idp/v1alpha1/ldapidentityprovider.go
generated
Normal file
178
generated/1.17/client/supervisor/clientset/versioned/typed/idp/v1alpha1/ldapidentityprovider.go
generated
Normal file
@ -0,0 +1,178 @@
|
||||
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
v1alpha1 "go.pinniped.dev/generated/1.17/apis/supervisor/idp/v1alpha1"
|
||||
scheme "go.pinniped.dev/generated/1.17/client/supervisor/clientset/versioned/scheme"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// LDAPIdentityProvidersGetter has a method to return a LDAPIdentityProviderInterface.
|
||||
// A group's client should implement this interface.
|
||||
type LDAPIdentityProvidersGetter interface {
|
||||
LDAPIdentityProviders(namespace string) LDAPIdentityProviderInterface
|
||||
}
|
||||
|
||||
// LDAPIdentityProviderInterface has methods to work with LDAPIdentityProvider resources.
|
||||
type LDAPIdentityProviderInterface interface {
|
||||
Create(*v1alpha1.LDAPIdentityProvider) (*v1alpha1.LDAPIdentityProvider, error)
|
||||
Update(*v1alpha1.LDAPIdentityProvider) (*v1alpha1.LDAPIdentityProvider, error)
|
||||
UpdateStatus(*v1alpha1.LDAPIdentityProvider) (*v1alpha1.LDAPIdentityProvider, error)
|
||||
Delete(name string, options *v1.DeleteOptions) error
|
||||
DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
|
||||
Get(name string, options v1.GetOptions) (*v1alpha1.LDAPIdentityProvider, error)
|
||||
List(opts v1.ListOptions) (*v1alpha1.LDAPIdentityProviderList, error)
|
||||
Watch(opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.LDAPIdentityProvider, err error)
|
||||
LDAPIdentityProviderExpansion
|
||||
}
|
||||
|
||||
// lDAPIdentityProviders implements LDAPIdentityProviderInterface
|
||||
type lDAPIdentityProviders struct {
|
||||
client rest.Interface
|
||||
ns string
|
||||
}
|
||||
|
||||
// newLDAPIdentityProviders returns a LDAPIdentityProviders
|
||||
func newLDAPIdentityProviders(c *IDPV1alpha1Client, namespace string) *lDAPIdentityProviders {
|
||||
return &lDAPIdentityProviders{
|
||||
client: c.RESTClient(),
|
||||
ns: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the lDAPIdentityProvider, and returns the corresponding lDAPIdentityProvider object, and an error if there is any.
|
||||
func (c *lDAPIdentityProviders) Get(name string, options v1.GetOptions) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
result = &v1alpha1.LDAPIdentityProvider{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of LDAPIdentityProviders that match those selectors.
|
||||
func (c *lDAPIdentityProviders) List(opts v1.ListOptions) (result *v1alpha1.LDAPIdentityProviderList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1alpha1.LDAPIdentityProviderList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested lDAPIdentityProviders.
|
||||
func (c *lDAPIdentityProviders) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
opts.Watch = true
|
||||
return c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch()
|
||||
}
|
||||
|
||||
// Create takes the representation of a lDAPIdentityProvider and creates it. Returns the server's representation of the lDAPIdentityProvider, and an error, if there is any.
|
||||
func (c *lDAPIdentityProviders) Create(lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
result = &v1alpha1.LDAPIdentityProvider{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
Body(lDAPIdentityProvider).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a lDAPIdentityProvider and updates it. Returns the server's representation of the lDAPIdentityProvider, and an error, if there is any.
|
||||
func (c *lDAPIdentityProviders) Update(lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
result = &v1alpha1.LDAPIdentityProvider{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
Name(lDAPIdentityProvider.Name).
|
||||
Body(lDAPIdentityProvider).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
|
||||
func (c *lDAPIdentityProviders) UpdateStatus(lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
result = &v1alpha1.LDAPIdentityProvider{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
Name(lDAPIdentityProvider.Name).
|
||||
SubResource("status").
|
||||
Body(lDAPIdentityProvider).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the lDAPIdentityProvider and deletes it. Returns an error if one occurs.
|
||||
func (c *lDAPIdentityProviders) Delete(name string, options *v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *lDAPIdentityProviders) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
||||
var timeout time.Duration
|
||||
if listOptions.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second
|
||||
}
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
VersionedParams(&listOptions, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched lDAPIdentityProvider.
|
||||
func (c *lDAPIdentityProviders) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
result = &v1alpha1.LDAPIdentityProvider{}
|
||||
err = c.client.Patch(pt).
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
SubResource(subresources...).
|
||||
Name(name).
|
||||
Body(data).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
@ -45,6 +45,8 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Config().V1alpha1().FederationDomains().Informer()}, nil
|
||||
|
||||
// Group=idp.supervisor.pinniped.dev, Version=v1alpha1
|
||||
case idpv1alpha1.SchemeGroupVersion.WithResource("ldapidentityproviders"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.IDP().V1alpha1().LDAPIdentityProviders().Informer()}, nil
|
||||
case idpv1alpha1.SchemeGroupVersion.WithResource("oidcidentityproviders"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.IDP().V1alpha1().OIDCIdentityProviders().Informer()}, nil
|
||||
|
||||
|
@ -11,6 +11,8 @@ import (
|
||||
|
||||
// Interface provides access to all the informers in this group version.
|
||||
type Interface interface {
|
||||
// LDAPIdentityProviders returns a LDAPIdentityProviderInformer.
|
||||
LDAPIdentityProviders() LDAPIdentityProviderInformer
|
||||
// OIDCIdentityProviders returns a OIDCIdentityProviderInformer.
|
||||
OIDCIdentityProviders() OIDCIdentityProviderInformer
|
||||
}
|
||||
@ -26,6 +28,11 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList
|
||||
return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
||||
}
|
||||
|
||||
// LDAPIdentityProviders returns a LDAPIdentityProviderInformer.
|
||||
func (v *version) LDAPIdentityProviders() LDAPIdentityProviderInformer {
|
||||
return &lDAPIdentityProviderInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
|
||||
// OIDCIdentityProviders returns a OIDCIdentityProviderInformer.
|
||||
func (v *version) OIDCIdentityProviders() OIDCIdentityProviderInformer {
|
||||
return &oIDCIdentityProviderInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
|
||||
|
76
generated/1.17/client/supervisor/informers/externalversions/idp/v1alpha1/ldapidentityprovider.go
generated
Normal file
76
generated/1.17/client/supervisor/informers/externalversions/idp/v1alpha1/ldapidentityprovider.go
generated
Normal file
@ -0,0 +1,76 @@
|
||||
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
time "time"
|
||||
|
||||
idpv1alpha1 "go.pinniped.dev/generated/1.17/apis/supervisor/idp/v1alpha1"
|
||||
versioned "go.pinniped.dev/generated/1.17/client/supervisor/clientset/versioned"
|
||||
internalinterfaces "go.pinniped.dev/generated/1.17/client/supervisor/informers/externalversions/internalinterfaces"
|
||||
v1alpha1 "go.pinniped.dev/generated/1.17/client/supervisor/listers/idp/v1alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// LDAPIdentityProviderInformer provides access to a shared informer and lister for
|
||||
// LDAPIdentityProviders.
|
||||
type LDAPIdentityProviderInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v1alpha1.LDAPIdentityProviderLister
|
||||
}
|
||||
|
||||
type lDAPIdentityProviderInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
namespace string
|
||||
}
|
||||
|
||||
// NewLDAPIdentityProviderInformer constructs a new informer for LDAPIdentityProvider type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewLDAPIdentityProviderInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredLDAPIdentityProviderInformer(client, namespace, resyncPeriod, indexers, nil)
|
||||
}
|
||||
|
||||
// NewFilteredLDAPIdentityProviderInformer constructs a new informer for LDAPIdentityProvider type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewFilteredLDAPIdentityProviderInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.IDPV1alpha1().LDAPIdentityProviders(namespace).List(options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.IDPV1alpha1().LDAPIdentityProviders(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&idpv1alpha1.LDAPIdentityProvider{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
}
|
||||
|
||||
func (f *lDAPIdentityProviderInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredLDAPIdentityProviderInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *lDAPIdentityProviderInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&idpv1alpha1.LDAPIdentityProvider{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *lDAPIdentityProviderInformer) Lister() v1alpha1.LDAPIdentityProviderLister {
|
||||
return v1alpha1.NewLDAPIdentityProviderLister(f.Informer().GetIndexer())
|
||||
}
|
@ -5,6 +5,14 @@
|
||||
|
||||
package v1alpha1
|
||||
|
||||
// LDAPIdentityProviderListerExpansion allows custom methods to be added to
|
||||
// LDAPIdentityProviderLister.
|
||||
type LDAPIdentityProviderListerExpansion interface{}
|
||||
|
||||
// LDAPIdentityProviderNamespaceListerExpansion allows custom methods to be added to
|
||||
// LDAPIdentityProviderNamespaceLister.
|
||||
type LDAPIdentityProviderNamespaceListerExpansion interface{}
|
||||
|
||||
// OIDCIdentityProviderListerExpansion allows custom methods to be added to
|
||||
// OIDCIdentityProviderLister.
|
||||
type OIDCIdentityProviderListerExpansion interface{}
|
||||
|
81
generated/1.17/client/supervisor/listers/idp/v1alpha1/ldapidentityprovider.go
generated
Normal file
81
generated/1.17/client/supervisor/listers/idp/v1alpha1/ldapidentityprovider.go
generated
Normal file
@ -0,0 +1,81 @@
|
||||
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
v1alpha1 "go.pinniped.dev/generated/1.17/apis/supervisor/idp/v1alpha1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// LDAPIdentityProviderLister helps list LDAPIdentityProviders.
|
||||
type LDAPIdentityProviderLister interface {
|
||||
// List lists all LDAPIdentityProviders in the indexer.
|
||||
List(selector labels.Selector) (ret []*v1alpha1.LDAPIdentityProvider, err error)
|
||||
// LDAPIdentityProviders returns an object that can list and get LDAPIdentityProviders.
|
||||
LDAPIdentityProviders(namespace string) LDAPIdentityProviderNamespaceLister
|
||||
LDAPIdentityProviderListerExpansion
|
||||
}
|
||||
|
||||
// lDAPIdentityProviderLister implements the LDAPIdentityProviderLister interface.
|
||||
type lDAPIdentityProviderLister struct {
|
||||
indexer cache.Indexer
|
||||
}
|
||||
|
||||
// NewLDAPIdentityProviderLister returns a new LDAPIdentityProviderLister.
|
||||
func NewLDAPIdentityProviderLister(indexer cache.Indexer) LDAPIdentityProviderLister {
|
||||
return &lDAPIdentityProviderLister{indexer: indexer}
|
||||
}
|
||||
|
||||
// List lists all LDAPIdentityProviders in the indexer.
|
||||
func (s *lDAPIdentityProviderLister) List(selector labels.Selector) (ret []*v1alpha1.LDAPIdentityProvider, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1alpha1.LDAPIdentityProvider))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// LDAPIdentityProviders returns an object that can list and get LDAPIdentityProviders.
|
||||
func (s *lDAPIdentityProviderLister) LDAPIdentityProviders(namespace string) LDAPIdentityProviderNamespaceLister {
|
||||
return lDAPIdentityProviderNamespaceLister{indexer: s.indexer, namespace: namespace}
|
||||
}
|
||||
|
||||
// LDAPIdentityProviderNamespaceLister helps list and get LDAPIdentityProviders.
|
||||
type LDAPIdentityProviderNamespaceLister interface {
|
||||
// List lists all LDAPIdentityProviders in the indexer for a given namespace.
|
||||
List(selector labels.Selector) (ret []*v1alpha1.LDAPIdentityProvider, err error)
|
||||
// Get retrieves the LDAPIdentityProvider from the indexer for a given namespace and name.
|
||||
Get(name string) (*v1alpha1.LDAPIdentityProvider, error)
|
||||
LDAPIdentityProviderNamespaceListerExpansion
|
||||
}
|
||||
|
||||
// lDAPIdentityProviderNamespaceLister implements the LDAPIdentityProviderNamespaceLister
|
||||
// interface.
|
||||
type lDAPIdentityProviderNamespaceLister struct {
|
||||
indexer cache.Indexer
|
||||
namespace string
|
||||
}
|
||||
|
||||
// List lists all LDAPIdentityProviders in the indexer for a given namespace.
|
||||
func (s lDAPIdentityProviderNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.LDAPIdentityProvider, err error) {
|
||||
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1alpha1.LDAPIdentityProvider))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the LDAPIdentityProvider from the indexer for a given namespace and name.
|
||||
func (s lDAPIdentityProviderNamespaceLister) Get(name string) (*v1alpha1.LDAPIdentityProvider, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v1alpha1.Resource("ldapidentityprovider"), name)
|
||||
}
|
||||
return obj.(*v1alpha1.LDAPIdentityProvider), nil
|
||||
}
|
234
generated/1.17/crds/idp.supervisor.pinniped.dev_ldapidentityproviders.yaml
generated
Normal file
234
generated/1.17/crds/idp.supervisor.pinniped.dev_ldapidentityproviders.yaml
generated
Normal file
@ -0,0 +1,234 @@
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.4.0
|
||||
creationTimestamp: null
|
||||
name: ldapidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
names:
|
||||
categories:
|
||||
- pinniped
|
||||
- pinniped-idp
|
||||
- pinniped-idps
|
||||
kind: LDAPIdentityProvider
|
||||
listKind: LDAPIdentityProviderList
|
||||
plural: ldapidentityproviders
|
||||
singular: ldapidentityprovider
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .spec.host
|
||||
name: Host
|
||||
type: string
|
||||
- jsonPath: .status.phase
|
||||
name: Status
|
||||
type: string
|
||||
- jsonPath: .metadata.creationTimestamp
|
||||
name: Age
|
||||
type: date
|
||||
name: v1alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: LDAPIdentityProvider describes the configuration of an upstream
|
||||
Lightweight Directory Access Protocol (LDAP) identity provider.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: Spec for configuring the identity provider.
|
||||
properties:
|
||||
bind:
|
||||
description: Bind contains the configuration for how to provide access
|
||||
credentials during an initial bind to the LDAP server to be allowed
|
||||
to perform searches and binds to validate a user's credentials during
|
||||
a user's authentication attempt.
|
||||
properties:
|
||||
secretName:
|
||||
description: SecretName contains the name of a namespace-local
|
||||
Secret object that provides the username and password for an
|
||||
LDAP bind user. This account will be used to perform LDAP searches.
|
||||
The Secret should be of type "kubernetes.io/basic-auth" which
|
||||
includes "username" and "password" keys. The username value
|
||||
should be the full DN 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
|
||||
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 attribute in the
|
||||
LDAP entry which 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 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 and will be dynamically replaced by the username
|
||||
for which the search is being run. E.g. "mail={}" or "&(objectClass=person)(uid={})".
|
||||
For more information about LDAP filters, see https://ldap.com/ldap-filters.
|
||||
Note that the dn (distinguished name) is not an attribute of
|
||||
an entry, so "dn={}" cannot be used. Optional. When not specified,
|
||||
the default will act as if the Filter were specified as the
|
||||
value from Attributes.Username appended by "={}". When the Attributes.Username
|
||||
is set to "dn" then the Filter must be explicitly specified,
|
||||
since the default value of "dn={}" would not work.
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- host
|
||||
type: object
|
||||
status:
|
||||
description: Status of the identity provider.
|
||||
properties:
|
||||
conditions:
|
||||
description: Represents the observations of an identity provider's
|
||||
current state.
|
||||
items:
|
||||
description: Condition status of a resource (mirrored from the metav1.Condition
|
||||
type added in Kubernetes 1.19). In a future API version we can
|
||||
switch to using the upstream type. See https://github.com/kubernetes/apimachinery/blob/v0.19.0/pkg/apis/meta/v1/types.go#L1353-L1413.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: lastTransitionTime is the last time the condition
|
||||
transitioned from one status to another. This should be when
|
||||
the underlying condition changed. If that is not known, then
|
||||
using the time when the API field changed is acceptable.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: message is a human readable message indicating
|
||||
details about the transition. This may be an empty string.
|
||||
maxLength: 32768
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: observedGeneration represents the .metadata.generation
|
||||
that the condition was set based upon. For instance, if .metadata.generation
|
||||
is currently 12, but the .status.conditions[x].observedGeneration
|
||||
is 9, the condition is out of date with respect to the current
|
||||
state of the instance.
|
||||
format: int64
|
||||
minimum: 0
|
||||
type: integer
|
||||
reason:
|
||||
description: reason contains a programmatic identifier indicating
|
||||
the reason for the condition's last transition. Producers
|
||||
of specific condition types may define expected values and
|
||||
meanings for this field, and whether the values are considered
|
||||
a guaranteed API. The value should be a CamelCase string.
|
||||
This field may not be empty.
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
||||
type: string
|
||||
status:
|
||||
description: status of the condition, one of True, False, Unknown.
|
||||
enum:
|
||||
- "True"
|
||||
- "False"
|
||||
- Unknown
|
||||
type: string
|
||||
type:
|
||||
description: type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||
--- Many .condition.type values are consistent across resources
|
||||
like Available, but because arbitrary conditions can be useful
|
||||
(see .node.status.conditions), the ability to deconflict is
|
||||
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- message
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
x-kubernetes-list-map-keys:
|
||||
- type
|
||||
x-kubernetes-list-type: map
|
||||
phase:
|
||||
default: Pending
|
||||
description: Phase summarizes the overall status of the LDAPIdentityProvider.
|
||||
enum:
|
||||
- Pending
|
||||
- Ready
|
||||
- Error
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- spec
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
132
generated/1.18/README.adoc
generated
132
generated/1.18/README.adoc
generated
@ -669,10 +669,11 @@ Package v1alpha1 is the v1alpha1 version of the Pinniped supervisor identity pro
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-supervisor-idp-v1alpha1-condition"]
|
||||
==== Condition
|
||||
|
||||
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.
|
||||
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-supervisor-idp-v1alpha1-ldapidentityproviderstatus[$$LDAPIdentityProviderStatus$$]
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-supervisor-idp-v1alpha1-oidcidentityproviderstatus[$$OIDCIdentityProviderStatus$$]
|
||||
****
|
||||
|
||||
@ -688,6 +689,132 @@ Condition status of a resource (mirrored from the metav1.Condition type added in
|
||||
|===
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-supervisor-idp-v1alpha1-conditionstatus"]
|
||||
==== ConditionStatus (string)
|
||||
|
||||
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-supervisor-idp-v1alpha1-condition[$$Condition$$]
|
||||
****
|
||||
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-supervisor-idp-v1alpha1-ldapidentityprovider"]
|
||||
==== LDAPIdentityProvider
|
||||
|
||||
LDAPIdentityProvider describes the configuration of an upstream Lightweight Directory Access Protocol (LDAP) identity provider.
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-supervisor-idp-v1alpha1-ldapidentityproviderlist[$$LDAPIdentityProviderList$$]
|
||||
****
|
||||
|
||||
[cols="25a,75a", options="header"]
|
||||
|===
|
||||
| Field | Description
|
||||
| *`metadata`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#objectmeta-v1-meta[$$ObjectMeta$$]__ | Refer to Kubernetes API documentation for fields of `metadata`.
|
||||
|
||||
| *`spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-supervisor-idp-v1alpha1-ldapidentityproviderspec[$$LDAPIdentityProviderSpec$$]__ | Spec for configuring the identity provider.
|
||||
| *`status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-supervisor-idp-v1alpha1-ldapidentityproviderstatus[$$LDAPIdentityProviderStatus$$]__ | Status of the identity provider.
|
||||
|===
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-supervisor-idp-v1alpha1-ldapidentityproviderbind"]
|
||||
==== LDAPIdentityProviderBind
|
||||
|
||||
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-supervisor-idp-v1alpha1-ldapidentityproviderspec[$$LDAPIdentityProviderSpec$$]
|
||||
****
|
||||
|
||||
[cols="25a,75a", options="header"]
|
||||
|===
|
||||
| Field | Description
|
||||
| *`secretName`* __string__ | 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 of your bind account, e.g. "cn=bind-account,ou=users,dc=example,dc=com". The password must be non-empty.
|
||||
|===
|
||||
|
||||
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-supervisor-idp-v1alpha1-ldapidentityproviderspec"]
|
||||
==== LDAPIdentityProviderSpec
|
||||
|
||||
Spec for configuring an LDAP identity provider.
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-supervisor-idp-v1alpha1-ldapidentityprovider[$$LDAPIdentityProvider$$]
|
||||
****
|
||||
|
||||
[cols="25a,75a", options="header"]
|
||||
|===
|
||||
| Field | Description
|
||||
| *`host`* __string__ | Host is the hostname of this LDAP identity provider, i.e., where to connect. For example: ldap.example.com:636.
|
||||
| *`tls`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-supervisor-idp-v1alpha1-tlsspec[$$TLSSpec$$]__ | TLS contains the connection settings for how to establish the connection to the Host.
|
||||
| *`bind`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-supervisor-idp-v1alpha1-ldapidentityproviderbind[$$LDAPIdentityProviderBind$$]__ | 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.
|
||||
| *`userSearch`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-supervisor-idp-v1alpha1-ldapidentityproviderusersearch[$$LDAPIdentityProviderUserSearch$$]__ | UserSearch contains the configuration for searching for a user by name in the LDAP provider.
|
||||
|===
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-supervisor-idp-v1alpha1-ldapidentityproviderstatus"]
|
||||
==== LDAPIdentityProviderStatus
|
||||
|
||||
Status of an LDAP identity provider.
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-supervisor-idp-v1alpha1-ldapidentityprovider[$$LDAPIdentityProvider$$]
|
||||
****
|
||||
|
||||
[cols="25a,75a", options="header"]
|
||||
|===
|
||||
| Field | Description
|
||||
| *`phase`* __LDAPIdentityProviderPhase__ | Phase summarizes the overall status of the LDAPIdentityProvider.
|
||||
| *`conditions`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-supervisor-idp-v1alpha1-condition[$$Condition$$] array__ | Represents the observations of an identity provider's current state.
|
||||
|===
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-supervisor-idp-v1alpha1-ldapidentityproviderusersearch"]
|
||||
==== LDAPIdentityProviderUserSearch
|
||||
|
||||
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-supervisor-idp-v1alpha1-ldapidentityproviderspec[$$LDAPIdentityProviderSpec$$]
|
||||
****
|
||||
|
||||
[cols="25a,75a", options="header"]
|
||||
|===
|
||||
| Field | Description
|
||||
| *`base`* __string__ | Base is the DN that should be used as the search base when searching for users. E.g. "ou=users,dc=example,dc=com".
|
||||
| *`filter`* __string__ | Filter is the LDAP search filter which should be applied when searching for users. The pattern "{}" must occur in the filter 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.
|
||||
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-supervisor-idp-v1alpha1-ldapidentityproviderusersearchattributes[$$LDAPIdentityProviderUserSearchAttributes$$]__ | Attributes specifies how the user's information should be read from the LDAP entry which was found as the result of the user search.
|
||||
|===
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-supervisor-idp-v1alpha1-ldapidentityproviderusersearchattributes"]
|
||||
==== LDAPIdentityProviderUserSearchAttributes
|
||||
|
||||
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-supervisor-idp-v1alpha1-ldapidentityproviderusersearch[$$LDAPIdentityProviderUserSearch$$]
|
||||
****
|
||||
|
||||
[cols="25a,75a", options="header"]
|
||||
|===
|
||||
| Field | Description
|
||||
| *`username`* __string__ | Username specifies the name of attribute in the LDAP entry which 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.
|
||||
| *`uid`* __string__ | 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".
|
||||
|===
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-supervisor-idp-v1alpha1-oidcauthorizationconfig"]
|
||||
==== OIDCAuthorizationConfig
|
||||
|
||||
@ -797,7 +924,7 @@ Status of an OIDC identity provider.
|
||||
|===
|
||||
| Field | Description
|
||||
| *`phase`* __OIDCIdentityProviderPhase__ | Phase summarizes the overall status of the OIDCIdentityProvider.
|
||||
| *`conditions`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-supervisor-idp-v1alpha1-condition[$$Condition$$]__ | Represents the observations of an identity provider's current state.
|
||||
| *`conditions`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-supervisor-idp-v1alpha1-condition[$$Condition$$] array__ | Represents the observations of an identity provider's current state.
|
||||
|===
|
||||
|
||||
|
||||
@ -808,6 +935,7 @@ Status of an OIDC identity provider.
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-supervisor-idp-v1alpha1-ldapidentityproviderspec[$$LDAPIdentityProviderSpec$$]
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-supervisor-idp-v1alpha1-oidcidentityproviderspec[$$OIDCIdentityProviderSpec$$]
|
||||
****
|
||||
|
||||
|
@ -32,6 +32,8 @@ func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&OIDCIdentityProvider{},
|
||||
&OIDCIdentityProviderList{},
|
||||
&LDAPIdentityProvider{},
|
||||
&LDAPIdentityProviderList{},
|
||||
)
|
||||
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
|
132
generated/1.18/apis/supervisor/idp/v1alpha1/types_ldapidentityprovider.go
generated
Normal file
132
generated/1.18/apis/supervisor/idp/v1alpha1/types_ldapidentityprovider.go
generated
Normal file
@ -0,0 +1,132 @@
|
||||
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
type LDAPIdentityProviderPhase string
|
||||
|
||||
const (
|
||||
// LDAPPhasePending is the default phase for newly-created LDAPIdentityProvider resources.
|
||||
LDAPPhasePending LDAPIdentityProviderPhase = "Pending"
|
||||
|
||||
// LDAPPhaseReady is the phase for an LDAPIdentityProvider resource in a healthy state.
|
||||
LDAPPhaseReady LDAPIdentityProviderPhase = "Ready"
|
||||
|
||||
// LDAPPhaseError is the phase for an LDAPIdentityProvider in an unhealthy state.
|
||||
LDAPPhaseError LDAPIdentityProviderPhase = "Error"
|
||||
)
|
||||
|
||||
// Status of an LDAP identity provider.
|
||||
type LDAPIdentityProviderStatus struct {
|
||||
// Phase summarizes the overall status of the LDAPIdentityProvider.
|
||||
// +kubebuilder:default=Pending
|
||||
// +kubebuilder:validation:Enum=Pending;Ready;Error
|
||||
Phase LDAPIdentityProviderPhase `json:"phase,omitempty"`
|
||||
|
||||
// Represents the observations of an identity provider's current state.
|
||||
// +patchMergeKey=type
|
||||
// +patchStrategy=merge
|
||||
// +listType=map
|
||||
// +listMapKey=type
|
||||
Conditions []Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
|
||||
}
|
||||
|
||||
type LDAPIdentityProviderBind struct {
|
||||
// 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 of your bind account, e.g. "cn=bind-account,ou=users,dc=example,dc=com".
|
||||
// The password must be non-empty.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
SecretName string `json:"secretName"`
|
||||
}
|
||||
|
||||
type LDAPIdentityProviderUserSearchAttributes struct {
|
||||
// Username specifies the name of attribute in the LDAP entry which 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.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
Username string `json:"username,omitempty"`
|
||||
|
||||
// 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".
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
UID string `json:"uid,omitempty"`
|
||||
}
|
||||
|
||||
type LDAPIdentityProviderUserSearch struct {
|
||||
// Base is the DN that should be used as the search base when searching for users. E.g. "ou=users,dc=example,dc=com".
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
Base string `json:"base,omitempty"`
|
||||
|
||||
// Filter is the LDAP search filter which should be applied when searching for users. The pattern "{}" must occur
|
||||
// in the filter 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.
|
||||
// +optional
|
||||
Filter string `json:"filter,omitempty"`
|
||||
|
||||
// Attributes specifies how the user's information should be read from the LDAP entry which was found as
|
||||
// the result of the user search.
|
||||
// +optional
|
||||
Attributes LDAPIdentityProviderUserSearchAttributes `json:"attributes,omitempty"`
|
||||
}
|
||||
|
||||
// Spec for configuring an LDAP identity provider.
|
||||
type LDAPIdentityProviderSpec struct {
|
||||
// Host is the hostname of this LDAP identity provider, i.e., where to connect. For example: ldap.example.com:636.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
Host string `json:"host"`
|
||||
|
||||
// TLS contains the connection settings for how to establish the connection to the Host.
|
||||
TLS *TLSSpec `json:"tls,omitempty"`
|
||||
|
||||
// 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.
|
||||
Bind LDAPIdentityProviderBind `json:"bind,omitempty"`
|
||||
|
||||
// UserSearch contains the configuration for searching for a user by name in the LDAP provider.
|
||||
UserSearch LDAPIdentityProviderUserSearch `json:"userSearch,omitempty"`
|
||||
}
|
||||
|
||||
// LDAPIdentityProvider describes the configuration of an upstream Lightweight Directory Access
|
||||
// Protocol (LDAP) identity provider.
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +kubebuilder:resource:categories=pinniped;pinniped-idp;pinniped-idps
|
||||
// +kubebuilder:printcolumn:name="Host",type=string,JSONPath=`.spec.host`
|
||||
// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.phase`
|
||||
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
|
||||
// +kubebuilder:subresource:status
|
||||
type LDAPIdentityProvider struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Spec for configuring the identity provider.
|
||||
Spec LDAPIdentityProviderSpec `json:"spec"`
|
||||
|
||||
// Status of the identity provider.
|
||||
Status LDAPIdentityProviderStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// List of LDAPIdentityProvider objects.
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type LDAPIdentityProviderList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
Items []LDAPIdentityProvider `json:"items"`
|
||||
}
|
@ -28,6 +28,162 @@ func (in *Condition) DeepCopy() *Condition {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LDAPIdentityProvider) DeepCopyInto(out *LDAPIdentityProvider) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LDAPIdentityProvider.
|
||||
func (in *LDAPIdentityProvider) DeepCopy() *LDAPIdentityProvider {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LDAPIdentityProvider)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *LDAPIdentityProvider) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LDAPIdentityProviderBind) DeepCopyInto(out *LDAPIdentityProviderBind) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LDAPIdentityProviderBind.
|
||||
func (in *LDAPIdentityProviderBind) DeepCopy() *LDAPIdentityProviderBind {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LDAPIdentityProviderBind)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LDAPIdentityProviderList) DeepCopyInto(out *LDAPIdentityProviderList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]LDAPIdentityProvider, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LDAPIdentityProviderList.
|
||||
func (in *LDAPIdentityProviderList) DeepCopy() *LDAPIdentityProviderList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LDAPIdentityProviderList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *LDAPIdentityProviderList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LDAPIdentityProviderSpec) DeepCopyInto(out *LDAPIdentityProviderSpec) {
|
||||
*out = *in
|
||||
if in.TLS != nil {
|
||||
in, out := &in.TLS, &out.TLS
|
||||
*out = new(TLSSpec)
|
||||
**out = **in
|
||||
}
|
||||
out.Bind = in.Bind
|
||||
out.UserSearch = in.UserSearch
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LDAPIdentityProviderSpec.
|
||||
func (in *LDAPIdentityProviderSpec) DeepCopy() *LDAPIdentityProviderSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LDAPIdentityProviderSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LDAPIdentityProviderStatus) DeepCopyInto(out *LDAPIdentityProviderStatus) {
|
||||
*out = *in
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = make([]Condition, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LDAPIdentityProviderStatus.
|
||||
func (in *LDAPIdentityProviderStatus) DeepCopy() *LDAPIdentityProviderStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LDAPIdentityProviderStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LDAPIdentityProviderUserSearch) DeepCopyInto(out *LDAPIdentityProviderUserSearch) {
|
||||
*out = *in
|
||||
out.Attributes = in.Attributes
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LDAPIdentityProviderUserSearch.
|
||||
func (in *LDAPIdentityProviderUserSearch) DeepCopy() *LDAPIdentityProviderUserSearch {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LDAPIdentityProviderUserSearch)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LDAPIdentityProviderUserSearchAttributes) DeepCopyInto(out *LDAPIdentityProviderUserSearchAttributes) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LDAPIdentityProviderUserSearchAttributes.
|
||||
func (in *LDAPIdentityProviderUserSearchAttributes) DeepCopy() *LDAPIdentityProviderUserSearchAttributes {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LDAPIdentityProviderUserSearchAttributes)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *OIDCAuthorizationConfig) DeepCopyInto(out *OIDCAuthorizationConfig) {
|
||||
*out = *in
|
||||
|
@ -15,6 +15,10 @@ type FakeIDPV1alpha1 struct {
|
||||
*testing.Fake
|
||||
}
|
||||
|
||||
func (c *FakeIDPV1alpha1) LDAPIdentityProviders(namespace string) v1alpha1.LDAPIdentityProviderInterface {
|
||||
return &FakeLDAPIdentityProviders{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeIDPV1alpha1) OIDCIdentityProviders(namespace string) v1alpha1.OIDCIdentityProviderInterface {
|
||||
return &FakeOIDCIdentityProviders{c, namespace}
|
||||
}
|
||||
|
@ -0,0 +1,129 @@
|
||||
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
v1alpha1 "go.pinniped.dev/generated/1.18/apis/supervisor/idp/v1alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
// FakeLDAPIdentityProviders implements LDAPIdentityProviderInterface
|
||||
type FakeLDAPIdentityProviders struct {
|
||||
Fake *FakeIDPV1alpha1
|
||||
ns string
|
||||
}
|
||||
|
||||
var ldapidentityprovidersResource = schema.GroupVersionResource{Group: "idp.supervisor.pinniped.dev", Version: "v1alpha1", Resource: "ldapidentityproviders"}
|
||||
|
||||
var ldapidentityprovidersKind = schema.GroupVersionKind{Group: "idp.supervisor.pinniped.dev", Version: "v1alpha1", Kind: "LDAPIdentityProvider"}
|
||||
|
||||
// Get takes name of the lDAPIdentityProvider, and returns the corresponding lDAPIdentityProvider object, and an error if there is any.
|
||||
func (c *FakeLDAPIdentityProviders) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewGetAction(ldapidentityprovidersResource, c.ns, name), &v1alpha1.LDAPIdentityProvider{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.LDAPIdentityProvider), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of LDAPIdentityProviders that match those selectors.
|
||||
func (c *FakeLDAPIdentityProviders) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.LDAPIdentityProviderList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewListAction(ldapidentityprovidersResource, ldapidentityprovidersKind, c.ns, opts), &v1alpha1.LDAPIdentityProviderList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1alpha1.LDAPIdentityProviderList{ListMeta: obj.(*v1alpha1.LDAPIdentityProviderList).ListMeta}
|
||||
for _, item := range obj.(*v1alpha1.LDAPIdentityProviderList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested lDAPIdentityProviders.
|
||||
func (c *FakeLDAPIdentityProviders) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewWatchAction(ldapidentityprovidersResource, c.ns, opts))
|
||||
|
||||
}
|
||||
|
||||
// Create takes the representation of a lDAPIdentityProvider and creates it. Returns the server's representation of the lDAPIdentityProvider, and an error, if there is any.
|
||||
func (c *FakeLDAPIdentityProviders) Create(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.CreateOptions) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewCreateAction(ldapidentityprovidersResource, c.ns, lDAPIdentityProvider), &v1alpha1.LDAPIdentityProvider{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.LDAPIdentityProvider), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a lDAPIdentityProvider and updates it. Returns the server's representation of the lDAPIdentityProvider, and an error, if there is any.
|
||||
func (c *FakeLDAPIdentityProviders) Update(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.UpdateOptions) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateAction(ldapidentityprovidersResource, c.ns, lDAPIdentityProvider), &v1alpha1.LDAPIdentityProvider{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.LDAPIdentityProvider), err
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *FakeLDAPIdentityProviders) UpdateStatus(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.UpdateOptions) (*v1alpha1.LDAPIdentityProvider, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateSubresourceAction(ldapidentityprovidersResource, "status", c.ns, lDAPIdentityProvider), &v1alpha1.LDAPIdentityProvider{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.LDAPIdentityProvider), err
|
||||
}
|
||||
|
||||
// Delete takes name of the lDAPIdentityProvider and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeLDAPIdentityProviders) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewDeleteAction(ldapidentityprovidersResource, c.ns, name), &v1alpha1.LDAPIdentityProvider{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakeLDAPIdentityProviders) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
action := testing.NewDeleteCollectionAction(ldapidentityprovidersResource, c.ns, listOpts)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1alpha1.LDAPIdentityProviderList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched lDAPIdentityProvider.
|
||||
func (c *FakeLDAPIdentityProviders) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewPatchSubresourceAction(ldapidentityprovidersResource, c.ns, name, pt, data, subresources...), &v1alpha1.LDAPIdentityProvider{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.LDAPIdentityProvider), err
|
||||
}
|
@ -5,4 +5,6 @@
|
||||
|
||||
package v1alpha1
|
||||
|
||||
type LDAPIdentityProviderExpansion interface{}
|
||||
|
||||
type OIDCIdentityProviderExpansion interface{}
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
|
||||
type IDPV1alpha1Interface interface {
|
||||
RESTClient() rest.Interface
|
||||
LDAPIdentityProvidersGetter
|
||||
OIDCIdentityProvidersGetter
|
||||
}
|
||||
|
||||
@ -21,6 +22,10 @@ type IDPV1alpha1Client struct {
|
||||
restClient rest.Interface
|
||||
}
|
||||
|
||||
func (c *IDPV1alpha1Client) LDAPIdentityProviders(namespace string) LDAPIdentityProviderInterface {
|
||||
return newLDAPIdentityProviders(c, namespace)
|
||||
}
|
||||
|
||||
func (c *IDPV1alpha1Client) OIDCIdentityProviders(namespace string) OIDCIdentityProviderInterface {
|
||||
return newOIDCIdentityProviders(c, namespace)
|
||||
}
|
||||
|
182
generated/1.18/client/supervisor/clientset/versioned/typed/idp/v1alpha1/ldapidentityprovider.go
generated
Normal file
182
generated/1.18/client/supervisor/clientset/versioned/typed/idp/v1alpha1/ldapidentityprovider.go
generated
Normal file
@ -0,0 +1,182 @@
|
||||
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
v1alpha1 "go.pinniped.dev/generated/1.18/apis/supervisor/idp/v1alpha1"
|
||||
scheme "go.pinniped.dev/generated/1.18/client/supervisor/clientset/versioned/scheme"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// LDAPIdentityProvidersGetter has a method to return a LDAPIdentityProviderInterface.
|
||||
// A group's client should implement this interface.
|
||||
type LDAPIdentityProvidersGetter interface {
|
||||
LDAPIdentityProviders(namespace string) LDAPIdentityProviderInterface
|
||||
}
|
||||
|
||||
// LDAPIdentityProviderInterface has methods to work with LDAPIdentityProvider resources.
|
||||
type LDAPIdentityProviderInterface interface {
|
||||
Create(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.CreateOptions) (*v1alpha1.LDAPIdentityProvider, error)
|
||||
Update(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.UpdateOptions) (*v1alpha1.LDAPIdentityProvider, error)
|
||||
UpdateStatus(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.UpdateOptions) (*v1alpha1.LDAPIdentityProvider, error)
|
||||
Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
|
||||
DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
|
||||
Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.LDAPIdentityProvider, error)
|
||||
List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.LDAPIdentityProviderList, error)
|
||||
Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.LDAPIdentityProvider, err error)
|
||||
LDAPIdentityProviderExpansion
|
||||
}
|
||||
|
||||
// lDAPIdentityProviders implements LDAPIdentityProviderInterface
|
||||
type lDAPIdentityProviders struct {
|
||||
client rest.Interface
|
||||
ns string
|
||||
}
|
||||
|
||||
// newLDAPIdentityProviders returns a LDAPIdentityProviders
|
||||
func newLDAPIdentityProviders(c *IDPV1alpha1Client, namespace string) *lDAPIdentityProviders {
|
||||
return &lDAPIdentityProviders{
|
||||
client: c.RESTClient(),
|
||||
ns: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the lDAPIdentityProvider, and returns the corresponding lDAPIdentityProvider object, and an error if there is any.
|
||||
func (c *lDAPIdentityProviders) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
result = &v1alpha1.LDAPIdentityProvider{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of LDAPIdentityProviders that match those selectors.
|
||||
func (c *lDAPIdentityProviders) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.LDAPIdentityProviderList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1alpha1.LDAPIdentityProviderList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested lDAPIdentityProviders.
|
||||
func (c *lDAPIdentityProviders) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
opts.Watch = true
|
||||
return c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch(ctx)
|
||||
}
|
||||
|
||||
// Create takes the representation of a lDAPIdentityProvider and creates it. Returns the server's representation of the lDAPIdentityProvider, and an error, if there is any.
|
||||
func (c *lDAPIdentityProviders) Create(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.CreateOptions) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
result = &v1alpha1.LDAPIdentityProvider{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(lDAPIdentityProvider).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a lDAPIdentityProvider and updates it. Returns the server's representation of the lDAPIdentityProvider, and an error, if there is any.
|
||||
func (c *lDAPIdentityProviders) Update(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.UpdateOptions) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
result = &v1alpha1.LDAPIdentityProvider{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
Name(lDAPIdentityProvider.Name).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(lDAPIdentityProvider).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *lDAPIdentityProviders) UpdateStatus(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.UpdateOptions) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
result = &v1alpha1.LDAPIdentityProvider{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
Name(lDAPIdentityProvider.Name).
|
||||
SubResource("status").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(lDAPIdentityProvider).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the lDAPIdentityProvider and deletes it. Returns an error if one occurs.
|
||||
func (c *lDAPIdentityProviders) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
Name(name).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *lDAPIdentityProviders) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
var timeout time.Duration
|
||||
if listOpts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
VersionedParams(&listOpts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched lDAPIdentityProvider.
|
||||
func (c *lDAPIdentityProviders) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
result = &v1alpha1.LDAPIdentityProvider{}
|
||||
err = c.client.Patch(pt).
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
Name(name).
|
||||
SubResource(subresources...).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(data).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
@ -45,6 +45,8 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Config().V1alpha1().FederationDomains().Informer()}, nil
|
||||
|
||||
// Group=idp.supervisor.pinniped.dev, Version=v1alpha1
|
||||
case idpv1alpha1.SchemeGroupVersion.WithResource("ldapidentityproviders"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.IDP().V1alpha1().LDAPIdentityProviders().Informer()}, nil
|
||||
case idpv1alpha1.SchemeGroupVersion.WithResource("oidcidentityproviders"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.IDP().V1alpha1().OIDCIdentityProviders().Informer()}, nil
|
||||
|
||||
|
@ -11,6 +11,8 @@ import (
|
||||
|
||||
// Interface provides access to all the informers in this group version.
|
||||
type Interface interface {
|
||||
// LDAPIdentityProviders returns a LDAPIdentityProviderInformer.
|
||||
LDAPIdentityProviders() LDAPIdentityProviderInformer
|
||||
// OIDCIdentityProviders returns a OIDCIdentityProviderInformer.
|
||||
OIDCIdentityProviders() OIDCIdentityProviderInformer
|
||||
}
|
||||
@ -26,6 +28,11 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList
|
||||
return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
||||
}
|
||||
|
||||
// LDAPIdentityProviders returns a LDAPIdentityProviderInformer.
|
||||
func (v *version) LDAPIdentityProviders() LDAPIdentityProviderInformer {
|
||||
return &lDAPIdentityProviderInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
|
||||
// OIDCIdentityProviders returns a OIDCIdentityProviderInformer.
|
||||
func (v *version) OIDCIdentityProviders() OIDCIdentityProviderInformer {
|
||||
return &oIDCIdentityProviderInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
|
||||
|
77
generated/1.18/client/supervisor/informers/externalversions/idp/v1alpha1/ldapidentityprovider.go
generated
Normal file
77
generated/1.18/client/supervisor/informers/externalversions/idp/v1alpha1/ldapidentityprovider.go
generated
Normal file
@ -0,0 +1,77 @@
|
||||
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
time "time"
|
||||
|
||||
idpv1alpha1 "go.pinniped.dev/generated/1.18/apis/supervisor/idp/v1alpha1"
|
||||
versioned "go.pinniped.dev/generated/1.18/client/supervisor/clientset/versioned"
|
||||
internalinterfaces "go.pinniped.dev/generated/1.18/client/supervisor/informers/externalversions/internalinterfaces"
|
||||
v1alpha1 "go.pinniped.dev/generated/1.18/client/supervisor/listers/idp/v1alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// LDAPIdentityProviderInformer provides access to a shared informer and lister for
|
||||
// LDAPIdentityProviders.
|
||||
type LDAPIdentityProviderInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v1alpha1.LDAPIdentityProviderLister
|
||||
}
|
||||
|
||||
type lDAPIdentityProviderInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
namespace string
|
||||
}
|
||||
|
||||
// NewLDAPIdentityProviderInformer constructs a new informer for LDAPIdentityProvider type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewLDAPIdentityProviderInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredLDAPIdentityProviderInformer(client, namespace, resyncPeriod, indexers, nil)
|
||||
}
|
||||
|
||||
// NewFilteredLDAPIdentityProviderInformer constructs a new informer for LDAPIdentityProvider type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewFilteredLDAPIdentityProviderInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.IDPV1alpha1().LDAPIdentityProviders(namespace).List(context.TODO(), options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.IDPV1alpha1().LDAPIdentityProviders(namespace).Watch(context.TODO(), options)
|
||||
},
|
||||
},
|
||||
&idpv1alpha1.LDAPIdentityProvider{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
}
|
||||
|
||||
func (f *lDAPIdentityProviderInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredLDAPIdentityProviderInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *lDAPIdentityProviderInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&idpv1alpha1.LDAPIdentityProvider{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *lDAPIdentityProviderInformer) Lister() v1alpha1.LDAPIdentityProviderLister {
|
||||
return v1alpha1.NewLDAPIdentityProviderLister(f.Informer().GetIndexer())
|
||||
}
|
@ -5,6 +5,14 @@
|
||||
|
||||
package v1alpha1
|
||||
|
||||
// LDAPIdentityProviderListerExpansion allows custom methods to be added to
|
||||
// LDAPIdentityProviderLister.
|
||||
type LDAPIdentityProviderListerExpansion interface{}
|
||||
|
||||
// LDAPIdentityProviderNamespaceListerExpansion allows custom methods to be added to
|
||||
// LDAPIdentityProviderNamespaceLister.
|
||||
type LDAPIdentityProviderNamespaceListerExpansion interface{}
|
||||
|
||||
// OIDCIdentityProviderListerExpansion allows custom methods to be added to
|
||||
// OIDCIdentityProviderLister.
|
||||
type OIDCIdentityProviderListerExpansion interface{}
|
||||
|
81
generated/1.18/client/supervisor/listers/idp/v1alpha1/ldapidentityprovider.go
generated
Normal file
81
generated/1.18/client/supervisor/listers/idp/v1alpha1/ldapidentityprovider.go
generated
Normal file
@ -0,0 +1,81 @@
|
||||
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
v1alpha1 "go.pinniped.dev/generated/1.18/apis/supervisor/idp/v1alpha1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// LDAPIdentityProviderLister helps list LDAPIdentityProviders.
|
||||
type LDAPIdentityProviderLister interface {
|
||||
// List lists all LDAPIdentityProviders in the indexer.
|
||||
List(selector labels.Selector) (ret []*v1alpha1.LDAPIdentityProvider, err error)
|
||||
// LDAPIdentityProviders returns an object that can list and get LDAPIdentityProviders.
|
||||
LDAPIdentityProviders(namespace string) LDAPIdentityProviderNamespaceLister
|
||||
LDAPIdentityProviderListerExpansion
|
||||
}
|
||||
|
||||
// lDAPIdentityProviderLister implements the LDAPIdentityProviderLister interface.
|
||||
type lDAPIdentityProviderLister struct {
|
||||
indexer cache.Indexer
|
||||
}
|
||||
|
||||
// NewLDAPIdentityProviderLister returns a new LDAPIdentityProviderLister.
|
||||
func NewLDAPIdentityProviderLister(indexer cache.Indexer) LDAPIdentityProviderLister {
|
||||
return &lDAPIdentityProviderLister{indexer: indexer}
|
||||
}
|
||||
|
||||
// List lists all LDAPIdentityProviders in the indexer.
|
||||
func (s *lDAPIdentityProviderLister) List(selector labels.Selector) (ret []*v1alpha1.LDAPIdentityProvider, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1alpha1.LDAPIdentityProvider))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// LDAPIdentityProviders returns an object that can list and get LDAPIdentityProviders.
|
||||
func (s *lDAPIdentityProviderLister) LDAPIdentityProviders(namespace string) LDAPIdentityProviderNamespaceLister {
|
||||
return lDAPIdentityProviderNamespaceLister{indexer: s.indexer, namespace: namespace}
|
||||
}
|
||||
|
||||
// LDAPIdentityProviderNamespaceLister helps list and get LDAPIdentityProviders.
|
||||
type LDAPIdentityProviderNamespaceLister interface {
|
||||
// List lists all LDAPIdentityProviders in the indexer for a given namespace.
|
||||
List(selector labels.Selector) (ret []*v1alpha1.LDAPIdentityProvider, err error)
|
||||
// Get retrieves the LDAPIdentityProvider from the indexer for a given namespace and name.
|
||||
Get(name string) (*v1alpha1.LDAPIdentityProvider, error)
|
||||
LDAPIdentityProviderNamespaceListerExpansion
|
||||
}
|
||||
|
||||
// lDAPIdentityProviderNamespaceLister implements the LDAPIdentityProviderNamespaceLister
|
||||
// interface.
|
||||
type lDAPIdentityProviderNamespaceLister struct {
|
||||
indexer cache.Indexer
|
||||
namespace string
|
||||
}
|
||||
|
||||
// List lists all LDAPIdentityProviders in the indexer for a given namespace.
|
||||
func (s lDAPIdentityProviderNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.LDAPIdentityProvider, err error) {
|
||||
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1alpha1.LDAPIdentityProvider))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the LDAPIdentityProvider from the indexer for a given namespace and name.
|
||||
func (s lDAPIdentityProviderNamespaceLister) Get(name string) (*v1alpha1.LDAPIdentityProvider, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v1alpha1.Resource("ldapidentityprovider"), name)
|
||||
}
|
||||
return obj.(*v1alpha1.LDAPIdentityProvider), nil
|
||||
}
|
234
generated/1.18/crds/idp.supervisor.pinniped.dev_ldapidentityproviders.yaml
generated
Normal file
234
generated/1.18/crds/idp.supervisor.pinniped.dev_ldapidentityproviders.yaml
generated
Normal file
@ -0,0 +1,234 @@
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.4.0
|
||||
creationTimestamp: null
|
||||
name: ldapidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
names:
|
||||
categories:
|
||||
- pinniped
|
||||
- pinniped-idp
|
||||
- pinniped-idps
|
||||
kind: LDAPIdentityProvider
|
||||
listKind: LDAPIdentityProviderList
|
||||
plural: ldapidentityproviders
|
||||
singular: ldapidentityprovider
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .spec.host
|
||||
name: Host
|
||||
type: string
|
||||
- jsonPath: .status.phase
|
||||
name: Status
|
||||
type: string
|
||||
- jsonPath: .metadata.creationTimestamp
|
||||
name: Age
|
||||
type: date
|
||||
name: v1alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: LDAPIdentityProvider describes the configuration of an upstream
|
||||
Lightweight Directory Access Protocol (LDAP) identity provider.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: Spec for configuring the identity provider.
|
||||
properties:
|
||||
bind:
|
||||
description: Bind contains the configuration for how to provide access
|
||||
credentials during an initial bind to the LDAP server to be allowed
|
||||
to perform searches and binds to validate a user's credentials during
|
||||
a user's authentication attempt.
|
||||
properties:
|
||||
secretName:
|
||||
description: SecretName contains the name of a namespace-local
|
||||
Secret object that provides the username and password for an
|
||||
LDAP bind user. This account will be used to perform LDAP searches.
|
||||
The Secret should be of type "kubernetes.io/basic-auth" which
|
||||
includes "username" and "password" keys. The username value
|
||||
should be the full DN 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
|
||||
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 attribute in the
|
||||
LDAP entry which 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 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 and will be dynamically replaced by the username
|
||||
for which the search is being run. E.g. "mail={}" or "&(objectClass=person)(uid={})".
|
||||
For more information about LDAP filters, see https://ldap.com/ldap-filters.
|
||||
Note that the dn (distinguished name) is not an attribute of
|
||||
an entry, so "dn={}" cannot be used. Optional. When not specified,
|
||||
the default will act as if the Filter were specified as the
|
||||
value from Attributes.Username appended by "={}". When the Attributes.Username
|
||||
is set to "dn" then the Filter must be explicitly specified,
|
||||
since the default value of "dn={}" would not work.
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- host
|
||||
type: object
|
||||
status:
|
||||
description: Status of the identity provider.
|
||||
properties:
|
||||
conditions:
|
||||
description: Represents the observations of an identity provider's
|
||||
current state.
|
||||
items:
|
||||
description: Condition status of a resource (mirrored from the metav1.Condition
|
||||
type added in Kubernetes 1.19). In a future API version we can
|
||||
switch to using the upstream type. See https://github.com/kubernetes/apimachinery/blob/v0.19.0/pkg/apis/meta/v1/types.go#L1353-L1413.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: lastTransitionTime is the last time the condition
|
||||
transitioned from one status to another. This should be when
|
||||
the underlying condition changed. If that is not known, then
|
||||
using the time when the API field changed is acceptable.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: message is a human readable message indicating
|
||||
details about the transition. This may be an empty string.
|
||||
maxLength: 32768
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: observedGeneration represents the .metadata.generation
|
||||
that the condition was set based upon. For instance, if .metadata.generation
|
||||
is currently 12, but the .status.conditions[x].observedGeneration
|
||||
is 9, the condition is out of date with respect to the current
|
||||
state of the instance.
|
||||
format: int64
|
||||
minimum: 0
|
||||
type: integer
|
||||
reason:
|
||||
description: reason contains a programmatic identifier indicating
|
||||
the reason for the condition's last transition. Producers
|
||||
of specific condition types may define expected values and
|
||||
meanings for this field, and whether the values are considered
|
||||
a guaranteed API. The value should be a CamelCase string.
|
||||
This field may not be empty.
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
||||
type: string
|
||||
status:
|
||||
description: status of the condition, one of True, False, Unknown.
|
||||
enum:
|
||||
- "True"
|
||||
- "False"
|
||||
- Unknown
|
||||
type: string
|
||||
type:
|
||||
description: type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||
--- Many .condition.type values are consistent across resources
|
||||
like Available, but because arbitrary conditions can be useful
|
||||
(see .node.status.conditions), the ability to deconflict is
|
||||
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- message
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
x-kubernetes-list-map-keys:
|
||||
- type
|
||||
x-kubernetes-list-type: map
|
||||
phase:
|
||||
default: Pending
|
||||
description: Phase summarizes the overall status of the LDAPIdentityProvider.
|
||||
enum:
|
||||
- Pending
|
||||
- Ready
|
||||
- Error
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- spec
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
132
generated/1.19/README.adoc
generated
132
generated/1.19/README.adoc
generated
@ -669,10 +669,11 @@ Package v1alpha1 is the v1alpha1 version of the Pinniped supervisor identity pro
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-supervisor-idp-v1alpha1-condition"]
|
||||
==== Condition
|
||||
|
||||
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.
|
||||
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-supervisor-idp-v1alpha1-ldapidentityproviderstatus[$$LDAPIdentityProviderStatus$$]
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-supervisor-idp-v1alpha1-oidcidentityproviderstatus[$$OIDCIdentityProviderStatus$$]
|
||||
****
|
||||
|
||||
@ -688,6 +689,132 @@ Condition status of a resource (mirrored from the metav1.Condition type added in
|
||||
|===
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-supervisor-idp-v1alpha1-conditionstatus"]
|
||||
==== ConditionStatus (string)
|
||||
|
||||
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-supervisor-idp-v1alpha1-condition[$$Condition$$]
|
||||
****
|
||||
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-supervisor-idp-v1alpha1-ldapidentityprovider"]
|
||||
==== LDAPIdentityProvider
|
||||
|
||||
LDAPIdentityProvider describes the configuration of an upstream Lightweight Directory Access Protocol (LDAP) identity provider.
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-supervisor-idp-v1alpha1-ldapidentityproviderlist[$$LDAPIdentityProviderList$$]
|
||||
****
|
||||
|
||||
[cols="25a,75a", options="header"]
|
||||
|===
|
||||
| Field | Description
|
||||
| *`metadata`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#objectmeta-v1-meta[$$ObjectMeta$$]__ | Refer to Kubernetes API documentation for fields of `metadata`.
|
||||
|
||||
| *`spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-supervisor-idp-v1alpha1-ldapidentityproviderspec[$$LDAPIdentityProviderSpec$$]__ | Spec for configuring the identity provider.
|
||||
| *`status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-supervisor-idp-v1alpha1-ldapidentityproviderstatus[$$LDAPIdentityProviderStatus$$]__ | Status of the identity provider.
|
||||
|===
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-supervisor-idp-v1alpha1-ldapidentityproviderbind"]
|
||||
==== LDAPIdentityProviderBind
|
||||
|
||||
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-supervisor-idp-v1alpha1-ldapidentityproviderspec[$$LDAPIdentityProviderSpec$$]
|
||||
****
|
||||
|
||||
[cols="25a,75a", options="header"]
|
||||
|===
|
||||
| Field | Description
|
||||
| *`secretName`* __string__ | 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 of your bind account, e.g. "cn=bind-account,ou=users,dc=example,dc=com". The password must be non-empty.
|
||||
|===
|
||||
|
||||
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-supervisor-idp-v1alpha1-ldapidentityproviderspec"]
|
||||
==== LDAPIdentityProviderSpec
|
||||
|
||||
Spec for configuring an LDAP identity provider.
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-supervisor-idp-v1alpha1-ldapidentityprovider[$$LDAPIdentityProvider$$]
|
||||
****
|
||||
|
||||
[cols="25a,75a", options="header"]
|
||||
|===
|
||||
| Field | Description
|
||||
| *`host`* __string__ | Host is the hostname of this LDAP identity provider, i.e., where to connect. For example: ldap.example.com:636.
|
||||
| *`tls`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-supervisor-idp-v1alpha1-tlsspec[$$TLSSpec$$]__ | TLS contains the connection settings for how to establish the connection to the Host.
|
||||
| *`bind`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-supervisor-idp-v1alpha1-ldapidentityproviderbind[$$LDAPIdentityProviderBind$$]__ | 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.
|
||||
| *`userSearch`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-supervisor-idp-v1alpha1-ldapidentityproviderusersearch[$$LDAPIdentityProviderUserSearch$$]__ | UserSearch contains the configuration for searching for a user by name in the LDAP provider.
|
||||
|===
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-supervisor-idp-v1alpha1-ldapidentityproviderstatus"]
|
||||
==== LDAPIdentityProviderStatus
|
||||
|
||||
Status of an LDAP identity provider.
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-supervisor-idp-v1alpha1-ldapidentityprovider[$$LDAPIdentityProvider$$]
|
||||
****
|
||||
|
||||
[cols="25a,75a", options="header"]
|
||||
|===
|
||||
| Field | Description
|
||||
| *`phase`* __LDAPIdentityProviderPhase__ | Phase summarizes the overall status of the LDAPIdentityProvider.
|
||||
| *`conditions`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-supervisor-idp-v1alpha1-condition[$$Condition$$] array__ | Represents the observations of an identity provider's current state.
|
||||
|===
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-supervisor-idp-v1alpha1-ldapidentityproviderusersearch"]
|
||||
==== LDAPIdentityProviderUserSearch
|
||||
|
||||
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-supervisor-idp-v1alpha1-ldapidentityproviderspec[$$LDAPIdentityProviderSpec$$]
|
||||
****
|
||||
|
||||
[cols="25a,75a", options="header"]
|
||||
|===
|
||||
| Field | Description
|
||||
| *`base`* __string__ | Base is the DN that should be used as the search base when searching for users. E.g. "ou=users,dc=example,dc=com".
|
||||
| *`filter`* __string__ | Filter is the LDAP search filter which should be applied when searching for users. The pattern "{}" must occur in the filter 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.
|
||||
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-supervisor-idp-v1alpha1-ldapidentityproviderusersearchattributes[$$LDAPIdentityProviderUserSearchAttributes$$]__ | Attributes specifies how the user's information should be read from the LDAP entry which was found as the result of the user search.
|
||||
|===
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-supervisor-idp-v1alpha1-ldapidentityproviderusersearchattributes"]
|
||||
==== LDAPIdentityProviderUserSearchAttributes
|
||||
|
||||
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-supervisor-idp-v1alpha1-ldapidentityproviderusersearch[$$LDAPIdentityProviderUserSearch$$]
|
||||
****
|
||||
|
||||
[cols="25a,75a", options="header"]
|
||||
|===
|
||||
| Field | Description
|
||||
| *`username`* __string__ | Username specifies the name of attribute in the LDAP entry which 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.
|
||||
| *`uid`* __string__ | 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".
|
||||
|===
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-supervisor-idp-v1alpha1-oidcauthorizationconfig"]
|
||||
==== OIDCAuthorizationConfig
|
||||
|
||||
@ -797,7 +924,7 @@ Status of an OIDC identity provider.
|
||||
|===
|
||||
| Field | Description
|
||||
| *`phase`* __OIDCIdentityProviderPhase__ | Phase summarizes the overall status of the OIDCIdentityProvider.
|
||||
| *`conditions`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-supervisor-idp-v1alpha1-condition[$$Condition$$]__ | Represents the observations of an identity provider's current state.
|
||||
| *`conditions`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-supervisor-idp-v1alpha1-condition[$$Condition$$] array__ | Represents the observations of an identity provider's current state.
|
||||
|===
|
||||
|
||||
|
||||
@ -808,6 +935,7 @@ Status of an OIDC identity provider.
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-supervisor-idp-v1alpha1-ldapidentityproviderspec[$$LDAPIdentityProviderSpec$$]
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-supervisor-idp-v1alpha1-oidcidentityproviderspec[$$OIDCIdentityProviderSpec$$]
|
||||
****
|
||||
|
||||
|
@ -32,6 +32,8 @@ func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&OIDCIdentityProvider{},
|
||||
&OIDCIdentityProviderList{},
|
||||
&LDAPIdentityProvider{},
|
||||
&LDAPIdentityProviderList{},
|
||||
)
|
||||
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
|
132
generated/1.19/apis/supervisor/idp/v1alpha1/types_ldapidentityprovider.go
generated
Normal file
132
generated/1.19/apis/supervisor/idp/v1alpha1/types_ldapidentityprovider.go
generated
Normal file
@ -0,0 +1,132 @@
|
||||
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
type LDAPIdentityProviderPhase string
|
||||
|
||||
const (
|
||||
// LDAPPhasePending is the default phase for newly-created LDAPIdentityProvider resources.
|
||||
LDAPPhasePending LDAPIdentityProviderPhase = "Pending"
|
||||
|
||||
// LDAPPhaseReady is the phase for an LDAPIdentityProvider resource in a healthy state.
|
||||
LDAPPhaseReady LDAPIdentityProviderPhase = "Ready"
|
||||
|
||||
// LDAPPhaseError is the phase for an LDAPIdentityProvider in an unhealthy state.
|
||||
LDAPPhaseError LDAPIdentityProviderPhase = "Error"
|
||||
)
|
||||
|
||||
// Status of an LDAP identity provider.
|
||||
type LDAPIdentityProviderStatus struct {
|
||||
// Phase summarizes the overall status of the LDAPIdentityProvider.
|
||||
// +kubebuilder:default=Pending
|
||||
// +kubebuilder:validation:Enum=Pending;Ready;Error
|
||||
Phase LDAPIdentityProviderPhase `json:"phase,omitempty"`
|
||||
|
||||
// Represents the observations of an identity provider's current state.
|
||||
// +patchMergeKey=type
|
||||
// +patchStrategy=merge
|
||||
// +listType=map
|
||||
// +listMapKey=type
|
||||
Conditions []Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
|
||||
}
|
||||
|
||||
type LDAPIdentityProviderBind struct {
|
||||
// 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 of your bind account, e.g. "cn=bind-account,ou=users,dc=example,dc=com".
|
||||
// The password must be non-empty.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
SecretName string `json:"secretName"`
|
||||
}
|
||||
|
||||
type LDAPIdentityProviderUserSearchAttributes struct {
|
||||
// Username specifies the name of attribute in the LDAP entry which 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.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
Username string `json:"username,omitempty"`
|
||||
|
||||
// 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".
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
UID string `json:"uid,omitempty"`
|
||||
}
|
||||
|
||||
type LDAPIdentityProviderUserSearch struct {
|
||||
// Base is the DN that should be used as the search base when searching for users. E.g. "ou=users,dc=example,dc=com".
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
Base string `json:"base,omitempty"`
|
||||
|
||||
// Filter is the LDAP search filter which should be applied when searching for users. The pattern "{}" must occur
|
||||
// in the filter 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.
|
||||
// +optional
|
||||
Filter string `json:"filter,omitempty"`
|
||||
|
||||
// Attributes specifies how the user's information should be read from the LDAP entry which was found as
|
||||
// the result of the user search.
|
||||
// +optional
|
||||
Attributes LDAPIdentityProviderUserSearchAttributes `json:"attributes,omitempty"`
|
||||
}
|
||||
|
||||
// Spec for configuring an LDAP identity provider.
|
||||
type LDAPIdentityProviderSpec struct {
|
||||
// Host is the hostname of this LDAP identity provider, i.e., where to connect. For example: ldap.example.com:636.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
Host string `json:"host"`
|
||||
|
||||
// TLS contains the connection settings for how to establish the connection to the Host.
|
||||
TLS *TLSSpec `json:"tls,omitempty"`
|
||||
|
||||
// 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.
|
||||
Bind LDAPIdentityProviderBind `json:"bind,omitempty"`
|
||||
|
||||
// UserSearch contains the configuration for searching for a user by name in the LDAP provider.
|
||||
UserSearch LDAPIdentityProviderUserSearch `json:"userSearch,omitempty"`
|
||||
}
|
||||
|
||||
// LDAPIdentityProvider describes the configuration of an upstream Lightweight Directory Access
|
||||
// Protocol (LDAP) identity provider.
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +kubebuilder:resource:categories=pinniped;pinniped-idp;pinniped-idps
|
||||
// +kubebuilder:printcolumn:name="Host",type=string,JSONPath=`.spec.host`
|
||||
// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.phase`
|
||||
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
|
||||
// +kubebuilder:subresource:status
|
||||
type LDAPIdentityProvider struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Spec for configuring the identity provider.
|
||||
Spec LDAPIdentityProviderSpec `json:"spec"`
|
||||
|
||||
// Status of the identity provider.
|
||||
Status LDAPIdentityProviderStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// List of LDAPIdentityProvider objects.
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type LDAPIdentityProviderList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
Items []LDAPIdentityProvider `json:"items"`
|
||||
}
|
@ -28,6 +28,162 @@ func (in *Condition) DeepCopy() *Condition {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LDAPIdentityProvider) DeepCopyInto(out *LDAPIdentityProvider) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LDAPIdentityProvider.
|
||||
func (in *LDAPIdentityProvider) DeepCopy() *LDAPIdentityProvider {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LDAPIdentityProvider)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *LDAPIdentityProvider) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LDAPIdentityProviderBind) DeepCopyInto(out *LDAPIdentityProviderBind) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LDAPIdentityProviderBind.
|
||||
func (in *LDAPIdentityProviderBind) DeepCopy() *LDAPIdentityProviderBind {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LDAPIdentityProviderBind)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LDAPIdentityProviderList) DeepCopyInto(out *LDAPIdentityProviderList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]LDAPIdentityProvider, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LDAPIdentityProviderList.
|
||||
func (in *LDAPIdentityProviderList) DeepCopy() *LDAPIdentityProviderList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LDAPIdentityProviderList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *LDAPIdentityProviderList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LDAPIdentityProviderSpec) DeepCopyInto(out *LDAPIdentityProviderSpec) {
|
||||
*out = *in
|
||||
if in.TLS != nil {
|
||||
in, out := &in.TLS, &out.TLS
|
||||
*out = new(TLSSpec)
|
||||
**out = **in
|
||||
}
|
||||
out.Bind = in.Bind
|
||||
out.UserSearch = in.UserSearch
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LDAPIdentityProviderSpec.
|
||||
func (in *LDAPIdentityProviderSpec) DeepCopy() *LDAPIdentityProviderSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LDAPIdentityProviderSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LDAPIdentityProviderStatus) DeepCopyInto(out *LDAPIdentityProviderStatus) {
|
||||
*out = *in
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = make([]Condition, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LDAPIdentityProviderStatus.
|
||||
func (in *LDAPIdentityProviderStatus) DeepCopy() *LDAPIdentityProviderStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LDAPIdentityProviderStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LDAPIdentityProviderUserSearch) DeepCopyInto(out *LDAPIdentityProviderUserSearch) {
|
||||
*out = *in
|
||||
out.Attributes = in.Attributes
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LDAPIdentityProviderUserSearch.
|
||||
func (in *LDAPIdentityProviderUserSearch) DeepCopy() *LDAPIdentityProviderUserSearch {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LDAPIdentityProviderUserSearch)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LDAPIdentityProviderUserSearchAttributes) DeepCopyInto(out *LDAPIdentityProviderUserSearchAttributes) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LDAPIdentityProviderUserSearchAttributes.
|
||||
func (in *LDAPIdentityProviderUserSearchAttributes) DeepCopy() *LDAPIdentityProviderUserSearchAttributes {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LDAPIdentityProviderUserSearchAttributes)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *OIDCAuthorizationConfig) DeepCopyInto(out *OIDCAuthorizationConfig) {
|
||||
*out = *in
|
||||
|
@ -15,6 +15,10 @@ type FakeIDPV1alpha1 struct {
|
||||
*testing.Fake
|
||||
}
|
||||
|
||||
func (c *FakeIDPV1alpha1) LDAPIdentityProviders(namespace string) v1alpha1.LDAPIdentityProviderInterface {
|
||||
return &FakeLDAPIdentityProviders{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeIDPV1alpha1) OIDCIdentityProviders(namespace string) v1alpha1.OIDCIdentityProviderInterface {
|
||||
return &FakeOIDCIdentityProviders{c, namespace}
|
||||
}
|
||||
|
@ -0,0 +1,129 @@
|
||||
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
v1alpha1 "go.pinniped.dev/generated/1.19/apis/supervisor/idp/v1alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
// FakeLDAPIdentityProviders implements LDAPIdentityProviderInterface
|
||||
type FakeLDAPIdentityProviders struct {
|
||||
Fake *FakeIDPV1alpha1
|
||||
ns string
|
||||
}
|
||||
|
||||
var ldapidentityprovidersResource = schema.GroupVersionResource{Group: "idp.supervisor.pinniped.dev", Version: "v1alpha1", Resource: "ldapidentityproviders"}
|
||||
|
||||
var ldapidentityprovidersKind = schema.GroupVersionKind{Group: "idp.supervisor.pinniped.dev", Version: "v1alpha1", Kind: "LDAPIdentityProvider"}
|
||||
|
||||
// Get takes name of the lDAPIdentityProvider, and returns the corresponding lDAPIdentityProvider object, and an error if there is any.
|
||||
func (c *FakeLDAPIdentityProviders) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewGetAction(ldapidentityprovidersResource, c.ns, name), &v1alpha1.LDAPIdentityProvider{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.LDAPIdentityProvider), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of LDAPIdentityProviders that match those selectors.
|
||||
func (c *FakeLDAPIdentityProviders) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.LDAPIdentityProviderList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewListAction(ldapidentityprovidersResource, ldapidentityprovidersKind, c.ns, opts), &v1alpha1.LDAPIdentityProviderList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1alpha1.LDAPIdentityProviderList{ListMeta: obj.(*v1alpha1.LDAPIdentityProviderList).ListMeta}
|
||||
for _, item := range obj.(*v1alpha1.LDAPIdentityProviderList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested lDAPIdentityProviders.
|
||||
func (c *FakeLDAPIdentityProviders) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewWatchAction(ldapidentityprovidersResource, c.ns, opts))
|
||||
|
||||
}
|
||||
|
||||
// Create takes the representation of a lDAPIdentityProvider and creates it. Returns the server's representation of the lDAPIdentityProvider, and an error, if there is any.
|
||||
func (c *FakeLDAPIdentityProviders) Create(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.CreateOptions) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewCreateAction(ldapidentityprovidersResource, c.ns, lDAPIdentityProvider), &v1alpha1.LDAPIdentityProvider{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.LDAPIdentityProvider), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a lDAPIdentityProvider and updates it. Returns the server's representation of the lDAPIdentityProvider, and an error, if there is any.
|
||||
func (c *FakeLDAPIdentityProviders) Update(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.UpdateOptions) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateAction(ldapidentityprovidersResource, c.ns, lDAPIdentityProvider), &v1alpha1.LDAPIdentityProvider{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.LDAPIdentityProvider), err
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *FakeLDAPIdentityProviders) UpdateStatus(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.UpdateOptions) (*v1alpha1.LDAPIdentityProvider, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateSubresourceAction(ldapidentityprovidersResource, "status", c.ns, lDAPIdentityProvider), &v1alpha1.LDAPIdentityProvider{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.LDAPIdentityProvider), err
|
||||
}
|
||||
|
||||
// Delete takes name of the lDAPIdentityProvider and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeLDAPIdentityProviders) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewDeleteAction(ldapidentityprovidersResource, c.ns, name), &v1alpha1.LDAPIdentityProvider{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakeLDAPIdentityProviders) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
action := testing.NewDeleteCollectionAction(ldapidentityprovidersResource, c.ns, listOpts)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1alpha1.LDAPIdentityProviderList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched lDAPIdentityProvider.
|
||||
func (c *FakeLDAPIdentityProviders) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewPatchSubresourceAction(ldapidentityprovidersResource, c.ns, name, pt, data, subresources...), &v1alpha1.LDAPIdentityProvider{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.LDAPIdentityProvider), err
|
||||
}
|
@ -5,4 +5,6 @@
|
||||
|
||||
package v1alpha1
|
||||
|
||||
type LDAPIdentityProviderExpansion interface{}
|
||||
|
||||
type OIDCIdentityProviderExpansion interface{}
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
|
||||
type IDPV1alpha1Interface interface {
|
||||
RESTClient() rest.Interface
|
||||
LDAPIdentityProvidersGetter
|
||||
OIDCIdentityProvidersGetter
|
||||
}
|
||||
|
||||
@ -21,6 +22,10 @@ type IDPV1alpha1Client struct {
|
||||
restClient rest.Interface
|
||||
}
|
||||
|
||||
func (c *IDPV1alpha1Client) LDAPIdentityProviders(namespace string) LDAPIdentityProviderInterface {
|
||||
return newLDAPIdentityProviders(c, namespace)
|
||||
}
|
||||
|
||||
func (c *IDPV1alpha1Client) OIDCIdentityProviders(namespace string) OIDCIdentityProviderInterface {
|
||||
return newOIDCIdentityProviders(c, namespace)
|
||||
}
|
||||
|
182
generated/1.19/client/supervisor/clientset/versioned/typed/idp/v1alpha1/ldapidentityprovider.go
generated
Normal file
182
generated/1.19/client/supervisor/clientset/versioned/typed/idp/v1alpha1/ldapidentityprovider.go
generated
Normal file
@ -0,0 +1,182 @@
|
||||
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
v1alpha1 "go.pinniped.dev/generated/1.19/apis/supervisor/idp/v1alpha1"
|
||||
scheme "go.pinniped.dev/generated/1.19/client/supervisor/clientset/versioned/scheme"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// LDAPIdentityProvidersGetter has a method to return a LDAPIdentityProviderInterface.
|
||||
// A group's client should implement this interface.
|
||||
type LDAPIdentityProvidersGetter interface {
|
||||
LDAPIdentityProviders(namespace string) LDAPIdentityProviderInterface
|
||||
}
|
||||
|
||||
// LDAPIdentityProviderInterface has methods to work with LDAPIdentityProvider resources.
|
||||
type LDAPIdentityProviderInterface interface {
|
||||
Create(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.CreateOptions) (*v1alpha1.LDAPIdentityProvider, error)
|
||||
Update(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.UpdateOptions) (*v1alpha1.LDAPIdentityProvider, error)
|
||||
UpdateStatus(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.UpdateOptions) (*v1alpha1.LDAPIdentityProvider, error)
|
||||
Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
|
||||
DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
|
||||
Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.LDAPIdentityProvider, error)
|
||||
List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.LDAPIdentityProviderList, error)
|
||||
Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.LDAPIdentityProvider, err error)
|
||||
LDAPIdentityProviderExpansion
|
||||
}
|
||||
|
||||
// lDAPIdentityProviders implements LDAPIdentityProviderInterface
|
||||
type lDAPIdentityProviders struct {
|
||||
client rest.Interface
|
||||
ns string
|
||||
}
|
||||
|
||||
// newLDAPIdentityProviders returns a LDAPIdentityProviders
|
||||
func newLDAPIdentityProviders(c *IDPV1alpha1Client, namespace string) *lDAPIdentityProviders {
|
||||
return &lDAPIdentityProviders{
|
||||
client: c.RESTClient(),
|
||||
ns: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the lDAPIdentityProvider, and returns the corresponding lDAPIdentityProvider object, and an error if there is any.
|
||||
func (c *lDAPIdentityProviders) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
result = &v1alpha1.LDAPIdentityProvider{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of LDAPIdentityProviders that match those selectors.
|
||||
func (c *lDAPIdentityProviders) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.LDAPIdentityProviderList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1alpha1.LDAPIdentityProviderList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested lDAPIdentityProviders.
|
||||
func (c *lDAPIdentityProviders) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
opts.Watch = true
|
||||
return c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch(ctx)
|
||||
}
|
||||
|
||||
// Create takes the representation of a lDAPIdentityProvider and creates it. Returns the server's representation of the lDAPIdentityProvider, and an error, if there is any.
|
||||
func (c *lDAPIdentityProviders) Create(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.CreateOptions) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
result = &v1alpha1.LDAPIdentityProvider{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(lDAPIdentityProvider).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a lDAPIdentityProvider and updates it. Returns the server's representation of the lDAPIdentityProvider, and an error, if there is any.
|
||||
func (c *lDAPIdentityProviders) Update(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.UpdateOptions) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
result = &v1alpha1.LDAPIdentityProvider{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
Name(lDAPIdentityProvider.Name).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(lDAPIdentityProvider).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *lDAPIdentityProviders) UpdateStatus(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.UpdateOptions) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
result = &v1alpha1.LDAPIdentityProvider{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
Name(lDAPIdentityProvider.Name).
|
||||
SubResource("status").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(lDAPIdentityProvider).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the lDAPIdentityProvider and deletes it. Returns an error if one occurs.
|
||||
func (c *lDAPIdentityProviders) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
Name(name).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *lDAPIdentityProviders) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
var timeout time.Duration
|
||||
if listOpts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
VersionedParams(&listOpts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched lDAPIdentityProvider.
|
||||
func (c *lDAPIdentityProviders) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
result = &v1alpha1.LDAPIdentityProvider{}
|
||||
err = c.client.Patch(pt).
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
Name(name).
|
||||
SubResource(subresources...).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(data).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
@ -45,6 +45,8 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Config().V1alpha1().FederationDomains().Informer()}, nil
|
||||
|
||||
// Group=idp.supervisor.pinniped.dev, Version=v1alpha1
|
||||
case idpv1alpha1.SchemeGroupVersion.WithResource("ldapidentityproviders"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.IDP().V1alpha1().LDAPIdentityProviders().Informer()}, nil
|
||||
case idpv1alpha1.SchemeGroupVersion.WithResource("oidcidentityproviders"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.IDP().V1alpha1().OIDCIdentityProviders().Informer()}, nil
|
||||
|
||||
|
@ -11,6 +11,8 @@ import (
|
||||
|
||||
// Interface provides access to all the informers in this group version.
|
||||
type Interface interface {
|
||||
// LDAPIdentityProviders returns a LDAPIdentityProviderInformer.
|
||||
LDAPIdentityProviders() LDAPIdentityProviderInformer
|
||||
// OIDCIdentityProviders returns a OIDCIdentityProviderInformer.
|
||||
OIDCIdentityProviders() OIDCIdentityProviderInformer
|
||||
}
|
||||
@ -26,6 +28,11 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList
|
||||
return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
||||
}
|
||||
|
||||
// LDAPIdentityProviders returns a LDAPIdentityProviderInformer.
|
||||
func (v *version) LDAPIdentityProviders() LDAPIdentityProviderInformer {
|
||||
return &lDAPIdentityProviderInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
|
||||
// OIDCIdentityProviders returns a OIDCIdentityProviderInformer.
|
||||
func (v *version) OIDCIdentityProviders() OIDCIdentityProviderInformer {
|
||||
return &oIDCIdentityProviderInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
|
||||
|
77
generated/1.19/client/supervisor/informers/externalversions/idp/v1alpha1/ldapidentityprovider.go
generated
Normal file
77
generated/1.19/client/supervisor/informers/externalversions/idp/v1alpha1/ldapidentityprovider.go
generated
Normal file
@ -0,0 +1,77 @@
|
||||
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
time "time"
|
||||
|
||||
idpv1alpha1 "go.pinniped.dev/generated/1.19/apis/supervisor/idp/v1alpha1"
|
||||
versioned "go.pinniped.dev/generated/1.19/client/supervisor/clientset/versioned"
|
||||
internalinterfaces "go.pinniped.dev/generated/1.19/client/supervisor/informers/externalversions/internalinterfaces"
|
||||
v1alpha1 "go.pinniped.dev/generated/1.19/client/supervisor/listers/idp/v1alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// LDAPIdentityProviderInformer provides access to a shared informer and lister for
|
||||
// LDAPIdentityProviders.
|
||||
type LDAPIdentityProviderInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v1alpha1.LDAPIdentityProviderLister
|
||||
}
|
||||
|
||||
type lDAPIdentityProviderInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
namespace string
|
||||
}
|
||||
|
||||
// NewLDAPIdentityProviderInformer constructs a new informer for LDAPIdentityProvider type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewLDAPIdentityProviderInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredLDAPIdentityProviderInformer(client, namespace, resyncPeriod, indexers, nil)
|
||||
}
|
||||
|
||||
// NewFilteredLDAPIdentityProviderInformer constructs a new informer for LDAPIdentityProvider type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewFilteredLDAPIdentityProviderInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.IDPV1alpha1().LDAPIdentityProviders(namespace).List(context.TODO(), options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.IDPV1alpha1().LDAPIdentityProviders(namespace).Watch(context.TODO(), options)
|
||||
},
|
||||
},
|
||||
&idpv1alpha1.LDAPIdentityProvider{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
}
|
||||
|
||||
func (f *lDAPIdentityProviderInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredLDAPIdentityProviderInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *lDAPIdentityProviderInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&idpv1alpha1.LDAPIdentityProvider{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *lDAPIdentityProviderInformer) Lister() v1alpha1.LDAPIdentityProviderLister {
|
||||
return v1alpha1.NewLDAPIdentityProviderLister(f.Informer().GetIndexer())
|
||||
}
|
@ -5,6 +5,14 @@
|
||||
|
||||
package v1alpha1
|
||||
|
||||
// LDAPIdentityProviderListerExpansion allows custom methods to be added to
|
||||
// LDAPIdentityProviderLister.
|
||||
type LDAPIdentityProviderListerExpansion interface{}
|
||||
|
||||
// LDAPIdentityProviderNamespaceListerExpansion allows custom methods to be added to
|
||||
// LDAPIdentityProviderNamespaceLister.
|
||||
type LDAPIdentityProviderNamespaceListerExpansion interface{}
|
||||
|
||||
// OIDCIdentityProviderListerExpansion allows custom methods to be added to
|
||||
// OIDCIdentityProviderLister.
|
||||
type OIDCIdentityProviderListerExpansion interface{}
|
||||
|
86
generated/1.19/client/supervisor/listers/idp/v1alpha1/ldapidentityprovider.go
generated
Normal file
86
generated/1.19/client/supervisor/listers/idp/v1alpha1/ldapidentityprovider.go
generated
Normal file
@ -0,0 +1,86 @@
|
||||
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
v1alpha1 "go.pinniped.dev/generated/1.19/apis/supervisor/idp/v1alpha1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// LDAPIdentityProviderLister helps list LDAPIdentityProviders.
|
||||
// All objects returned here must be treated as read-only.
|
||||
type LDAPIdentityProviderLister interface {
|
||||
// List lists all LDAPIdentityProviders in the indexer.
|
||||
// Objects returned here must be treated as read-only.
|
||||
List(selector labels.Selector) (ret []*v1alpha1.LDAPIdentityProvider, err error)
|
||||
// LDAPIdentityProviders returns an object that can list and get LDAPIdentityProviders.
|
||||
LDAPIdentityProviders(namespace string) LDAPIdentityProviderNamespaceLister
|
||||
LDAPIdentityProviderListerExpansion
|
||||
}
|
||||
|
||||
// lDAPIdentityProviderLister implements the LDAPIdentityProviderLister interface.
|
||||
type lDAPIdentityProviderLister struct {
|
||||
indexer cache.Indexer
|
||||
}
|
||||
|
||||
// NewLDAPIdentityProviderLister returns a new LDAPIdentityProviderLister.
|
||||
func NewLDAPIdentityProviderLister(indexer cache.Indexer) LDAPIdentityProviderLister {
|
||||
return &lDAPIdentityProviderLister{indexer: indexer}
|
||||
}
|
||||
|
||||
// List lists all LDAPIdentityProviders in the indexer.
|
||||
func (s *lDAPIdentityProviderLister) List(selector labels.Selector) (ret []*v1alpha1.LDAPIdentityProvider, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1alpha1.LDAPIdentityProvider))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// LDAPIdentityProviders returns an object that can list and get LDAPIdentityProviders.
|
||||
func (s *lDAPIdentityProviderLister) LDAPIdentityProviders(namespace string) LDAPIdentityProviderNamespaceLister {
|
||||
return lDAPIdentityProviderNamespaceLister{indexer: s.indexer, namespace: namespace}
|
||||
}
|
||||
|
||||
// LDAPIdentityProviderNamespaceLister helps list and get LDAPIdentityProviders.
|
||||
// All objects returned here must be treated as read-only.
|
||||
type LDAPIdentityProviderNamespaceLister interface {
|
||||
// List lists all LDAPIdentityProviders in the indexer for a given namespace.
|
||||
// Objects returned here must be treated as read-only.
|
||||
List(selector labels.Selector) (ret []*v1alpha1.LDAPIdentityProvider, err error)
|
||||
// Get retrieves the LDAPIdentityProvider from the indexer for a given namespace and name.
|
||||
// Objects returned here must be treated as read-only.
|
||||
Get(name string) (*v1alpha1.LDAPIdentityProvider, error)
|
||||
LDAPIdentityProviderNamespaceListerExpansion
|
||||
}
|
||||
|
||||
// lDAPIdentityProviderNamespaceLister implements the LDAPIdentityProviderNamespaceLister
|
||||
// interface.
|
||||
type lDAPIdentityProviderNamespaceLister struct {
|
||||
indexer cache.Indexer
|
||||
namespace string
|
||||
}
|
||||
|
||||
// List lists all LDAPIdentityProviders in the indexer for a given namespace.
|
||||
func (s lDAPIdentityProviderNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.LDAPIdentityProvider, err error) {
|
||||
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1alpha1.LDAPIdentityProvider))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the LDAPIdentityProvider from the indexer for a given namespace and name.
|
||||
func (s lDAPIdentityProviderNamespaceLister) Get(name string) (*v1alpha1.LDAPIdentityProvider, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v1alpha1.Resource("ldapidentityprovider"), name)
|
||||
}
|
||||
return obj.(*v1alpha1.LDAPIdentityProvider), nil
|
||||
}
|
234
generated/1.19/crds/idp.supervisor.pinniped.dev_ldapidentityproviders.yaml
generated
Normal file
234
generated/1.19/crds/idp.supervisor.pinniped.dev_ldapidentityproviders.yaml
generated
Normal file
@ -0,0 +1,234 @@
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.4.0
|
||||
creationTimestamp: null
|
||||
name: ldapidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
names:
|
||||
categories:
|
||||
- pinniped
|
||||
- pinniped-idp
|
||||
- pinniped-idps
|
||||
kind: LDAPIdentityProvider
|
||||
listKind: LDAPIdentityProviderList
|
||||
plural: ldapidentityproviders
|
||||
singular: ldapidentityprovider
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .spec.host
|
||||
name: Host
|
||||
type: string
|
||||
- jsonPath: .status.phase
|
||||
name: Status
|
||||
type: string
|
||||
- jsonPath: .metadata.creationTimestamp
|
||||
name: Age
|
||||
type: date
|
||||
name: v1alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: LDAPIdentityProvider describes the configuration of an upstream
|
||||
Lightweight Directory Access Protocol (LDAP) identity provider.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: Spec for configuring the identity provider.
|
||||
properties:
|
||||
bind:
|
||||
description: Bind contains the configuration for how to provide access
|
||||
credentials during an initial bind to the LDAP server to be allowed
|
||||
to perform searches and binds to validate a user's credentials during
|
||||
a user's authentication attempt.
|
||||
properties:
|
||||
secretName:
|
||||
description: SecretName contains the name of a namespace-local
|
||||
Secret object that provides the username and password for an
|
||||
LDAP bind user. This account will be used to perform LDAP searches.
|
||||
The Secret should be of type "kubernetes.io/basic-auth" which
|
||||
includes "username" and "password" keys. The username value
|
||||
should be the full DN 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
|
||||
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 attribute in the
|
||||
LDAP entry which 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 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 and will be dynamically replaced by the username
|
||||
for which the search is being run. E.g. "mail={}" or "&(objectClass=person)(uid={})".
|
||||
For more information about LDAP filters, see https://ldap.com/ldap-filters.
|
||||
Note that the dn (distinguished name) is not an attribute of
|
||||
an entry, so "dn={}" cannot be used. Optional. When not specified,
|
||||
the default will act as if the Filter were specified as the
|
||||
value from Attributes.Username appended by "={}". When the Attributes.Username
|
||||
is set to "dn" then the Filter must be explicitly specified,
|
||||
since the default value of "dn={}" would not work.
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- host
|
||||
type: object
|
||||
status:
|
||||
description: Status of the identity provider.
|
||||
properties:
|
||||
conditions:
|
||||
description: Represents the observations of an identity provider's
|
||||
current state.
|
||||
items:
|
||||
description: Condition status of a resource (mirrored from the metav1.Condition
|
||||
type added in Kubernetes 1.19). In a future API version we can
|
||||
switch to using the upstream type. See https://github.com/kubernetes/apimachinery/blob/v0.19.0/pkg/apis/meta/v1/types.go#L1353-L1413.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: lastTransitionTime is the last time the condition
|
||||
transitioned from one status to another. This should be when
|
||||
the underlying condition changed. If that is not known, then
|
||||
using the time when the API field changed is acceptable.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: message is a human readable message indicating
|
||||
details about the transition. This may be an empty string.
|
||||
maxLength: 32768
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: observedGeneration represents the .metadata.generation
|
||||
that the condition was set based upon. For instance, if .metadata.generation
|
||||
is currently 12, but the .status.conditions[x].observedGeneration
|
||||
is 9, the condition is out of date with respect to the current
|
||||
state of the instance.
|
||||
format: int64
|
||||
minimum: 0
|
||||
type: integer
|
||||
reason:
|
||||
description: reason contains a programmatic identifier indicating
|
||||
the reason for the condition's last transition. Producers
|
||||
of specific condition types may define expected values and
|
||||
meanings for this field, and whether the values are considered
|
||||
a guaranteed API. The value should be a CamelCase string.
|
||||
This field may not be empty.
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
||||
type: string
|
||||
status:
|
||||
description: status of the condition, one of True, False, Unknown.
|
||||
enum:
|
||||
- "True"
|
||||
- "False"
|
||||
- Unknown
|
||||
type: string
|
||||
type:
|
||||
description: type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||
--- Many .condition.type values are consistent across resources
|
||||
like Available, but because arbitrary conditions can be useful
|
||||
(see .node.status.conditions), the ability to deconflict is
|
||||
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- message
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
x-kubernetes-list-map-keys:
|
||||
- type
|
||||
x-kubernetes-list-type: map
|
||||
phase:
|
||||
default: Pending
|
||||
description: Phase summarizes the overall status of the LDAPIdentityProvider.
|
||||
enum:
|
||||
- Pending
|
||||
- Ready
|
||||
- Error
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- spec
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
132
generated/1.20/README.adoc
generated
132
generated/1.20/README.adoc
generated
@ -669,10 +669,11 @@ Package v1alpha1 is the v1alpha1 version of the Pinniped supervisor identity pro
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-20-apis-supervisor-idp-v1alpha1-condition"]
|
||||
==== Condition
|
||||
|
||||
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.
|
||||
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-20-apis-supervisor-idp-v1alpha1-ldapidentityproviderstatus[$$LDAPIdentityProviderStatus$$]
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-20-apis-supervisor-idp-v1alpha1-oidcidentityproviderstatus[$$OIDCIdentityProviderStatus$$]
|
||||
****
|
||||
|
||||
@ -688,6 +689,132 @@ Condition status of a resource (mirrored from the metav1.Condition type added in
|
||||
|===
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-20-apis-supervisor-idp-v1alpha1-conditionstatus"]
|
||||
==== ConditionStatus (string)
|
||||
|
||||
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-20-apis-supervisor-idp-v1alpha1-condition[$$Condition$$]
|
||||
****
|
||||
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-20-apis-supervisor-idp-v1alpha1-ldapidentityprovider"]
|
||||
==== LDAPIdentityProvider
|
||||
|
||||
LDAPIdentityProvider describes the configuration of an upstream Lightweight Directory Access Protocol (LDAP) identity provider.
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-20-apis-supervisor-idp-v1alpha1-ldapidentityproviderlist[$$LDAPIdentityProviderList$$]
|
||||
****
|
||||
|
||||
[cols="25a,75a", options="header"]
|
||||
|===
|
||||
| Field | Description
|
||||
| *`metadata`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.2/#objectmeta-v1-meta[$$ObjectMeta$$]__ | Refer to Kubernetes API documentation for fields of `metadata`.
|
||||
|
||||
| *`spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-20-apis-supervisor-idp-v1alpha1-ldapidentityproviderspec[$$LDAPIdentityProviderSpec$$]__ | Spec for configuring the identity provider.
|
||||
| *`status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-20-apis-supervisor-idp-v1alpha1-ldapidentityproviderstatus[$$LDAPIdentityProviderStatus$$]__ | Status of the identity provider.
|
||||
|===
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-20-apis-supervisor-idp-v1alpha1-ldapidentityproviderbind"]
|
||||
==== LDAPIdentityProviderBind
|
||||
|
||||
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-20-apis-supervisor-idp-v1alpha1-ldapidentityproviderspec[$$LDAPIdentityProviderSpec$$]
|
||||
****
|
||||
|
||||
[cols="25a,75a", options="header"]
|
||||
|===
|
||||
| Field | Description
|
||||
| *`secretName`* __string__ | 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 of your bind account, e.g. "cn=bind-account,ou=users,dc=example,dc=com". The password must be non-empty.
|
||||
|===
|
||||
|
||||
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-20-apis-supervisor-idp-v1alpha1-ldapidentityproviderspec"]
|
||||
==== LDAPIdentityProviderSpec
|
||||
|
||||
Spec for configuring an LDAP identity provider.
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-20-apis-supervisor-idp-v1alpha1-ldapidentityprovider[$$LDAPIdentityProvider$$]
|
||||
****
|
||||
|
||||
[cols="25a,75a", options="header"]
|
||||
|===
|
||||
| Field | Description
|
||||
| *`host`* __string__ | Host is the hostname of this LDAP identity provider, i.e., where to connect. For example: ldap.example.com:636.
|
||||
| *`tls`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-20-apis-supervisor-idp-v1alpha1-tlsspec[$$TLSSpec$$]__ | TLS contains the connection settings for how to establish the connection to the Host.
|
||||
| *`bind`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-20-apis-supervisor-idp-v1alpha1-ldapidentityproviderbind[$$LDAPIdentityProviderBind$$]__ | 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.
|
||||
| *`userSearch`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-20-apis-supervisor-idp-v1alpha1-ldapidentityproviderusersearch[$$LDAPIdentityProviderUserSearch$$]__ | UserSearch contains the configuration for searching for a user by name in the LDAP provider.
|
||||
|===
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-20-apis-supervisor-idp-v1alpha1-ldapidentityproviderstatus"]
|
||||
==== LDAPIdentityProviderStatus
|
||||
|
||||
Status of an LDAP identity provider.
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-20-apis-supervisor-idp-v1alpha1-ldapidentityprovider[$$LDAPIdentityProvider$$]
|
||||
****
|
||||
|
||||
[cols="25a,75a", options="header"]
|
||||
|===
|
||||
| Field | Description
|
||||
| *`phase`* __LDAPIdentityProviderPhase__ | Phase summarizes the overall status of the LDAPIdentityProvider.
|
||||
| *`conditions`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-20-apis-supervisor-idp-v1alpha1-condition[$$Condition$$] array__ | Represents the observations of an identity provider's current state.
|
||||
|===
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-20-apis-supervisor-idp-v1alpha1-ldapidentityproviderusersearch"]
|
||||
==== LDAPIdentityProviderUserSearch
|
||||
|
||||
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-20-apis-supervisor-idp-v1alpha1-ldapidentityproviderspec[$$LDAPIdentityProviderSpec$$]
|
||||
****
|
||||
|
||||
[cols="25a,75a", options="header"]
|
||||
|===
|
||||
| Field | Description
|
||||
| *`base`* __string__ | Base is the DN that should be used as the search base when searching for users. E.g. "ou=users,dc=example,dc=com".
|
||||
| *`filter`* __string__ | Filter is the LDAP search filter which should be applied when searching for users. The pattern "{}" must occur in the filter 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.
|
||||
| *`attributes`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-20-apis-supervisor-idp-v1alpha1-ldapidentityproviderusersearchattributes[$$LDAPIdentityProviderUserSearchAttributes$$]__ | Attributes specifies how the user's information should be read from the LDAP entry which was found as the result of the user search.
|
||||
|===
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-20-apis-supervisor-idp-v1alpha1-ldapidentityproviderusersearchattributes"]
|
||||
==== LDAPIdentityProviderUserSearchAttributes
|
||||
|
||||
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-20-apis-supervisor-idp-v1alpha1-ldapidentityproviderusersearch[$$LDAPIdentityProviderUserSearch$$]
|
||||
****
|
||||
|
||||
[cols="25a,75a", options="header"]
|
||||
|===
|
||||
| Field | Description
|
||||
| *`username`* __string__ | Username specifies the name of attribute in the LDAP entry which 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.
|
||||
| *`uid`* __string__ | 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".
|
||||
|===
|
||||
|
||||
|
||||
[id="{anchor_prefix}-go-pinniped-dev-generated-1-20-apis-supervisor-idp-v1alpha1-oidcauthorizationconfig"]
|
||||
==== OIDCAuthorizationConfig
|
||||
|
||||
@ -797,7 +924,7 @@ Status of an OIDC identity provider.
|
||||
|===
|
||||
| Field | Description
|
||||
| *`phase`* __OIDCIdentityProviderPhase__ | Phase summarizes the overall status of the OIDCIdentityProvider.
|
||||
| *`conditions`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-20-apis-supervisor-idp-v1alpha1-condition[$$Condition$$]__ | Represents the observations of an identity provider's current state.
|
||||
| *`conditions`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-20-apis-supervisor-idp-v1alpha1-condition[$$Condition$$] array__ | Represents the observations of an identity provider's current state.
|
||||
|===
|
||||
|
||||
|
||||
@ -808,6 +935,7 @@ Status of an OIDC identity provider.
|
||||
|
||||
.Appears In:
|
||||
****
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-20-apis-supervisor-idp-v1alpha1-ldapidentityproviderspec[$$LDAPIdentityProviderSpec$$]
|
||||
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-20-apis-supervisor-idp-v1alpha1-oidcidentityproviderspec[$$OIDCIdentityProviderSpec$$]
|
||||
****
|
||||
|
||||
|
@ -32,6 +32,8 @@ func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&OIDCIdentityProvider{},
|
||||
&OIDCIdentityProviderList{},
|
||||
&LDAPIdentityProvider{},
|
||||
&LDAPIdentityProviderList{},
|
||||
)
|
||||
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
|
132
generated/1.20/apis/supervisor/idp/v1alpha1/types_ldapidentityprovider.go
generated
Normal file
132
generated/1.20/apis/supervisor/idp/v1alpha1/types_ldapidentityprovider.go
generated
Normal file
@ -0,0 +1,132 @@
|
||||
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
type LDAPIdentityProviderPhase string
|
||||
|
||||
const (
|
||||
// LDAPPhasePending is the default phase for newly-created LDAPIdentityProvider resources.
|
||||
LDAPPhasePending LDAPIdentityProviderPhase = "Pending"
|
||||
|
||||
// LDAPPhaseReady is the phase for an LDAPIdentityProvider resource in a healthy state.
|
||||
LDAPPhaseReady LDAPIdentityProviderPhase = "Ready"
|
||||
|
||||
// LDAPPhaseError is the phase for an LDAPIdentityProvider in an unhealthy state.
|
||||
LDAPPhaseError LDAPIdentityProviderPhase = "Error"
|
||||
)
|
||||
|
||||
// Status of an LDAP identity provider.
|
||||
type LDAPIdentityProviderStatus struct {
|
||||
// Phase summarizes the overall status of the LDAPIdentityProvider.
|
||||
// +kubebuilder:default=Pending
|
||||
// +kubebuilder:validation:Enum=Pending;Ready;Error
|
||||
Phase LDAPIdentityProviderPhase `json:"phase,omitempty"`
|
||||
|
||||
// Represents the observations of an identity provider's current state.
|
||||
// +patchMergeKey=type
|
||||
// +patchStrategy=merge
|
||||
// +listType=map
|
||||
// +listMapKey=type
|
||||
Conditions []Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
|
||||
}
|
||||
|
||||
type LDAPIdentityProviderBind struct {
|
||||
// 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 of your bind account, e.g. "cn=bind-account,ou=users,dc=example,dc=com".
|
||||
// The password must be non-empty.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
SecretName string `json:"secretName"`
|
||||
}
|
||||
|
||||
type LDAPIdentityProviderUserSearchAttributes struct {
|
||||
// Username specifies the name of attribute in the LDAP entry which 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.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
Username string `json:"username,omitempty"`
|
||||
|
||||
// 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".
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
UID string `json:"uid,omitempty"`
|
||||
}
|
||||
|
||||
type LDAPIdentityProviderUserSearch struct {
|
||||
// Base is the DN that should be used as the search base when searching for users. E.g. "ou=users,dc=example,dc=com".
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
Base string `json:"base,omitempty"`
|
||||
|
||||
// Filter is the LDAP search filter which should be applied when searching for users. The pattern "{}" must occur
|
||||
// in the filter 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.
|
||||
// +optional
|
||||
Filter string `json:"filter,omitempty"`
|
||||
|
||||
// Attributes specifies how the user's information should be read from the LDAP entry which was found as
|
||||
// the result of the user search.
|
||||
// +optional
|
||||
Attributes LDAPIdentityProviderUserSearchAttributes `json:"attributes,omitempty"`
|
||||
}
|
||||
|
||||
// Spec for configuring an LDAP identity provider.
|
||||
type LDAPIdentityProviderSpec struct {
|
||||
// Host is the hostname of this LDAP identity provider, i.e., where to connect. For example: ldap.example.com:636.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
Host string `json:"host"`
|
||||
|
||||
// TLS contains the connection settings for how to establish the connection to the Host.
|
||||
TLS *TLSSpec `json:"tls,omitempty"`
|
||||
|
||||
// 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.
|
||||
Bind LDAPIdentityProviderBind `json:"bind,omitempty"`
|
||||
|
||||
// UserSearch contains the configuration for searching for a user by name in the LDAP provider.
|
||||
UserSearch LDAPIdentityProviderUserSearch `json:"userSearch,omitempty"`
|
||||
}
|
||||
|
||||
// LDAPIdentityProvider describes the configuration of an upstream Lightweight Directory Access
|
||||
// Protocol (LDAP) identity provider.
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +kubebuilder:resource:categories=pinniped;pinniped-idp;pinniped-idps
|
||||
// +kubebuilder:printcolumn:name="Host",type=string,JSONPath=`.spec.host`
|
||||
// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.phase`
|
||||
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
|
||||
// +kubebuilder:subresource:status
|
||||
type LDAPIdentityProvider struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Spec for configuring the identity provider.
|
||||
Spec LDAPIdentityProviderSpec `json:"spec"`
|
||||
|
||||
// Status of the identity provider.
|
||||
Status LDAPIdentityProviderStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// List of LDAPIdentityProvider objects.
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type LDAPIdentityProviderList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
Items []LDAPIdentityProvider `json:"items"`
|
||||
}
|
@ -28,6 +28,162 @@ func (in *Condition) DeepCopy() *Condition {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LDAPIdentityProvider) DeepCopyInto(out *LDAPIdentityProvider) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LDAPIdentityProvider.
|
||||
func (in *LDAPIdentityProvider) DeepCopy() *LDAPIdentityProvider {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LDAPIdentityProvider)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *LDAPIdentityProvider) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LDAPIdentityProviderBind) DeepCopyInto(out *LDAPIdentityProviderBind) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LDAPIdentityProviderBind.
|
||||
func (in *LDAPIdentityProviderBind) DeepCopy() *LDAPIdentityProviderBind {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LDAPIdentityProviderBind)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LDAPIdentityProviderList) DeepCopyInto(out *LDAPIdentityProviderList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]LDAPIdentityProvider, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LDAPIdentityProviderList.
|
||||
func (in *LDAPIdentityProviderList) DeepCopy() *LDAPIdentityProviderList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LDAPIdentityProviderList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *LDAPIdentityProviderList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LDAPIdentityProviderSpec) DeepCopyInto(out *LDAPIdentityProviderSpec) {
|
||||
*out = *in
|
||||
if in.TLS != nil {
|
||||
in, out := &in.TLS, &out.TLS
|
||||
*out = new(TLSSpec)
|
||||
**out = **in
|
||||
}
|
||||
out.Bind = in.Bind
|
||||
out.UserSearch = in.UserSearch
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LDAPIdentityProviderSpec.
|
||||
func (in *LDAPIdentityProviderSpec) DeepCopy() *LDAPIdentityProviderSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LDAPIdentityProviderSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LDAPIdentityProviderStatus) DeepCopyInto(out *LDAPIdentityProviderStatus) {
|
||||
*out = *in
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = make([]Condition, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LDAPIdentityProviderStatus.
|
||||
func (in *LDAPIdentityProviderStatus) DeepCopy() *LDAPIdentityProviderStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LDAPIdentityProviderStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LDAPIdentityProviderUserSearch) DeepCopyInto(out *LDAPIdentityProviderUserSearch) {
|
||||
*out = *in
|
||||
out.Attributes = in.Attributes
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LDAPIdentityProviderUserSearch.
|
||||
func (in *LDAPIdentityProviderUserSearch) DeepCopy() *LDAPIdentityProviderUserSearch {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LDAPIdentityProviderUserSearch)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LDAPIdentityProviderUserSearchAttributes) DeepCopyInto(out *LDAPIdentityProviderUserSearchAttributes) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LDAPIdentityProviderUserSearchAttributes.
|
||||
func (in *LDAPIdentityProviderUserSearchAttributes) DeepCopy() *LDAPIdentityProviderUserSearchAttributes {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LDAPIdentityProviderUserSearchAttributes)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *OIDCAuthorizationConfig) DeepCopyInto(out *OIDCAuthorizationConfig) {
|
||||
*out = *in
|
||||
|
@ -15,6 +15,10 @@ type FakeIDPV1alpha1 struct {
|
||||
*testing.Fake
|
||||
}
|
||||
|
||||
func (c *FakeIDPV1alpha1) LDAPIdentityProviders(namespace string) v1alpha1.LDAPIdentityProviderInterface {
|
||||
return &FakeLDAPIdentityProviders{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeIDPV1alpha1) OIDCIdentityProviders(namespace string) v1alpha1.OIDCIdentityProviderInterface {
|
||||
return &FakeOIDCIdentityProviders{c, namespace}
|
||||
}
|
||||
|
@ -0,0 +1,129 @@
|
||||
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
v1alpha1 "go.pinniped.dev/generated/1.20/apis/supervisor/idp/v1alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
// FakeLDAPIdentityProviders implements LDAPIdentityProviderInterface
|
||||
type FakeLDAPIdentityProviders struct {
|
||||
Fake *FakeIDPV1alpha1
|
||||
ns string
|
||||
}
|
||||
|
||||
var ldapidentityprovidersResource = schema.GroupVersionResource{Group: "idp.supervisor.pinniped.dev", Version: "v1alpha1", Resource: "ldapidentityproviders"}
|
||||
|
||||
var ldapidentityprovidersKind = schema.GroupVersionKind{Group: "idp.supervisor.pinniped.dev", Version: "v1alpha1", Kind: "LDAPIdentityProvider"}
|
||||
|
||||
// Get takes name of the lDAPIdentityProvider, and returns the corresponding lDAPIdentityProvider object, and an error if there is any.
|
||||
func (c *FakeLDAPIdentityProviders) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewGetAction(ldapidentityprovidersResource, c.ns, name), &v1alpha1.LDAPIdentityProvider{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.LDAPIdentityProvider), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of LDAPIdentityProviders that match those selectors.
|
||||
func (c *FakeLDAPIdentityProviders) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.LDAPIdentityProviderList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewListAction(ldapidentityprovidersResource, ldapidentityprovidersKind, c.ns, opts), &v1alpha1.LDAPIdentityProviderList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1alpha1.LDAPIdentityProviderList{ListMeta: obj.(*v1alpha1.LDAPIdentityProviderList).ListMeta}
|
||||
for _, item := range obj.(*v1alpha1.LDAPIdentityProviderList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested lDAPIdentityProviders.
|
||||
func (c *FakeLDAPIdentityProviders) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewWatchAction(ldapidentityprovidersResource, c.ns, opts))
|
||||
|
||||
}
|
||||
|
||||
// Create takes the representation of a lDAPIdentityProvider and creates it. Returns the server's representation of the lDAPIdentityProvider, and an error, if there is any.
|
||||
func (c *FakeLDAPIdentityProviders) Create(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.CreateOptions) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewCreateAction(ldapidentityprovidersResource, c.ns, lDAPIdentityProvider), &v1alpha1.LDAPIdentityProvider{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.LDAPIdentityProvider), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a lDAPIdentityProvider and updates it. Returns the server's representation of the lDAPIdentityProvider, and an error, if there is any.
|
||||
func (c *FakeLDAPIdentityProviders) Update(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.UpdateOptions) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateAction(ldapidentityprovidersResource, c.ns, lDAPIdentityProvider), &v1alpha1.LDAPIdentityProvider{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.LDAPIdentityProvider), err
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *FakeLDAPIdentityProviders) UpdateStatus(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.UpdateOptions) (*v1alpha1.LDAPIdentityProvider, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateSubresourceAction(ldapidentityprovidersResource, "status", c.ns, lDAPIdentityProvider), &v1alpha1.LDAPIdentityProvider{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.LDAPIdentityProvider), err
|
||||
}
|
||||
|
||||
// Delete takes name of the lDAPIdentityProvider and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeLDAPIdentityProviders) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewDeleteAction(ldapidentityprovidersResource, c.ns, name), &v1alpha1.LDAPIdentityProvider{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakeLDAPIdentityProviders) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
action := testing.NewDeleteCollectionAction(ldapidentityprovidersResource, c.ns, listOpts)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1alpha1.LDAPIdentityProviderList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched lDAPIdentityProvider.
|
||||
func (c *FakeLDAPIdentityProviders) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewPatchSubresourceAction(ldapidentityprovidersResource, c.ns, name, pt, data, subresources...), &v1alpha1.LDAPIdentityProvider{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.LDAPIdentityProvider), err
|
||||
}
|
@ -5,4 +5,6 @@
|
||||
|
||||
package v1alpha1
|
||||
|
||||
type LDAPIdentityProviderExpansion interface{}
|
||||
|
||||
type OIDCIdentityProviderExpansion interface{}
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
|
||||
type IDPV1alpha1Interface interface {
|
||||
RESTClient() rest.Interface
|
||||
LDAPIdentityProvidersGetter
|
||||
OIDCIdentityProvidersGetter
|
||||
}
|
||||
|
||||
@ -21,6 +22,10 @@ type IDPV1alpha1Client struct {
|
||||
restClient rest.Interface
|
||||
}
|
||||
|
||||
func (c *IDPV1alpha1Client) LDAPIdentityProviders(namespace string) LDAPIdentityProviderInterface {
|
||||
return newLDAPIdentityProviders(c, namespace)
|
||||
}
|
||||
|
||||
func (c *IDPV1alpha1Client) OIDCIdentityProviders(namespace string) OIDCIdentityProviderInterface {
|
||||
return newOIDCIdentityProviders(c, namespace)
|
||||
}
|
||||
|
182
generated/1.20/client/supervisor/clientset/versioned/typed/idp/v1alpha1/ldapidentityprovider.go
generated
Normal file
182
generated/1.20/client/supervisor/clientset/versioned/typed/idp/v1alpha1/ldapidentityprovider.go
generated
Normal file
@ -0,0 +1,182 @@
|
||||
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
v1alpha1 "go.pinniped.dev/generated/1.20/apis/supervisor/idp/v1alpha1"
|
||||
scheme "go.pinniped.dev/generated/1.20/client/supervisor/clientset/versioned/scheme"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// LDAPIdentityProvidersGetter has a method to return a LDAPIdentityProviderInterface.
|
||||
// A group's client should implement this interface.
|
||||
type LDAPIdentityProvidersGetter interface {
|
||||
LDAPIdentityProviders(namespace string) LDAPIdentityProviderInterface
|
||||
}
|
||||
|
||||
// LDAPIdentityProviderInterface has methods to work with LDAPIdentityProvider resources.
|
||||
type LDAPIdentityProviderInterface interface {
|
||||
Create(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.CreateOptions) (*v1alpha1.LDAPIdentityProvider, error)
|
||||
Update(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.UpdateOptions) (*v1alpha1.LDAPIdentityProvider, error)
|
||||
UpdateStatus(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.UpdateOptions) (*v1alpha1.LDAPIdentityProvider, error)
|
||||
Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
|
||||
DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
|
||||
Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.LDAPIdentityProvider, error)
|
||||
List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.LDAPIdentityProviderList, error)
|
||||
Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.LDAPIdentityProvider, err error)
|
||||
LDAPIdentityProviderExpansion
|
||||
}
|
||||
|
||||
// lDAPIdentityProviders implements LDAPIdentityProviderInterface
|
||||
type lDAPIdentityProviders struct {
|
||||
client rest.Interface
|
||||
ns string
|
||||
}
|
||||
|
||||
// newLDAPIdentityProviders returns a LDAPIdentityProviders
|
||||
func newLDAPIdentityProviders(c *IDPV1alpha1Client, namespace string) *lDAPIdentityProviders {
|
||||
return &lDAPIdentityProviders{
|
||||
client: c.RESTClient(),
|
||||
ns: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the lDAPIdentityProvider, and returns the corresponding lDAPIdentityProvider object, and an error if there is any.
|
||||
func (c *lDAPIdentityProviders) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
result = &v1alpha1.LDAPIdentityProvider{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of LDAPIdentityProviders that match those selectors.
|
||||
func (c *lDAPIdentityProviders) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.LDAPIdentityProviderList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1alpha1.LDAPIdentityProviderList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested lDAPIdentityProviders.
|
||||
func (c *lDAPIdentityProviders) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
opts.Watch = true
|
||||
return c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch(ctx)
|
||||
}
|
||||
|
||||
// Create takes the representation of a lDAPIdentityProvider and creates it. Returns the server's representation of the lDAPIdentityProvider, and an error, if there is any.
|
||||
func (c *lDAPIdentityProviders) Create(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.CreateOptions) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
result = &v1alpha1.LDAPIdentityProvider{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(lDAPIdentityProvider).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a lDAPIdentityProvider and updates it. Returns the server's representation of the lDAPIdentityProvider, and an error, if there is any.
|
||||
func (c *lDAPIdentityProviders) Update(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.UpdateOptions) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
result = &v1alpha1.LDAPIdentityProvider{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
Name(lDAPIdentityProvider.Name).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(lDAPIdentityProvider).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *lDAPIdentityProviders) UpdateStatus(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.UpdateOptions) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
result = &v1alpha1.LDAPIdentityProvider{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
Name(lDAPIdentityProvider.Name).
|
||||
SubResource("status").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(lDAPIdentityProvider).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the lDAPIdentityProvider and deletes it. Returns an error if one occurs.
|
||||
func (c *lDAPIdentityProviders) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
Name(name).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *lDAPIdentityProviders) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
var timeout time.Duration
|
||||
if listOpts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
VersionedParams(&listOpts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched lDAPIdentityProvider.
|
||||
func (c *lDAPIdentityProviders) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
result = &v1alpha1.LDAPIdentityProvider{}
|
||||
err = c.client.Patch(pt).
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
Name(name).
|
||||
SubResource(subresources...).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(data).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
@ -45,6 +45,8 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Config().V1alpha1().FederationDomains().Informer()}, nil
|
||||
|
||||
// Group=idp.supervisor.pinniped.dev, Version=v1alpha1
|
||||
case idpv1alpha1.SchemeGroupVersion.WithResource("ldapidentityproviders"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.IDP().V1alpha1().LDAPIdentityProviders().Informer()}, nil
|
||||
case idpv1alpha1.SchemeGroupVersion.WithResource("oidcidentityproviders"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.IDP().V1alpha1().OIDCIdentityProviders().Informer()}, nil
|
||||
|
||||
|
@ -11,6 +11,8 @@ import (
|
||||
|
||||
// Interface provides access to all the informers in this group version.
|
||||
type Interface interface {
|
||||
// LDAPIdentityProviders returns a LDAPIdentityProviderInformer.
|
||||
LDAPIdentityProviders() LDAPIdentityProviderInformer
|
||||
// OIDCIdentityProviders returns a OIDCIdentityProviderInformer.
|
||||
OIDCIdentityProviders() OIDCIdentityProviderInformer
|
||||
}
|
||||
@ -26,6 +28,11 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList
|
||||
return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
||||
}
|
||||
|
||||
// LDAPIdentityProviders returns a LDAPIdentityProviderInformer.
|
||||
func (v *version) LDAPIdentityProviders() LDAPIdentityProviderInformer {
|
||||
return &lDAPIdentityProviderInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
|
||||
// OIDCIdentityProviders returns a OIDCIdentityProviderInformer.
|
||||
func (v *version) OIDCIdentityProviders() OIDCIdentityProviderInformer {
|
||||
return &oIDCIdentityProviderInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
|
||||
|
77
generated/1.20/client/supervisor/informers/externalversions/idp/v1alpha1/ldapidentityprovider.go
generated
Normal file
77
generated/1.20/client/supervisor/informers/externalversions/idp/v1alpha1/ldapidentityprovider.go
generated
Normal file
@ -0,0 +1,77 @@
|
||||
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
time "time"
|
||||
|
||||
idpv1alpha1 "go.pinniped.dev/generated/1.20/apis/supervisor/idp/v1alpha1"
|
||||
versioned "go.pinniped.dev/generated/1.20/client/supervisor/clientset/versioned"
|
||||
internalinterfaces "go.pinniped.dev/generated/1.20/client/supervisor/informers/externalversions/internalinterfaces"
|
||||
v1alpha1 "go.pinniped.dev/generated/1.20/client/supervisor/listers/idp/v1alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// LDAPIdentityProviderInformer provides access to a shared informer and lister for
|
||||
// LDAPIdentityProviders.
|
||||
type LDAPIdentityProviderInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v1alpha1.LDAPIdentityProviderLister
|
||||
}
|
||||
|
||||
type lDAPIdentityProviderInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
namespace string
|
||||
}
|
||||
|
||||
// NewLDAPIdentityProviderInformer constructs a new informer for LDAPIdentityProvider type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewLDAPIdentityProviderInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredLDAPIdentityProviderInformer(client, namespace, resyncPeriod, indexers, nil)
|
||||
}
|
||||
|
||||
// NewFilteredLDAPIdentityProviderInformer constructs a new informer for LDAPIdentityProvider type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewFilteredLDAPIdentityProviderInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.IDPV1alpha1().LDAPIdentityProviders(namespace).List(context.TODO(), options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.IDPV1alpha1().LDAPIdentityProviders(namespace).Watch(context.TODO(), options)
|
||||
},
|
||||
},
|
||||
&idpv1alpha1.LDAPIdentityProvider{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
}
|
||||
|
||||
func (f *lDAPIdentityProviderInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredLDAPIdentityProviderInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *lDAPIdentityProviderInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&idpv1alpha1.LDAPIdentityProvider{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *lDAPIdentityProviderInformer) Lister() v1alpha1.LDAPIdentityProviderLister {
|
||||
return v1alpha1.NewLDAPIdentityProviderLister(f.Informer().GetIndexer())
|
||||
}
|
@ -5,6 +5,14 @@
|
||||
|
||||
package v1alpha1
|
||||
|
||||
// LDAPIdentityProviderListerExpansion allows custom methods to be added to
|
||||
// LDAPIdentityProviderLister.
|
||||
type LDAPIdentityProviderListerExpansion interface{}
|
||||
|
||||
// LDAPIdentityProviderNamespaceListerExpansion allows custom methods to be added to
|
||||
// LDAPIdentityProviderNamespaceLister.
|
||||
type LDAPIdentityProviderNamespaceListerExpansion interface{}
|
||||
|
||||
// OIDCIdentityProviderListerExpansion allows custom methods to be added to
|
||||
// OIDCIdentityProviderLister.
|
||||
type OIDCIdentityProviderListerExpansion interface{}
|
||||
|
86
generated/1.20/client/supervisor/listers/idp/v1alpha1/ldapidentityprovider.go
generated
Normal file
86
generated/1.20/client/supervisor/listers/idp/v1alpha1/ldapidentityprovider.go
generated
Normal file
@ -0,0 +1,86 @@
|
||||
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
v1alpha1 "go.pinniped.dev/generated/1.20/apis/supervisor/idp/v1alpha1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// LDAPIdentityProviderLister helps list LDAPIdentityProviders.
|
||||
// All objects returned here must be treated as read-only.
|
||||
type LDAPIdentityProviderLister interface {
|
||||
// List lists all LDAPIdentityProviders in the indexer.
|
||||
// Objects returned here must be treated as read-only.
|
||||
List(selector labels.Selector) (ret []*v1alpha1.LDAPIdentityProvider, err error)
|
||||
// LDAPIdentityProviders returns an object that can list and get LDAPIdentityProviders.
|
||||
LDAPIdentityProviders(namespace string) LDAPIdentityProviderNamespaceLister
|
||||
LDAPIdentityProviderListerExpansion
|
||||
}
|
||||
|
||||
// lDAPIdentityProviderLister implements the LDAPIdentityProviderLister interface.
|
||||
type lDAPIdentityProviderLister struct {
|
||||
indexer cache.Indexer
|
||||
}
|
||||
|
||||
// NewLDAPIdentityProviderLister returns a new LDAPIdentityProviderLister.
|
||||
func NewLDAPIdentityProviderLister(indexer cache.Indexer) LDAPIdentityProviderLister {
|
||||
return &lDAPIdentityProviderLister{indexer: indexer}
|
||||
}
|
||||
|
||||
// List lists all LDAPIdentityProviders in the indexer.
|
||||
func (s *lDAPIdentityProviderLister) List(selector labels.Selector) (ret []*v1alpha1.LDAPIdentityProvider, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1alpha1.LDAPIdentityProvider))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// LDAPIdentityProviders returns an object that can list and get LDAPIdentityProviders.
|
||||
func (s *lDAPIdentityProviderLister) LDAPIdentityProviders(namespace string) LDAPIdentityProviderNamespaceLister {
|
||||
return lDAPIdentityProviderNamespaceLister{indexer: s.indexer, namespace: namespace}
|
||||
}
|
||||
|
||||
// LDAPIdentityProviderNamespaceLister helps list and get LDAPIdentityProviders.
|
||||
// All objects returned here must be treated as read-only.
|
||||
type LDAPIdentityProviderNamespaceLister interface {
|
||||
// List lists all LDAPIdentityProviders in the indexer for a given namespace.
|
||||
// Objects returned here must be treated as read-only.
|
||||
List(selector labels.Selector) (ret []*v1alpha1.LDAPIdentityProvider, err error)
|
||||
// Get retrieves the LDAPIdentityProvider from the indexer for a given namespace and name.
|
||||
// Objects returned here must be treated as read-only.
|
||||
Get(name string) (*v1alpha1.LDAPIdentityProvider, error)
|
||||
LDAPIdentityProviderNamespaceListerExpansion
|
||||
}
|
||||
|
||||
// lDAPIdentityProviderNamespaceLister implements the LDAPIdentityProviderNamespaceLister
|
||||
// interface.
|
||||
type lDAPIdentityProviderNamespaceLister struct {
|
||||
indexer cache.Indexer
|
||||
namespace string
|
||||
}
|
||||
|
||||
// List lists all LDAPIdentityProviders in the indexer for a given namespace.
|
||||
func (s lDAPIdentityProviderNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.LDAPIdentityProvider, err error) {
|
||||
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1alpha1.LDAPIdentityProvider))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the LDAPIdentityProvider from the indexer for a given namespace and name.
|
||||
func (s lDAPIdentityProviderNamespaceLister) Get(name string) (*v1alpha1.LDAPIdentityProvider, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v1alpha1.Resource("ldapidentityprovider"), name)
|
||||
}
|
||||
return obj.(*v1alpha1.LDAPIdentityProvider), nil
|
||||
}
|
234
generated/1.20/crds/idp.supervisor.pinniped.dev_ldapidentityproviders.yaml
generated
Normal file
234
generated/1.20/crds/idp.supervisor.pinniped.dev_ldapidentityproviders.yaml
generated
Normal file
@ -0,0 +1,234 @@
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.4.0
|
||||
creationTimestamp: null
|
||||
name: ldapidentityproviders.idp.supervisor.pinniped.dev
|
||||
spec:
|
||||
group: idp.supervisor.pinniped.dev
|
||||
names:
|
||||
categories:
|
||||
- pinniped
|
||||
- pinniped-idp
|
||||
- pinniped-idps
|
||||
kind: LDAPIdentityProvider
|
||||
listKind: LDAPIdentityProviderList
|
||||
plural: ldapidentityproviders
|
||||
singular: ldapidentityprovider
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .spec.host
|
||||
name: Host
|
||||
type: string
|
||||
- jsonPath: .status.phase
|
||||
name: Status
|
||||
type: string
|
||||
- jsonPath: .metadata.creationTimestamp
|
||||
name: Age
|
||||
type: date
|
||||
name: v1alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: LDAPIdentityProvider describes the configuration of an upstream
|
||||
Lightweight Directory Access Protocol (LDAP) identity provider.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: Spec for configuring the identity provider.
|
||||
properties:
|
||||
bind:
|
||||
description: Bind contains the configuration for how to provide access
|
||||
credentials during an initial bind to the LDAP server to be allowed
|
||||
to perform searches and binds to validate a user's credentials during
|
||||
a user's authentication attempt.
|
||||
properties:
|
||||
secretName:
|
||||
description: SecretName contains the name of a namespace-local
|
||||
Secret object that provides the username and password for an
|
||||
LDAP bind user. This account will be used to perform LDAP searches.
|
||||
The Secret should be of type "kubernetes.io/basic-auth" which
|
||||
includes "username" and "password" keys. The username value
|
||||
should be the full DN 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
|
||||
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 attribute in the
|
||||
LDAP entry which 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 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 and will be dynamically replaced by the username
|
||||
for which the search is being run. E.g. "mail={}" or "&(objectClass=person)(uid={})".
|
||||
For more information about LDAP filters, see https://ldap.com/ldap-filters.
|
||||
Note that the dn (distinguished name) is not an attribute of
|
||||
an entry, so "dn={}" cannot be used. Optional. When not specified,
|
||||
the default will act as if the Filter were specified as the
|
||||
value from Attributes.Username appended by "={}". When the Attributes.Username
|
||||
is set to "dn" then the Filter must be explicitly specified,
|
||||
since the default value of "dn={}" would not work.
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- host
|
||||
type: object
|
||||
status:
|
||||
description: Status of the identity provider.
|
||||
properties:
|
||||
conditions:
|
||||
description: Represents the observations of an identity provider's
|
||||
current state.
|
||||
items:
|
||||
description: Condition status of a resource (mirrored from the metav1.Condition
|
||||
type added in Kubernetes 1.19). In a future API version we can
|
||||
switch to using the upstream type. See https://github.com/kubernetes/apimachinery/blob/v0.19.0/pkg/apis/meta/v1/types.go#L1353-L1413.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: lastTransitionTime is the last time the condition
|
||||
transitioned from one status to another. This should be when
|
||||
the underlying condition changed. If that is not known, then
|
||||
using the time when the API field changed is acceptable.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: message is a human readable message indicating
|
||||
details about the transition. This may be an empty string.
|
||||
maxLength: 32768
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: observedGeneration represents the .metadata.generation
|
||||
that the condition was set based upon. For instance, if .metadata.generation
|
||||
is currently 12, but the .status.conditions[x].observedGeneration
|
||||
is 9, the condition is out of date with respect to the current
|
||||
state of the instance.
|
||||
format: int64
|
||||
minimum: 0
|
||||
type: integer
|
||||
reason:
|
||||
description: reason contains a programmatic identifier indicating
|
||||
the reason for the condition's last transition. Producers
|
||||
of specific condition types may define expected values and
|
||||
meanings for this field, and whether the values are considered
|
||||
a guaranteed API. The value should be a CamelCase string.
|
||||
This field may not be empty.
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
||||
type: string
|
||||
status:
|
||||
description: status of the condition, one of True, False, Unknown.
|
||||
enum:
|
||||
- "True"
|
||||
- "False"
|
||||
- Unknown
|
||||
type: string
|
||||
type:
|
||||
description: type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||
--- Many .condition.type values are consistent across resources
|
||||
like Available, but because arbitrary conditions can be useful
|
||||
(see .node.status.conditions), the ability to deconflict is
|
||||
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- message
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
x-kubernetes-list-map-keys:
|
||||
- type
|
||||
x-kubernetes-list-type: map
|
||||
phase:
|
||||
default: Pending
|
||||
description: Phase summarizes the overall status of the LDAPIdentityProvider.
|
||||
enum:
|
||||
- Pending
|
||||
- Ready
|
||||
- Error
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- spec
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
@ -32,6 +32,8 @@ func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&OIDCIdentityProvider{},
|
||||
&OIDCIdentityProviderList{},
|
||||
&LDAPIdentityProvider{},
|
||||
&LDAPIdentityProviderList{},
|
||||
)
|
||||
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
|
132
generated/latest/apis/supervisor/idp/v1alpha1/types_ldapidentityprovider.go
generated
Normal file
132
generated/latest/apis/supervisor/idp/v1alpha1/types_ldapidentityprovider.go
generated
Normal file
@ -0,0 +1,132 @@
|
||||
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
type LDAPIdentityProviderPhase string
|
||||
|
||||
const (
|
||||
// LDAPPhasePending is the default phase for newly-created LDAPIdentityProvider resources.
|
||||
LDAPPhasePending LDAPIdentityProviderPhase = "Pending"
|
||||
|
||||
// LDAPPhaseReady is the phase for an LDAPIdentityProvider resource in a healthy state.
|
||||
LDAPPhaseReady LDAPIdentityProviderPhase = "Ready"
|
||||
|
||||
// LDAPPhaseError is the phase for an LDAPIdentityProvider in an unhealthy state.
|
||||
LDAPPhaseError LDAPIdentityProviderPhase = "Error"
|
||||
)
|
||||
|
||||
// Status of an LDAP identity provider.
|
||||
type LDAPIdentityProviderStatus struct {
|
||||
// Phase summarizes the overall status of the LDAPIdentityProvider.
|
||||
// +kubebuilder:default=Pending
|
||||
// +kubebuilder:validation:Enum=Pending;Ready;Error
|
||||
Phase LDAPIdentityProviderPhase `json:"phase,omitempty"`
|
||||
|
||||
// Represents the observations of an identity provider's current state.
|
||||
// +patchMergeKey=type
|
||||
// +patchStrategy=merge
|
||||
// +listType=map
|
||||
// +listMapKey=type
|
||||
Conditions []Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
|
||||
}
|
||||
|
||||
type LDAPIdentityProviderBind struct {
|
||||
// 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 of your bind account, e.g. "cn=bind-account,ou=users,dc=example,dc=com".
|
||||
// The password must be non-empty.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
SecretName string `json:"secretName"`
|
||||
}
|
||||
|
||||
type LDAPIdentityProviderUserSearchAttributes struct {
|
||||
// Username specifies the name of attribute in the LDAP entry which 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.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
Username string `json:"username,omitempty"`
|
||||
|
||||
// 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".
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
UID string `json:"uid,omitempty"`
|
||||
}
|
||||
|
||||
type LDAPIdentityProviderUserSearch struct {
|
||||
// Base is the DN that should be used as the search base when searching for users. E.g. "ou=users,dc=example,dc=com".
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
Base string `json:"base,omitempty"`
|
||||
|
||||
// Filter is the LDAP search filter which should be applied when searching for users. The pattern "{}" must occur
|
||||
// in the filter 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.
|
||||
// +optional
|
||||
Filter string `json:"filter,omitempty"`
|
||||
|
||||
// Attributes specifies how the user's information should be read from the LDAP entry which was found as
|
||||
// the result of the user search.
|
||||
// +optional
|
||||
Attributes LDAPIdentityProviderUserSearchAttributes `json:"attributes,omitempty"`
|
||||
}
|
||||
|
||||
// Spec for configuring an LDAP identity provider.
|
||||
type LDAPIdentityProviderSpec struct {
|
||||
// Host is the hostname of this LDAP identity provider, i.e., where to connect. For example: ldap.example.com:636.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
Host string `json:"host"`
|
||||
|
||||
// TLS contains the connection settings for how to establish the connection to the Host.
|
||||
TLS *TLSSpec `json:"tls,omitempty"`
|
||||
|
||||
// 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.
|
||||
Bind LDAPIdentityProviderBind `json:"bind,omitempty"`
|
||||
|
||||
// UserSearch contains the configuration for searching for a user by name in the LDAP provider.
|
||||
UserSearch LDAPIdentityProviderUserSearch `json:"userSearch,omitempty"`
|
||||
}
|
||||
|
||||
// LDAPIdentityProvider describes the configuration of an upstream Lightweight Directory Access
|
||||
// Protocol (LDAP) identity provider.
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +kubebuilder:resource:categories=pinniped;pinniped-idp;pinniped-idps
|
||||
// +kubebuilder:printcolumn:name="Host",type=string,JSONPath=`.spec.host`
|
||||
// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.phase`
|
||||
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
|
||||
// +kubebuilder:subresource:status
|
||||
type LDAPIdentityProvider struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Spec for configuring the identity provider.
|
||||
Spec LDAPIdentityProviderSpec `json:"spec"`
|
||||
|
||||
// Status of the identity provider.
|
||||
Status LDAPIdentityProviderStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// List of LDAPIdentityProvider objects.
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type LDAPIdentityProviderList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
Items []LDAPIdentityProvider `json:"items"`
|
||||
}
|
@ -28,6 +28,162 @@ func (in *Condition) DeepCopy() *Condition {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LDAPIdentityProvider) DeepCopyInto(out *LDAPIdentityProvider) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LDAPIdentityProvider.
|
||||
func (in *LDAPIdentityProvider) DeepCopy() *LDAPIdentityProvider {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LDAPIdentityProvider)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *LDAPIdentityProvider) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LDAPIdentityProviderBind) DeepCopyInto(out *LDAPIdentityProviderBind) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LDAPIdentityProviderBind.
|
||||
func (in *LDAPIdentityProviderBind) DeepCopy() *LDAPIdentityProviderBind {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LDAPIdentityProviderBind)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LDAPIdentityProviderList) DeepCopyInto(out *LDAPIdentityProviderList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]LDAPIdentityProvider, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LDAPIdentityProviderList.
|
||||
func (in *LDAPIdentityProviderList) DeepCopy() *LDAPIdentityProviderList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LDAPIdentityProviderList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *LDAPIdentityProviderList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LDAPIdentityProviderSpec) DeepCopyInto(out *LDAPIdentityProviderSpec) {
|
||||
*out = *in
|
||||
if in.TLS != nil {
|
||||
in, out := &in.TLS, &out.TLS
|
||||
*out = new(TLSSpec)
|
||||
**out = **in
|
||||
}
|
||||
out.Bind = in.Bind
|
||||
out.UserSearch = in.UserSearch
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LDAPIdentityProviderSpec.
|
||||
func (in *LDAPIdentityProviderSpec) DeepCopy() *LDAPIdentityProviderSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LDAPIdentityProviderSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LDAPIdentityProviderStatus) DeepCopyInto(out *LDAPIdentityProviderStatus) {
|
||||
*out = *in
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = make([]Condition, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LDAPIdentityProviderStatus.
|
||||
func (in *LDAPIdentityProviderStatus) DeepCopy() *LDAPIdentityProviderStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LDAPIdentityProviderStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LDAPIdentityProviderUserSearch) DeepCopyInto(out *LDAPIdentityProviderUserSearch) {
|
||||
*out = *in
|
||||
out.Attributes = in.Attributes
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LDAPIdentityProviderUserSearch.
|
||||
func (in *LDAPIdentityProviderUserSearch) DeepCopy() *LDAPIdentityProviderUserSearch {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LDAPIdentityProviderUserSearch)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LDAPIdentityProviderUserSearchAttributes) DeepCopyInto(out *LDAPIdentityProviderUserSearchAttributes) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LDAPIdentityProviderUserSearchAttributes.
|
||||
func (in *LDAPIdentityProviderUserSearchAttributes) DeepCopy() *LDAPIdentityProviderUserSearchAttributes {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LDAPIdentityProviderUserSearchAttributes)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *OIDCAuthorizationConfig) DeepCopyInto(out *OIDCAuthorizationConfig) {
|
||||
*out = *in
|
||||
|
@ -15,6 +15,10 @@ type FakeIDPV1alpha1 struct {
|
||||
*testing.Fake
|
||||
}
|
||||
|
||||
func (c *FakeIDPV1alpha1) LDAPIdentityProviders(namespace string) v1alpha1.LDAPIdentityProviderInterface {
|
||||
return &FakeLDAPIdentityProviders{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeIDPV1alpha1) OIDCIdentityProviders(namespace string) v1alpha1.OIDCIdentityProviderInterface {
|
||||
return &FakeOIDCIdentityProviders{c, namespace}
|
||||
}
|
||||
|
@ -0,0 +1,129 @@
|
||||
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
v1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
// FakeLDAPIdentityProviders implements LDAPIdentityProviderInterface
|
||||
type FakeLDAPIdentityProviders struct {
|
||||
Fake *FakeIDPV1alpha1
|
||||
ns string
|
||||
}
|
||||
|
||||
var ldapidentityprovidersResource = schema.GroupVersionResource{Group: "idp.supervisor.pinniped.dev", Version: "v1alpha1", Resource: "ldapidentityproviders"}
|
||||
|
||||
var ldapidentityprovidersKind = schema.GroupVersionKind{Group: "idp.supervisor.pinniped.dev", Version: "v1alpha1", Kind: "LDAPIdentityProvider"}
|
||||
|
||||
// Get takes name of the lDAPIdentityProvider, and returns the corresponding lDAPIdentityProvider object, and an error if there is any.
|
||||
func (c *FakeLDAPIdentityProviders) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewGetAction(ldapidentityprovidersResource, c.ns, name), &v1alpha1.LDAPIdentityProvider{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.LDAPIdentityProvider), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of LDAPIdentityProviders that match those selectors.
|
||||
func (c *FakeLDAPIdentityProviders) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.LDAPIdentityProviderList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewListAction(ldapidentityprovidersResource, ldapidentityprovidersKind, c.ns, opts), &v1alpha1.LDAPIdentityProviderList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1alpha1.LDAPIdentityProviderList{ListMeta: obj.(*v1alpha1.LDAPIdentityProviderList).ListMeta}
|
||||
for _, item := range obj.(*v1alpha1.LDAPIdentityProviderList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested lDAPIdentityProviders.
|
||||
func (c *FakeLDAPIdentityProviders) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewWatchAction(ldapidentityprovidersResource, c.ns, opts))
|
||||
|
||||
}
|
||||
|
||||
// Create takes the representation of a lDAPIdentityProvider and creates it. Returns the server's representation of the lDAPIdentityProvider, and an error, if there is any.
|
||||
func (c *FakeLDAPIdentityProviders) Create(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.CreateOptions) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewCreateAction(ldapidentityprovidersResource, c.ns, lDAPIdentityProvider), &v1alpha1.LDAPIdentityProvider{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.LDAPIdentityProvider), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a lDAPIdentityProvider and updates it. Returns the server's representation of the lDAPIdentityProvider, and an error, if there is any.
|
||||
func (c *FakeLDAPIdentityProviders) Update(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.UpdateOptions) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateAction(ldapidentityprovidersResource, c.ns, lDAPIdentityProvider), &v1alpha1.LDAPIdentityProvider{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.LDAPIdentityProvider), err
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *FakeLDAPIdentityProviders) UpdateStatus(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.UpdateOptions) (*v1alpha1.LDAPIdentityProvider, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateSubresourceAction(ldapidentityprovidersResource, "status", c.ns, lDAPIdentityProvider), &v1alpha1.LDAPIdentityProvider{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.LDAPIdentityProvider), err
|
||||
}
|
||||
|
||||
// Delete takes name of the lDAPIdentityProvider and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeLDAPIdentityProviders) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewDeleteAction(ldapidentityprovidersResource, c.ns, name), &v1alpha1.LDAPIdentityProvider{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakeLDAPIdentityProviders) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
action := testing.NewDeleteCollectionAction(ldapidentityprovidersResource, c.ns, listOpts)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1alpha1.LDAPIdentityProviderList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched lDAPIdentityProvider.
|
||||
func (c *FakeLDAPIdentityProviders) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewPatchSubresourceAction(ldapidentityprovidersResource, c.ns, name, pt, data, subresources...), &v1alpha1.LDAPIdentityProvider{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.LDAPIdentityProvider), err
|
||||
}
|
@ -5,4 +5,6 @@
|
||||
|
||||
package v1alpha1
|
||||
|
||||
type LDAPIdentityProviderExpansion interface{}
|
||||
|
||||
type OIDCIdentityProviderExpansion interface{}
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
|
||||
type IDPV1alpha1Interface interface {
|
||||
RESTClient() rest.Interface
|
||||
LDAPIdentityProvidersGetter
|
||||
OIDCIdentityProvidersGetter
|
||||
}
|
||||
|
||||
@ -21,6 +22,10 @@ type IDPV1alpha1Client struct {
|
||||
restClient rest.Interface
|
||||
}
|
||||
|
||||
func (c *IDPV1alpha1Client) LDAPIdentityProviders(namespace string) LDAPIdentityProviderInterface {
|
||||
return newLDAPIdentityProviders(c, namespace)
|
||||
}
|
||||
|
||||
func (c *IDPV1alpha1Client) OIDCIdentityProviders(namespace string) OIDCIdentityProviderInterface {
|
||||
return newOIDCIdentityProviders(c, namespace)
|
||||
}
|
||||
|
182
generated/latest/client/supervisor/clientset/versioned/typed/idp/v1alpha1/ldapidentityprovider.go
generated
Normal file
182
generated/latest/client/supervisor/clientset/versioned/typed/idp/v1alpha1/ldapidentityprovider.go
generated
Normal file
@ -0,0 +1,182 @@
|
||||
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
v1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
|
||||
scheme "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/scheme"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// LDAPIdentityProvidersGetter has a method to return a LDAPIdentityProviderInterface.
|
||||
// A group's client should implement this interface.
|
||||
type LDAPIdentityProvidersGetter interface {
|
||||
LDAPIdentityProviders(namespace string) LDAPIdentityProviderInterface
|
||||
}
|
||||
|
||||
// LDAPIdentityProviderInterface has methods to work with LDAPIdentityProvider resources.
|
||||
type LDAPIdentityProviderInterface interface {
|
||||
Create(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.CreateOptions) (*v1alpha1.LDAPIdentityProvider, error)
|
||||
Update(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.UpdateOptions) (*v1alpha1.LDAPIdentityProvider, error)
|
||||
UpdateStatus(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.UpdateOptions) (*v1alpha1.LDAPIdentityProvider, error)
|
||||
Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
|
||||
DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
|
||||
Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.LDAPIdentityProvider, error)
|
||||
List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.LDAPIdentityProviderList, error)
|
||||
Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.LDAPIdentityProvider, err error)
|
||||
LDAPIdentityProviderExpansion
|
||||
}
|
||||
|
||||
// lDAPIdentityProviders implements LDAPIdentityProviderInterface
|
||||
type lDAPIdentityProviders struct {
|
||||
client rest.Interface
|
||||
ns string
|
||||
}
|
||||
|
||||
// newLDAPIdentityProviders returns a LDAPIdentityProviders
|
||||
func newLDAPIdentityProviders(c *IDPV1alpha1Client, namespace string) *lDAPIdentityProviders {
|
||||
return &lDAPIdentityProviders{
|
||||
client: c.RESTClient(),
|
||||
ns: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the lDAPIdentityProvider, and returns the corresponding lDAPIdentityProvider object, and an error if there is any.
|
||||
func (c *lDAPIdentityProviders) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
result = &v1alpha1.LDAPIdentityProvider{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of LDAPIdentityProviders that match those selectors.
|
||||
func (c *lDAPIdentityProviders) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.LDAPIdentityProviderList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1alpha1.LDAPIdentityProviderList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested lDAPIdentityProviders.
|
||||
func (c *lDAPIdentityProviders) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
opts.Watch = true
|
||||
return c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch(ctx)
|
||||
}
|
||||
|
||||
// Create takes the representation of a lDAPIdentityProvider and creates it. Returns the server's representation of the lDAPIdentityProvider, and an error, if there is any.
|
||||
func (c *lDAPIdentityProviders) Create(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.CreateOptions) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
result = &v1alpha1.LDAPIdentityProvider{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(lDAPIdentityProvider).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a lDAPIdentityProvider and updates it. Returns the server's representation of the lDAPIdentityProvider, and an error, if there is any.
|
||||
func (c *lDAPIdentityProviders) Update(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.UpdateOptions) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
result = &v1alpha1.LDAPIdentityProvider{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
Name(lDAPIdentityProvider.Name).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(lDAPIdentityProvider).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *lDAPIdentityProviders) UpdateStatus(ctx context.Context, lDAPIdentityProvider *v1alpha1.LDAPIdentityProvider, opts v1.UpdateOptions) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
result = &v1alpha1.LDAPIdentityProvider{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
Name(lDAPIdentityProvider.Name).
|
||||
SubResource("status").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(lDAPIdentityProvider).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the lDAPIdentityProvider and deletes it. Returns an error if one occurs.
|
||||
func (c *lDAPIdentityProviders) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
Name(name).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *lDAPIdentityProviders) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
var timeout time.Duration
|
||||
if listOpts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
VersionedParams(&listOpts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched lDAPIdentityProvider.
|
||||
func (c *lDAPIdentityProviders) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.LDAPIdentityProvider, err error) {
|
||||
result = &v1alpha1.LDAPIdentityProvider{}
|
||||
err = c.client.Patch(pt).
|
||||
Namespace(c.ns).
|
||||
Resource("ldapidentityproviders").
|
||||
Name(name).
|
||||
SubResource(subresources...).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(data).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
@ -45,6 +45,8 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Config().V1alpha1().FederationDomains().Informer()}, nil
|
||||
|
||||
// Group=idp.supervisor.pinniped.dev, Version=v1alpha1
|
||||
case idpv1alpha1.SchemeGroupVersion.WithResource("ldapidentityproviders"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.IDP().V1alpha1().LDAPIdentityProviders().Informer()}, nil
|
||||
case idpv1alpha1.SchemeGroupVersion.WithResource("oidcidentityproviders"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.IDP().V1alpha1().OIDCIdentityProviders().Informer()}, nil
|
||||
|
||||
|
@ -11,6 +11,8 @@ import (
|
||||
|
||||
// Interface provides access to all the informers in this group version.
|
||||
type Interface interface {
|
||||
// LDAPIdentityProviders returns a LDAPIdentityProviderInformer.
|
||||
LDAPIdentityProviders() LDAPIdentityProviderInformer
|
||||
// OIDCIdentityProviders returns a OIDCIdentityProviderInformer.
|
||||
OIDCIdentityProviders() OIDCIdentityProviderInformer
|
||||
}
|
||||
@ -26,6 +28,11 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList
|
||||
return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
||||
}
|
||||
|
||||
// LDAPIdentityProviders returns a LDAPIdentityProviderInformer.
|
||||
func (v *version) LDAPIdentityProviders() LDAPIdentityProviderInformer {
|
||||
return &lDAPIdentityProviderInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
|
||||
// OIDCIdentityProviders returns a OIDCIdentityProviderInformer.
|
||||
func (v *version) OIDCIdentityProviders() OIDCIdentityProviderInformer {
|
||||
return &oIDCIdentityProviderInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
|
||||
|
77
generated/latest/client/supervisor/informers/externalversions/idp/v1alpha1/ldapidentityprovider.go
generated
Normal file
77
generated/latest/client/supervisor/informers/externalversions/idp/v1alpha1/ldapidentityprovider.go
generated
Normal file
@ -0,0 +1,77 @@
|
||||
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
time "time"
|
||||
|
||||
idpv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
|
||||
versioned "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned"
|
||||
internalinterfaces "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions/internalinterfaces"
|
||||
v1alpha1 "go.pinniped.dev/generated/latest/client/supervisor/listers/idp/v1alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// LDAPIdentityProviderInformer provides access to a shared informer and lister for
|
||||
// LDAPIdentityProviders.
|
||||
type LDAPIdentityProviderInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v1alpha1.LDAPIdentityProviderLister
|
||||
}
|
||||
|
||||
type lDAPIdentityProviderInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
namespace string
|
||||
}
|
||||
|
||||
// NewLDAPIdentityProviderInformer constructs a new informer for LDAPIdentityProvider type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewLDAPIdentityProviderInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredLDAPIdentityProviderInformer(client, namespace, resyncPeriod, indexers, nil)
|
||||
}
|
||||
|
||||
// NewFilteredLDAPIdentityProviderInformer constructs a new informer for LDAPIdentityProvider type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewFilteredLDAPIdentityProviderInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.IDPV1alpha1().LDAPIdentityProviders(namespace).List(context.TODO(), options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.IDPV1alpha1().LDAPIdentityProviders(namespace).Watch(context.TODO(), options)
|
||||
},
|
||||
},
|
||||
&idpv1alpha1.LDAPIdentityProvider{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
}
|
||||
|
||||
func (f *lDAPIdentityProviderInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredLDAPIdentityProviderInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *lDAPIdentityProviderInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&idpv1alpha1.LDAPIdentityProvider{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *lDAPIdentityProviderInformer) Lister() v1alpha1.LDAPIdentityProviderLister {
|
||||
return v1alpha1.NewLDAPIdentityProviderLister(f.Informer().GetIndexer())
|
||||
}
|
@ -5,6 +5,14 @@
|
||||
|
||||
package v1alpha1
|
||||
|
||||
// LDAPIdentityProviderListerExpansion allows custom methods to be added to
|
||||
// LDAPIdentityProviderLister.
|
||||
type LDAPIdentityProviderListerExpansion interface{}
|
||||
|
||||
// LDAPIdentityProviderNamespaceListerExpansion allows custom methods to be added to
|
||||
// LDAPIdentityProviderNamespaceLister.
|
||||
type LDAPIdentityProviderNamespaceListerExpansion interface{}
|
||||
|
||||
// OIDCIdentityProviderListerExpansion allows custom methods to be added to
|
||||
// OIDCIdentityProviderLister.
|
||||
type OIDCIdentityProviderListerExpansion interface{}
|
||||
|
86
generated/latest/client/supervisor/listers/idp/v1alpha1/ldapidentityprovider.go
generated
Normal file
86
generated/latest/client/supervisor/listers/idp/v1alpha1/ldapidentityprovider.go
generated
Normal file
@ -0,0 +1,86 @@
|
||||
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
v1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// LDAPIdentityProviderLister helps list LDAPIdentityProviders.
|
||||
// All objects returned here must be treated as read-only.
|
||||
type LDAPIdentityProviderLister interface {
|
||||
// List lists all LDAPIdentityProviders in the indexer.
|
||||
// Objects returned here must be treated as read-only.
|
||||
List(selector labels.Selector) (ret []*v1alpha1.LDAPIdentityProvider, err error)
|
||||
// LDAPIdentityProviders returns an object that can list and get LDAPIdentityProviders.
|
||||
LDAPIdentityProviders(namespace string) LDAPIdentityProviderNamespaceLister
|
||||
LDAPIdentityProviderListerExpansion
|
||||
}
|
||||
|
||||
// lDAPIdentityProviderLister implements the LDAPIdentityProviderLister interface.
|
||||
type lDAPIdentityProviderLister struct {
|
||||
indexer cache.Indexer
|
||||
}
|
||||
|
||||
// NewLDAPIdentityProviderLister returns a new LDAPIdentityProviderLister.
|
||||
func NewLDAPIdentityProviderLister(indexer cache.Indexer) LDAPIdentityProviderLister {
|
||||
return &lDAPIdentityProviderLister{indexer: indexer}
|
||||
}
|
||||
|
||||
// List lists all LDAPIdentityProviders in the indexer.
|
||||
func (s *lDAPIdentityProviderLister) List(selector labels.Selector) (ret []*v1alpha1.LDAPIdentityProvider, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1alpha1.LDAPIdentityProvider))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// LDAPIdentityProviders returns an object that can list and get LDAPIdentityProviders.
|
||||
func (s *lDAPIdentityProviderLister) LDAPIdentityProviders(namespace string) LDAPIdentityProviderNamespaceLister {
|
||||
return lDAPIdentityProviderNamespaceLister{indexer: s.indexer, namespace: namespace}
|
||||
}
|
||||
|
||||
// LDAPIdentityProviderNamespaceLister helps list and get LDAPIdentityProviders.
|
||||
// All objects returned here must be treated as read-only.
|
||||
type LDAPIdentityProviderNamespaceLister interface {
|
||||
// List lists all LDAPIdentityProviders in the indexer for a given namespace.
|
||||
// Objects returned here must be treated as read-only.
|
||||
List(selector labels.Selector) (ret []*v1alpha1.LDAPIdentityProvider, err error)
|
||||
// Get retrieves the LDAPIdentityProvider from the indexer for a given namespace and name.
|
||||
// Objects returned here must be treated as read-only.
|
||||
Get(name string) (*v1alpha1.LDAPIdentityProvider, error)
|
||||
LDAPIdentityProviderNamespaceListerExpansion
|
||||
}
|
||||
|
||||
// lDAPIdentityProviderNamespaceLister implements the LDAPIdentityProviderNamespaceLister
|
||||
// interface.
|
||||
type lDAPIdentityProviderNamespaceLister struct {
|
||||
indexer cache.Indexer
|
||||
namespace string
|
||||
}
|
||||
|
||||
// List lists all LDAPIdentityProviders in the indexer for a given namespace.
|
||||
func (s lDAPIdentityProviderNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.LDAPIdentityProvider, err error) {
|
||||
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1alpha1.LDAPIdentityProvider))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the LDAPIdentityProvider from the indexer for a given namespace and name.
|
||||
func (s lDAPIdentityProviderNamespaceLister) Get(name string) (*v1alpha1.LDAPIdentityProvider, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v1alpha1.Resource("ldapidentityprovider"), name)
|
||||
}
|
||||
return obj.(*v1alpha1.LDAPIdentityProvider), nil
|
||||
}
|
3
go.mod
3
go.mod
@ -6,7 +6,9 @@ require (
|
||||
cloud.google.com/go v0.60.0 // indirect
|
||||
github.com/MakeNowJust/heredoc/v2 v2.0.1
|
||||
github.com/coreos/go-oidc/v3 v3.0.0
|
||||
github.com/creack/pty v1.1.11
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/go-ldap/ldap/v3 v3.3.0
|
||||
github.com/go-logr/logr v0.4.0
|
||||
github.com/go-logr/stdr v0.4.0
|
||||
github.com/go-openapi/spec v0.20.3
|
||||
@ -30,6 +32,7 @@ require (
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d
|
||||
gopkg.in/square/go-jose.v2 v2.5.1
|
||||
k8s.io/api v0.21.0
|
||||
k8s.io/apimachinery v0.21.0
|
||||
|
8
go.sum
8
go.sum
@ -47,6 +47,8 @@ github.com/Azure/go-autorest/logger v0.2.0 h1:e4RVHVZKC5p6UANLJHkM4OfR1UKZPj8Wt8
|
||||
github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c h1:/IBSNwUN8+eKzUzbJPqhK839ygXJ82sde8x3ogr6R28=
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
@ -146,6 +148,7 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
|
||||
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cucumber/godog v0.8.1/go.mod h1:vSh3r/lM+psC1BPXvdkSEuNjmXfpVqrMGYAElF6hxnA=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@ -198,12 +201,16 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.1 h1:pDbRAunXzIUXfx4CB2QJFv5IuPiuoW+sWvr/Us009o8=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
|
||||
github.com/go-bindata/go-bindata v3.1.1+incompatible/go.mod h1:xK8Dsgwmeed+BBsSy2XTopBn/8uK2HWuGSnA11C3Joo=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-ldap/ldap/v3 v3.3.0 h1:lwx+SJpgOHd8tG6SumBQZXCmNX51zM8B1cfxJ5gv4tQ=
|
||||
github.com/go-ldap/ldap/v3 v3.3.0/go.mod h1:iYS1MdmrmceOJ1QOTnRXrIs7i3kloqtmGQjRvjKpyMg=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||
@ -1094,6 +1101,7 @@ golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPh
|
||||
golang.org/x/crypto v0.0.0-20200320181102-891825fb96df/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
|
@ -20,6 +20,34 @@ set -euo pipefail
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
use_oidc_upstream=no
|
||||
use_ldap_upstream=no
|
||||
while (("$#")); do
|
||||
case "$1" in
|
||||
--ldap)
|
||||
use_ldap_upstream=yes
|
||||
shift
|
||||
;;
|
||||
--oidc)
|
||||
use_oidc_upstream=yes
|
||||
shift
|
||||
;;
|
||||
-*)
|
||||
log_error "Unsupported flag $1" >&2
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
log_error "Unsupported positional arg $1" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ "$use_oidc_upstream" == "no" && "$use_ldap_upstream" == "no" ]]; then
|
||||
echo "Error: Please use --oidc or --ldap to specify which type of upstream identity provider(s) you would like"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Read the env vars output by hack/prepare-for-integration-tests.sh
|
||||
source /tmp/integration-test-env
|
||||
|
||||
@ -73,8 +101,9 @@ sleep 5
|
||||
echo "Fetching FederationDomain discovery info..."
|
||||
https_proxy="$PINNIPED_TEST_PROXY" curl -fLsS --cacert "$root_ca_crt_path" "$issuer/.well-known/openid-configuration" | jq .
|
||||
|
||||
# Make an OIDCIdentityProvider which uses Dex to provide identity.
|
||||
cat <<EOF | kubectl apply --namespace "$PINNIPED_TEST_SUPERVISOR_NAMESPACE" -f -
|
||||
if [[ "$use_oidc_upstream" == "yes" ]]; then
|
||||
# Make an OIDCIdentityProvider which uses Dex to provide identity.
|
||||
cat <<EOF | kubectl apply --namespace "$PINNIPED_TEST_SUPERVISOR_NAMESPACE" -f -
|
||||
apiVersion: idp.supervisor.pinniped.dev/v1alpha1
|
||||
kind: OIDCIdentityProvider
|
||||
metadata:
|
||||
@ -92,8 +121,8 @@ spec:
|
||||
secretName: my-oidc-provider-client-secret
|
||||
EOF
|
||||
|
||||
# Make a Secret for the above OIDCIdentityProvider to describe the OIDC client configured in Dex.
|
||||
cat <<EOF | kubectl apply --namespace "$PINNIPED_TEST_SUPERVISOR_NAMESPACE" -f -
|
||||
# Make a Secret for the above OIDCIdentityProvider to describe the OIDC client configured in Dex.
|
||||
cat <<EOF | kubectl apply --namespace "$PINNIPED_TEST_SUPERVISOR_NAMESPACE" -f -
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
@ -104,10 +133,50 @@ stringData:
|
||||
type: "secrets.pinniped.dev/oidc-client"
|
||||
EOF
|
||||
|
||||
# Grant the test user some RBAC permissions so we can play with kubectl as that user.
|
||||
kubectl create clusterrolebinding test-user-can-view --clusterrole view \
|
||||
--user "$PINNIPED_TEST_SUPERVISOR_UPSTREAM_OIDC_USERNAME" \
|
||||
--dry-run=client --output yaml | kubectl apply -f -
|
||||
# Grant the test user some RBAC permissions so we can play with kubectl as that user.
|
||||
kubectl create clusterrolebinding oidc-test-user-can-view --clusterrole view \
|
||||
--user "$PINNIPED_TEST_SUPERVISOR_UPSTREAM_OIDC_USERNAME" \
|
||||
--dry-run=client --output yaml | kubectl apply -f -
|
||||
fi
|
||||
|
||||
if [[ "$use_ldap_upstream" == "yes" ]]; then
|
||||
# Make an LDAPIdentityProvider which uses OpenLDAP to provide identity.
|
||||
cat <<EOF | kubectl apply --namespace "$PINNIPED_TEST_SUPERVISOR_NAMESPACE" -f -
|
||||
apiVersion: idp.supervisor.pinniped.dev/v1alpha1
|
||||
kind: LDAPIdentityProvider
|
||||
metadata:
|
||||
name: my-ldap-provider
|
||||
spec:
|
||||
host: "$PINNIPED_TEST_LDAP_HOST"
|
||||
tls:
|
||||
certificateAuthorityData: "$PINNIPED_TEST_LDAP_LDAPS_CA_BUNDLE"
|
||||
bind:
|
||||
secretName: my-ldap-service-account
|
||||
userSearch:
|
||||
base: "$PINNIPED_TEST_LDAP_USERS_SEARCH_BASE"
|
||||
filter: "cn={}"
|
||||
attributes:
|
||||
uid: "$PINNIPED_TEST_LDAP_USER_UNIQUE_ID_ATTRIBUTE_NAME"
|
||||
username: "$PINNIPED_TEST_LDAP_USER_EMAIL_ATTRIBUTE_NAME"
|
||||
EOF
|
||||
|
||||
# Make a Secret for the above LDAPIdentityProvider to describe the bind account.
|
||||
cat <<EOF | kubectl apply --namespace "$PINNIPED_TEST_SUPERVISOR_NAMESPACE" -f -
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: my-ldap-service-account
|
||||
stringData:
|
||||
username: "$PINNIPED_TEST_LDAP_BIND_ACCOUNT_USERNAME"
|
||||
password: "$PINNIPED_TEST_LDAP_BIND_ACCOUNT_PASSWORD"
|
||||
type: "kubernetes.io/basic-auth"
|
||||
EOF
|
||||
|
||||
# Grant the test user some RBAC permissions so we can play with kubectl as that user.
|
||||
kubectl create clusterrolebinding ldap-test-user-can-view --clusterrole view \
|
||||
--user "$PINNIPED_TEST_LDAP_USER_EMAIL_ATTRIBUTE_VALUE" \
|
||||
--dry-run=client --output yaml | kubectl apply -f -
|
||||
fi
|
||||
|
||||
# Make a JWTAuthenticator which respects JWTs from the Supervisor's issuer.
|
||||
# The issuer URL must be accessible from within the cluster for OIDC discovery.
|
||||
@ -124,27 +193,39 @@ spec:
|
||||
EOF
|
||||
|
||||
echo "Waiting for JWTAuthenticator to initialize..."
|
||||
# Our integration tests wait 10 seconds, so use that same value here.
|
||||
sleep 10
|
||||
sleep 5
|
||||
|
||||
# Compile the CLI.
|
||||
go build ./cmd/pinniped
|
||||
|
||||
# Use the CLI to get the kubeconfig. Tell it that you don't want the browser to automatically open for logins.
|
||||
./pinniped get kubeconfig --oidc-skip-browser >kubeconfig
|
||||
https_proxy="$PINNIPED_TEST_PROXY" no_proxy="127.0.0.1" ./pinniped get kubeconfig --oidc-skip-browser >kubeconfig
|
||||
|
||||
# Clear the local CLI cache to ensure that the kubectl command below will need to perform a fresh login.
|
||||
rm -f "$HOME"/.config/pinniped/sessions.yaml
|
||||
rm -f "$HOME/.config/pinniped/sessions.yaml"
|
||||
rm -f "$HOME/.config/pinniped/credentials.yaml"
|
||||
|
||||
echo
|
||||
echo "Ready! 🚀"
|
||||
echo "To be able to access the login URL shown below, start Chrome like this:"
|
||||
echo " open -a \"Google Chrome\" --args --proxy-server=\"$PINNIPED_TEST_PROXY\""
|
||||
echo "Then use these credentials at the Dex login page:"
|
||||
echo " Username: $PINNIPED_TEST_SUPERVISOR_UPSTREAM_OIDC_USERNAME"
|
||||
echo " Password: $PINNIPED_TEST_SUPERVISOR_UPSTREAM_OIDC_PASSWORD"
|
||||
|
||||
# Perform a login using the kubectl plugin. This should print the URL to be followed for the Dex login page.
|
||||
if [[ "$use_oidc_upstream" == "yes" ]]; then
|
||||
echo
|
||||
echo "To be able to access the login URL shown below, start Chrome like this:"
|
||||
echo " open -a \"Google Chrome\" --args --proxy-server=\"$PINNIPED_TEST_PROXY\""
|
||||
echo "Then use these credentials at the Dex login page:"
|
||||
echo " Username: $PINNIPED_TEST_SUPERVISOR_UPSTREAM_OIDC_USERNAME"
|
||||
echo " Password: $PINNIPED_TEST_SUPERVISOR_UPSTREAM_OIDC_PASSWORD"
|
||||
fi
|
||||
|
||||
if [[ "$use_ldap_upstream" == "yes" ]]; then
|
||||
echo
|
||||
echo "When prompted for username and password by the CLI, use these values:"
|
||||
echo " Username: $PINNIPED_TEST_LDAP_USER_CN"
|
||||
echo " Password: $PINNIPED_TEST_LDAP_USER_PASSWORD"
|
||||
fi
|
||||
|
||||
# Perform a login using the kubectl plugin. This should print the URL to be followed for the Dex login page
|
||||
# if using an OIDC upstream, or should prompt on the CLI for username/password if using an LDAP upstream.
|
||||
echo
|
||||
echo "Running: https_proxy=\"$PINNIPED_TEST_PROXY\" no_proxy=\"127.0.0.1\" kubectl --kubeconfig ./kubeconfig get pods -A"
|
||||
https_proxy="$PINNIPED_TEST_PROXY" no_proxy="127.0.0.1" kubectl --kubeconfig ./kubeconfig get pods -A
|
||||
|
35
internal/authenticators/authenticators.go
Normal file
35
internal/authenticators/authenticators.go
Normal file
@ -0,0 +1,35 @@
|
||||
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package authenticators contains authenticator interfaces.
|
||||
package authenticators
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"k8s.io/apiserver/pkg/authentication/authenticator"
|
||||
)
|
||||
|
||||
// This interface is similar to the k8s token authenticator, but works with username/passwords instead
|
||||
// of a single token string.
|
||||
//
|
||||
// The return values should be as follows.
|
||||
// 1. For a successful authentication:
|
||||
// - A response which includes the username, uid, and groups in the userInfo. The username and uid must not be blank.
|
||||
// - true
|
||||
// - nil error
|
||||
// 2. For an unsuccessful authentication, e.g. bad username or password:
|
||||
// - nil response
|
||||
// - false
|
||||
// - nil error
|
||||
// 3. For an unexpected error, e.g. a network problem:
|
||||
// - nil response
|
||||
// - false
|
||||
// - an error
|
||||
// Other combinations of return values must be avoided.
|
||||
//
|
||||
// See k8s.io/apiserver/pkg/authentication/authenticator/interfaces.go for the token authenticator
|
||||
// interface, as well as the Response type.
|
||||
type UserAuthenticator interface {
|
||||
AuthenticateUser(ctx context.Context, username, password string) (*authenticator.Response, bool, error)
|
||||
}
|
@ -10,6 +10,7 @@ import (
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"k8s.io/utils/pointer"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"go.pinniped.dev/internal/constable"
|
||||
@ -69,27 +70,27 @@ func FromPath(path string) (*Config, error) {
|
||||
|
||||
func maybeSetAPIDefaults(apiConfig *APIConfigSpec) {
|
||||
if apiConfig.ServingCertificateConfig.DurationSeconds == nil {
|
||||
apiConfig.ServingCertificateConfig.DurationSeconds = int64Ptr(aboutAYear)
|
||||
apiConfig.ServingCertificateConfig.DurationSeconds = pointer.Int64Ptr(aboutAYear)
|
||||
}
|
||||
|
||||
if apiConfig.ServingCertificateConfig.RenewBeforeSeconds == nil {
|
||||
apiConfig.ServingCertificateConfig.RenewBeforeSeconds = int64Ptr(about9Months)
|
||||
apiConfig.ServingCertificateConfig.RenewBeforeSeconds = pointer.Int64Ptr(about9Months)
|
||||
}
|
||||
}
|
||||
|
||||
func maybeSetAPIGroupSuffixDefault(apiGroupSuffix **string) {
|
||||
if *apiGroupSuffix == nil {
|
||||
*apiGroupSuffix = stringPtr(groupsuffix.PinnipedDefaultSuffix)
|
||||
*apiGroupSuffix = pointer.StringPtr(groupsuffix.PinnipedDefaultSuffix)
|
||||
}
|
||||
}
|
||||
|
||||
func maybeSetKubeCertAgentDefaults(cfg *KubeCertAgentSpec) {
|
||||
if cfg.NamePrefix == nil {
|
||||
cfg.NamePrefix = stringPtr("pinniped-kube-cert-agent-")
|
||||
cfg.NamePrefix = pointer.StringPtr("pinniped-kube-cert-agent-")
|
||||
}
|
||||
|
||||
if cfg.Image == nil {
|
||||
cfg.Image = stringPtr("debian:latest")
|
||||
cfg.Image = pointer.StringPtr("debian:latest")
|
||||
}
|
||||
}
|
||||
|
||||
@ -146,11 +147,3 @@ func validateAPI(apiConfig *APIConfigSpec) error {
|
||||
func validateAPIGroupSuffix(apiGroupSuffix string) error {
|
||||
return groupsuffix.Validate(apiGroupSuffix)
|
||||
}
|
||||
|
||||
func int64Ptr(i int64) *int64 {
|
||||
return &i
|
||||
}
|
||||
|
||||
func stringPtr(s string) *string {
|
||||
return &s
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"k8s.io/utils/pointer"
|
||||
|
||||
"go.pinniped.dev/internal/here"
|
||||
"go.pinniped.dev/internal/plog"
|
||||
@ -55,15 +56,15 @@ func TestFromPath(t *testing.T) {
|
||||
`),
|
||||
wantConfig: &Config{
|
||||
DiscoveryInfo: DiscoveryInfoSpec{
|
||||
URL: stringPtr("https://some.discovery/url"),
|
||||
URL: pointer.StringPtr("https://some.discovery/url"),
|
||||
},
|
||||
APIConfig: APIConfigSpec{
|
||||
ServingCertificateConfig: ServingCertificateConfigSpec{
|
||||
DurationSeconds: int64Ptr(3600),
|
||||
RenewBeforeSeconds: int64Ptr(2400),
|
||||
DurationSeconds: pointer.Int64Ptr(3600),
|
||||
RenewBeforeSeconds: pointer.Int64Ptr(2400),
|
||||
},
|
||||
},
|
||||
APIGroupSuffix: stringPtr("some.suffix.com"),
|
||||
APIGroupSuffix: pointer.StringPtr("some.suffix.com"),
|
||||
NamesConfig: NamesConfigSpec{
|
||||
ServingCertificateSecret: "pinniped-concierge-api-tls-serving-certificate",
|
||||
CredentialIssuer: "pinniped-config",
|
||||
@ -80,8 +81,8 @@ func TestFromPath(t *testing.T) {
|
||||
"myLabelKey2": "myLabelValue2",
|
||||
},
|
||||
KubeCertAgentConfig: KubeCertAgentSpec{
|
||||
NamePrefix: stringPtr("kube-cert-agent-name-prefix-"),
|
||||
Image: stringPtr("kube-cert-agent-image"),
|
||||
NamePrefix: pointer.StringPtr("kube-cert-agent-name-prefix-"),
|
||||
Image: pointer.StringPtr("kube-cert-agent-image"),
|
||||
ImagePullSecrets: []string{"kube-cert-agent-image-pull-secret"},
|
||||
},
|
||||
LogLevel: plog.LevelDebug,
|
||||
@ -106,11 +107,11 @@ func TestFromPath(t *testing.T) {
|
||||
DiscoveryInfo: DiscoveryInfoSpec{
|
||||
URL: nil,
|
||||
},
|
||||
APIGroupSuffix: stringPtr("pinniped.dev"),
|
||||
APIGroupSuffix: pointer.StringPtr("pinniped.dev"),
|
||||
APIConfig: APIConfigSpec{
|
||||
ServingCertificateConfig: ServingCertificateConfigSpec{
|
||||
DurationSeconds: int64Ptr(60 * 60 * 24 * 365), // about a year
|
||||
RenewBeforeSeconds: int64Ptr(60 * 60 * 24 * 30 * 9), // about 9 months
|
||||
DurationSeconds: pointer.Int64Ptr(60 * 60 * 24 * 365), // about a year
|
||||
RenewBeforeSeconds: pointer.Int64Ptr(60 * 60 * 24 * 30 * 9), // about 9 months
|
||||
},
|
||||
},
|
||||
NamesConfig: NamesConfigSpec{
|
||||
@ -126,8 +127,8 @@ func TestFromPath(t *testing.T) {
|
||||
},
|
||||
Labels: map[string]string{},
|
||||
KubeCertAgentConfig: KubeCertAgentSpec{
|
||||
NamePrefix: stringPtr("pinniped-kube-cert-agent-"),
|
||||
Image: stringPtr("debian:latest"),
|
||||
NamePrefix: pointer.StringPtr("pinniped-kube-cert-agent-"),
|
||||
Image: pointer.StringPtr("debian:latest"),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"k8s.io/utils/pointer"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"go.pinniped.dev/internal/constable"
|
||||
@ -54,7 +55,7 @@ func FromPath(path string) (*Config, error) {
|
||||
|
||||
func maybeSetAPIGroupSuffixDefault(apiGroupSuffix **string) {
|
||||
if *apiGroupSuffix == nil {
|
||||
*apiGroupSuffix = stringPtr(groupsuffix.PinnipedDefaultSuffix)
|
||||
*apiGroupSuffix = pointer.StringPtr(groupsuffix.PinnipedDefaultSuffix)
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,7 +73,3 @@ func validateNames(names *NamesConfigSpec) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func stringPtr(s string) *string {
|
||||
return &s
|
||||
}
|
||||
|
@ -8,6 +8,8 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"k8s.io/utils/pointer"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"go.pinniped.dev/internal/here"
|
||||
@ -32,7 +34,7 @@ func TestFromPath(t *testing.T) {
|
||||
defaultTLSCertificateSecret: my-secret-name
|
||||
`),
|
||||
wantConfig: &Config{
|
||||
APIGroupSuffix: stringPtr("some.suffix.com"),
|
||||
APIGroupSuffix: pointer.StringPtr("some.suffix.com"),
|
||||
Labels: map[string]string{
|
||||
"myLabelKey1": "myLabelValue1",
|
||||
"myLabelKey2": "myLabelValue2",
|
||||
@ -50,7 +52,7 @@ func TestFromPath(t *testing.T) {
|
||||
defaultTLSCertificateSecret: my-secret-name
|
||||
`),
|
||||
wantConfig: &Config{
|
||||
APIGroupSuffix: stringPtr("pinniped.dev"),
|
||||
APIGroupSuffix: pointer.StringPtr("pinniped.dev"),
|
||||
Labels: map[string]string{},
|
||||
NamesConfig: NamesConfigSpec{
|
||||
DefaultTLSCertificateSecret: "my-secret-name",
|
||||
|
68
internal/controller/conditionsutil/conditions_util.go.go
Normal file
68
internal/controller/conditionsutil/conditions_util.go.go
Normal file
@ -0,0 +1,68 @@
|
||||
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package conditionsutil
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
"k8s.io/apimachinery/pkg/api/equality"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
|
||||
)
|
||||
|
||||
// Merge merges conditions into conditionsToUpdate. If returns true if it merged any error conditions.
|
||||
func Merge(conditions []*v1alpha1.Condition, observedGeneration int64, conditionsToUpdate *[]v1alpha1.Condition, log logr.Logger) bool {
|
||||
hadErrorCondition := false
|
||||
for i := range conditions {
|
||||
cond := conditions[i].DeepCopy()
|
||||
cond.LastTransitionTime = v1.Now()
|
||||
cond.ObservedGeneration = observedGeneration
|
||||
if mergeCondition(conditionsToUpdate, cond) {
|
||||
log.Info("updated condition", "type", cond.Type, "status", cond.Status, "reason", cond.Reason, "message", cond.Message)
|
||||
}
|
||||
if cond.Status == v1alpha1.ConditionFalse {
|
||||
hadErrorCondition = true
|
||||
}
|
||||
}
|
||||
sort.SliceStable(*conditionsToUpdate, func(i, j int) bool {
|
||||
return (*conditionsToUpdate)[i].Type < (*conditionsToUpdate)[j].Type
|
||||
})
|
||||
return hadErrorCondition
|
||||
}
|
||||
|
||||
// mergeCondition merges a new v1alpha1.Condition into a slice of existing conditions. It returns true
|
||||
// if the condition has meaningfully changed.
|
||||
func mergeCondition(existing *[]v1alpha1.Condition, new *v1alpha1.Condition) bool {
|
||||
// Find any existing condition with a matching type.
|
||||
var old *v1alpha1.Condition
|
||||
for i := range *existing {
|
||||
if (*existing)[i].Type == new.Type {
|
||||
old = &(*existing)[i]
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// If there is no existing condition of this type, append this one and we're done.
|
||||
if old == nil {
|
||||
*existing = append(*existing, *new)
|
||||
return true
|
||||
}
|
||||
|
||||
// Set the LastTransitionTime depending on whether the status has changed.
|
||||
new = new.DeepCopy()
|
||||
if old.Status == new.Status {
|
||||
new.LastTransitionTime = old.LastTransitionTime
|
||||
}
|
||||
|
||||
// If anything has actually changed, update the entry and return true.
|
||||
if !equality.Semantic.DeepEqual(old, new) {
|
||||
*old = *new
|
||||
return true
|
||||
}
|
||||
|
||||
// Otherwise the entry is already up to date.
|
||||
return false
|
||||
}
|
@ -0,0 +1,372 @@
|
||||
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package ldapupstreamwatcher implements a controller which watches LDAPIdentityProviders.
|
||||
package ldapupstreamwatcher
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/equality"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
corev1informers "k8s.io/client-go/informers/core/v1"
|
||||
"k8s.io/klog/v2/klogr"
|
||||
|
||||
"go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
|
||||
pinnipedclientset "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned"
|
||||
idpinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions/idp/v1alpha1"
|
||||
pinnipedcontroller "go.pinniped.dev/internal/controller"
|
||||
"go.pinniped.dev/internal/controller/conditionsutil"
|
||||
"go.pinniped.dev/internal/controller/supervisorconfig/upstreamwatchers"
|
||||
"go.pinniped.dev/internal/controllerlib"
|
||||
"go.pinniped.dev/internal/oidc/provider"
|
||||
"go.pinniped.dev/internal/upstreamldap"
|
||||
)
|
||||
|
||||
const (
|
||||
ldapControllerName = "ldap-upstream-observer"
|
||||
ldapBindAccountSecretType = corev1.SecretTypeBasicAuth
|
||||
testLDAPConnectionTimeout = 90 * time.Second
|
||||
|
||||
// Constants related to conditions.
|
||||
typeBindSecretValid = "BindSecretValid"
|
||||
typeTLSConfigurationValid = "TLSConfigurationValid"
|
||||
typeLDAPConnectionValid = "LDAPConnectionValid"
|
||||
reasonLDAPConnectionError = "LDAPConnectionError"
|
||||
noTLSConfigurationMessage = "no TLS configuration provided"
|
||||
loadedTLSConfigurationMessage = "loaded TLS configuration"
|
||||
)
|
||||
|
||||
// UpstreamLDAPIdentityProviderICache is a thread safe cache that holds a list of validated upstream LDAP IDP configurations.
|
||||
type UpstreamLDAPIdentityProviderICache interface {
|
||||
SetLDAPIdentityProviders([]provider.UpstreamLDAPIdentityProviderI)
|
||||
}
|
||||
|
||||
type ldapWatcherController struct {
|
||||
cache UpstreamLDAPIdentityProviderICache
|
||||
validatedSecretVersionsCache *secretVersionCache
|
||||
ldapDialer upstreamldap.LDAPDialer
|
||||
client pinnipedclientset.Interface
|
||||
ldapIdentityProviderInformer idpinformers.LDAPIdentityProviderInformer
|
||||
secretInformer corev1informers.SecretInformer
|
||||
}
|
||||
|
||||
// An in-memory cache with an entry for each LDAPIdentityProvider, to keep track of which ResourceVersion
|
||||
// of the bind Secret was used during the most recent successful validation.
|
||||
type secretVersionCache struct {
|
||||
ResourceVersionsByName map[string]string
|
||||
}
|
||||
|
||||
func newSecretVersionCache() *secretVersionCache {
|
||||
return &secretVersionCache{ResourceVersionsByName: map[string]string{}}
|
||||
}
|
||||
|
||||
// New instantiates a new controllerlib.Controller which will populate the provided UpstreamLDAPIdentityProviderICache.
|
||||
func New(
|
||||
idpCache UpstreamLDAPIdentityProviderICache,
|
||||
client pinnipedclientset.Interface,
|
||||
ldapIdentityProviderInformer idpinformers.LDAPIdentityProviderInformer,
|
||||
secretInformer corev1informers.SecretInformer,
|
||||
withInformer pinnipedcontroller.WithInformerOptionFunc,
|
||||
) controllerlib.Controller {
|
||||
return newInternal(
|
||||
idpCache,
|
||||
// start with an empty secretVersionCache
|
||||
newSecretVersionCache(),
|
||||
// nil means to use a real production dialer when creating objects to add to the cache
|
||||
nil,
|
||||
client,
|
||||
ldapIdentityProviderInformer,
|
||||
secretInformer,
|
||||
withInformer,
|
||||
)
|
||||
}
|
||||
|
||||
// For test dependency injection purposes.
|
||||
func newInternal(
|
||||
idpCache UpstreamLDAPIdentityProviderICache,
|
||||
validatedSecretVersionsCache *secretVersionCache,
|
||||
ldapDialer upstreamldap.LDAPDialer,
|
||||
client pinnipedclientset.Interface,
|
||||
ldapIdentityProviderInformer idpinformers.LDAPIdentityProviderInformer,
|
||||
secretInformer corev1informers.SecretInformer,
|
||||
withInformer pinnipedcontroller.WithInformerOptionFunc,
|
||||
) controllerlib.Controller {
|
||||
c := ldapWatcherController{
|
||||
cache: idpCache,
|
||||
validatedSecretVersionsCache: validatedSecretVersionsCache,
|
||||
ldapDialer: ldapDialer,
|
||||
client: client,
|
||||
ldapIdentityProviderInformer: ldapIdentityProviderInformer,
|
||||
secretInformer: secretInformer,
|
||||
}
|
||||
return controllerlib.New(
|
||||
controllerlib.Config{Name: ldapControllerName, Syncer: &c},
|
||||
withInformer(
|
||||
ldapIdentityProviderInformer,
|
||||
pinnipedcontroller.MatchAnythingFilter(pinnipedcontroller.SingletonQueue()),
|
||||
controllerlib.InformerOption{},
|
||||
),
|
||||
withInformer(
|
||||
secretInformer,
|
||||
pinnipedcontroller.MatchAnySecretOfTypeFilter(ldapBindAccountSecretType, pinnipedcontroller.SingletonQueue()),
|
||||
controllerlib.InformerOption{},
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// Sync implements controllerlib.Syncer.
|
||||
func (c *ldapWatcherController) Sync(ctx controllerlib.Context) error {
|
||||
actualUpstreams, err := c.ldapIdentityProviderInformer.Lister().List(labels.Everything())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to list LDAPIdentityProviders: %w", err)
|
||||
}
|
||||
|
||||
requeue := false
|
||||
validatedUpstreams := make([]provider.UpstreamLDAPIdentityProviderI, 0, len(actualUpstreams))
|
||||
for _, upstream := range actualUpstreams {
|
||||
valid, requestedRequeue := c.validateUpstream(ctx.Context, upstream)
|
||||
if valid != nil {
|
||||
validatedUpstreams = append(validatedUpstreams, valid)
|
||||
}
|
||||
if requestedRequeue {
|
||||
requeue = true
|
||||
}
|
||||
}
|
||||
|
||||
c.cache.SetLDAPIdentityProviders(validatedUpstreams)
|
||||
|
||||
if requeue {
|
||||
return controllerlib.ErrSyntheticRequeue
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ldapWatcherController) validateUpstream(ctx context.Context, upstream *v1alpha1.LDAPIdentityProvider) (p provider.UpstreamLDAPIdentityProviderI, requeue bool) {
|
||||
spec := upstream.Spec
|
||||
|
||||
config := &upstreamldap.ProviderConfig{
|
||||
Name: upstream.Name,
|
||||
Host: spec.Host,
|
||||
UserSearch: upstreamldap.UserSearchConfig{
|
||||
Base: spec.UserSearch.Base,
|
||||
Filter: spec.UserSearch.Filter,
|
||||
UsernameAttribute: spec.UserSearch.Attributes.Username,
|
||||
UIDAttribute: spec.UserSearch.Attributes.UID,
|
||||
},
|
||||
Dialer: c.ldapDialer,
|
||||
}
|
||||
|
||||
conditions := []*v1alpha1.Condition{}
|
||||
secretValidCondition, currentSecretVersion := c.validateSecret(upstream, config)
|
||||
tlsValidCondition := c.validateTLSConfig(upstream, config)
|
||||
conditions = append(conditions, secretValidCondition, tlsValidCondition)
|
||||
|
||||
// No point in trying to connect to the server if the config was already determined to be invalid.
|
||||
var finishedConfigCondition *v1alpha1.Condition
|
||||
if secretValidCondition.Status == v1alpha1.ConditionTrue && tlsValidCondition.Status == v1alpha1.ConditionTrue {
|
||||
finishedConfigCondition = c.validateFinishedConfig(ctx, upstream, config, currentSecretVersion)
|
||||
if finishedConfigCondition != nil {
|
||||
conditions = append(conditions, finishedConfigCondition)
|
||||
}
|
||||
}
|
||||
|
||||
c.updateStatus(ctx, upstream, conditions)
|
||||
|
||||
switch {
|
||||
case secretValidCondition.Status != v1alpha1.ConditionTrue || tlsValidCondition.Status != v1alpha1.ConditionTrue:
|
||||
// Invalid provider, so do not load it into the cache.
|
||||
p = nil
|
||||
requeue = true
|
||||
case finishedConfigCondition != nil && finishedConfigCondition.Status != v1alpha1.ConditionTrue:
|
||||
// Error but load it into the cache anyway, treating this condition failure more like a warning.
|
||||
p = upstreamldap.New(*config)
|
||||
// Try again hoping that the condition will improve.
|
||||
requeue = true
|
||||
default:
|
||||
// Fully validated provider, so load it into the cache.
|
||||
p = upstreamldap.New(*config)
|
||||
requeue = false
|
||||
}
|
||||
|
||||
return p, requeue
|
||||
}
|
||||
|
||||
func (c *ldapWatcherController) validateTLSConfig(upstream *v1alpha1.LDAPIdentityProvider, config *upstreamldap.ProviderConfig) *v1alpha1.Condition {
|
||||
tlsSpec := upstream.Spec.TLS
|
||||
if tlsSpec == nil {
|
||||
return c.validTLSCondition(noTLSConfigurationMessage)
|
||||
}
|
||||
if len(tlsSpec.CertificateAuthorityData) == 0 {
|
||||
return c.validTLSCondition(loadedTLSConfigurationMessage)
|
||||
}
|
||||
|
||||
bundle, err := base64.StdEncoding.DecodeString(tlsSpec.CertificateAuthorityData)
|
||||
if err != nil {
|
||||
return c.invalidTLSCondition(fmt.Sprintf("certificateAuthorityData is invalid: %s", err.Error()))
|
||||
}
|
||||
|
||||
ca := x509.NewCertPool()
|
||||
ok := ca.AppendCertsFromPEM(bundle)
|
||||
if !ok {
|
||||
return c.invalidTLSCondition(fmt.Sprintf("certificateAuthorityData is invalid: %s", upstreamwatchers.ErrNoCertificates))
|
||||
}
|
||||
|
||||
config.CABundle = bundle
|
||||
return c.validTLSCondition(loadedTLSConfigurationMessage)
|
||||
}
|
||||
|
||||
func (c *ldapWatcherController) validateFinishedConfig(ctx context.Context, upstream *v1alpha1.LDAPIdentityProvider, config *upstreamldap.ProviderConfig, currentSecretVersion string) *v1alpha1.Condition {
|
||||
ldapProvider := upstreamldap.New(*config)
|
||||
|
||||
if c.hasPreviousSuccessfulConditionForCurrentSpecGenerationAndSecretVersion(upstream, currentSecretVersion) {
|
||||
return nil
|
||||
}
|
||||
|
||||
testConnectionTimeout, cancelFunc := context.WithTimeout(ctx, testLDAPConnectionTimeout)
|
||||
defer cancelFunc()
|
||||
|
||||
condition := c.testConnection(testConnectionTimeout, upstream, config, ldapProvider, currentSecretVersion)
|
||||
|
||||
if condition.Status == v1alpha1.ConditionTrue {
|
||||
// Remember (in-memory for this pod) that the controller has successfully validated the LDAP provider
|
||||
// using this version of the Secret. This is for performance reasons, to avoid attempting to connect to
|
||||
// the LDAP server more than is needed. If the pod restarts, it will attempt this validation again.
|
||||
c.validatedSecretVersionsCache.ResourceVersionsByName[upstream.GetName()] = currentSecretVersion
|
||||
}
|
||||
|
||||
return condition
|
||||
}
|
||||
|
||||
func (c *ldapWatcherController) testConnection(
|
||||
ctx context.Context,
|
||||
upstream *v1alpha1.LDAPIdentityProvider,
|
||||
config *upstreamldap.ProviderConfig,
|
||||
ldapProvider *upstreamldap.Provider,
|
||||
currentSecretVersion string,
|
||||
) *v1alpha1.Condition {
|
||||
err := ldapProvider.TestConnection(ctx)
|
||||
if err != nil {
|
||||
return &v1alpha1.Condition{
|
||||
Type: typeLDAPConnectionValid,
|
||||
Status: v1alpha1.ConditionFalse,
|
||||
Reason: reasonLDAPConnectionError,
|
||||
Message: fmt.Sprintf(`could not successfully connect to "%s" and bind as user "%s": %s`,
|
||||
config.Host, config.BindUsername, err.Error()),
|
||||
}
|
||||
}
|
||||
|
||||
return &v1alpha1.Condition{
|
||||
Type: typeLDAPConnectionValid,
|
||||
Status: v1alpha1.ConditionTrue,
|
||||
Reason: upstreamwatchers.ReasonSuccess,
|
||||
Message: fmt.Sprintf(`successfully able to connect to "%s" and bind as user "%s" [validated with Secret "%s" at version "%s"]`,
|
||||
config.Host, config.BindUsername, upstream.Spec.Bind.SecretName, currentSecretVersion),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ldapWatcherController) hasPreviousSuccessfulConditionForCurrentSpecGenerationAndSecretVersion(upstream *v1alpha1.LDAPIdentityProvider, currentSecretVersion string) bool {
|
||||
currentGeneration := upstream.Generation
|
||||
for _, cond := range upstream.Status.Conditions {
|
||||
if cond.Type == typeLDAPConnectionValid && cond.Status == v1alpha1.ConditionTrue && cond.ObservedGeneration == currentGeneration {
|
||||
// Found a previously successful condition for the current spec generation.
|
||||
// Now figure out which version of the bind Secret was used during that previous validation, if any.
|
||||
validatedSecretVersion := c.validatedSecretVersionsCache.ResourceVersionsByName[upstream.GetName()]
|
||||
if validatedSecretVersion == currentSecretVersion {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *ldapWatcherController) validTLSCondition(message string) *v1alpha1.Condition {
|
||||
return &v1alpha1.Condition{
|
||||
Type: typeTLSConfigurationValid,
|
||||
Status: v1alpha1.ConditionTrue,
|
||||
Reason: upstreamwatchers.ReasonSuccess,
|
||||
Message: message,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ldapWatcherController) invalidTLSCondition(message string) *v1alpha1.Condition {
|
||||
return &v1alpha1.Condition{
|
||||
Type: typeTLSConfigurationValid,
|
||||
Status: v1alpha1.ConditionFalse,
|
||||
Reason: upstreamwatchers.ReasonInvalidTLSConfig,
|
||||
Message: message,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ldapWatcherController) validateSecret(upstream *v1alpha1.LDAPIdentityProvider, config *upstreamldap.ProviderConfig) (*v1alpha1.Condition, string) {
|
||||
secretName := upstream.Spec.Bind.SecretName
|
||||
|
||||
secret, err := c.secretInformer.Lister().Secrets(upstream.Namespace).Get(secretName)
|
||||
if err != nil {
|
||||
return &v1alpha1.Condition{
|
||||
Type: typeBindSecretValid,
|
||||
Status: v1alpha1.ConditionFalse,
|
||||
Reason: upstreamwatchers.ReasonNotFound,
|
||||
Message: err.Error(),
|
||||
}, ""
|
||||
}
|
||||
|
||||
if secret.Type != corev1.SecretTypeBasicAuth {
|
||||
return &v1alpha1.Condition{
|
||||
Type: typeBindSecretValid,
|
||||
Status: v1alpha1.ConditionFalse,
|
||||
Reason: upstreamwatchers.ReasonWrongType,
|
||||
Message: fmt.Sprintf("referenced Secret %q has wrong type %q (should be %q)",
|
||||
secretName, secret.Type, corev1.SecretTypeBasicAuth),
|
||||
}, secret.ResourceVersion
|
||||
}
|
||||
|
||||
config.BindUsername = string(secret.Data[corev1.BasicAuthUsernameKey])
|
||||
config.BindPassword = string(secret.Data[corev1.BasicAuthPasswordKey])
|
||||
if len(config.BindUsername) == 0 || len(config.BindPassword) == 0 {
|
||||
return &v1alpha1.Condition{
|
||||
Type: typeBindSecretValid,
|
||||
Status: v1alpha1.ConditionFalse,
|
||||
Reason: upstreamwatchers.ReasonMissingKeys,
|
||||
Message: fmt.Sprintf("referenced Secret %q is missing required keys %q",
|
||||
secretName, []string{corev1.BasicAuthUsernameKey, corev1.BasicAuthPasswordKey}),
|
||||
}, secret.ResourceVersion
|
||||
}
|
||||
|
||||
return &v1alpha1.Condition{
|
||||
Type: typeBindSecretValid,
|
||||
Status: v1alpha1.ConditionTrue,
|
||||
Reason: upstreamwatchers.ReasonSuccess,
|
||||
Message: "loaded bind secret",
|
||||
}, secret.ResourceVersion
|
||||
}
|
||||
|
||||
func (c *ldapWatcherController) updateStatus(ctx context.Context, upstream *v1alpha1.LDAPIdentityProvider, conditions []*v1alpha1.Condition) {
|
||||
log := klogr.New().WithValues("namespace", upstream.Namespace, "name", upstream.Name)
|
||||
updated := upstream.DeepCopy()
|
||||
|
||||
hadErrorCondition := conditionsutil.Merge(conditions, upstream.Generation, &updated.Status.Conditions, log)
|
||||
|
||||
updated.Status.Phase = v1alpha1.LDAPPhaseReady
|
||||
if hadErrorCondition {
|
||||
updated.Status.Phase = v1alpha1.LDAPPhaseError
|
||||
}
|
||||
|
||||
if equality.Semantic.DeepEqual(upstream, updated) {
|
||||
return // nothing to update
|
||||
}
|
||||
|
||||
_, err := c.client.
|
||||
IDPV1alpha1().
|
||||
LDAPIdentityProviders(upstream.Namespace).
|
||||
UpdateStatus(ctx, updated, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
log.Error(err, "failed to update status")
|
||||
}
|
||||
}
|
@ -0,0 +1,793 @@
|
||||
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package ldapupstreamwatcher
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sort"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/stretchr/testify/require"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/informers"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
|
||||
"go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
|
||||
pinnipedfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
|
||||
pinnipedinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions"
|
||||
"go.pinniped.dev/internal/certauthority"
|
||||
"go.pinniped.dev/internal/controllerlib"
|
||||
"go.pinniped.dev/internal/mocks/mockldapconn"
|
||||
"go.pinniped.dev/internal/oidc/provider"
|
||||
"go.pinniped.dev/internal/testutil"
|
||||
"go.pinniped.dev/internal/upstreamldap"
|
||||
)
|
||||
|
||||
func TestLDAPUpstreamWatcherControllerFilterSecrets(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
secret metav1.Object
|
||||
wantAdd bool
|
||||
wantUpdate bool
|
||||
wantDelete bool
|
||||
}{
|
||||
{
|
||||
name: "a secret of the right type",
|
||||
secret: &corev1.Secret{
|
||||
Type: corev1.SecretTypeBasicAuth,
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "some-name", Namespace: "some-namespace"},
|
||||
},
|
||||
wantAdd: true,
|
||||
wantUpdate: true,
|
||||
wantDelete: true,
|
||||
},
|
||||
{
|
||||
name: "a secret of the wrong type",
|
||||
secret: &corev1.Secret{
|
||||
Type: "this-is-the-wrong-type",
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "some-name", Namespace: "some-namespace"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "resource of a data type which is not watched by this controller",
|
||||
secret: &corev1.Namespace{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "some-name", Namespace: "some-namespace"},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
test := test
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
fakePinnipedClient := pinnipedfake.NewSimpleClientset()
|
||||
pinnipedInformers := pinnipedinformers.NewSharedInformerFactory(fakePinnipedClient, 0)
|
||||
ldapIDPInformer := pinnipedInformers.IDP().V1alpha1().LDAPIdentityProviders()
|
||||
fakeKubeClient := fake.NewSimpleClientset()
|
||||
kubeInformers := informers.NewSharedInformerFactory(fakeKubeClient, 0)
|
||||
secretInformer := kubeInformers.Core().V1().Secrets()
|
||||
withInformer := testutil.NewObservableWithInformerOption()
|
||||
|
||||
New(nil, nil, ldapIDPInformer, secretInformer, withInformer.WithInformer)
|
||||
|
||||
unrelated := corev1.Secret{}
|
||||
filter := withInformer.GetFilterForInformer(secretInformer)
|
||||
require.Equal(t, test.wantAdd, filter.Add(test.secret))
|
||||
require.Equal(t, test.wantUpdate, filter.Update(&unrelated, test.secret))
|
||||
require.Equal(t, test.wantUpdate, filter.Update(test.secret, &unrelated))
|
||||
require.Equal(t, test.wantDelete, filter.Delete(test.secret))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLDAPUpstreamWatcherControllerFilterLDAPIdentityProviders(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
idp metav1.Object
|
||||
wantAdd bool
|
||||
wantUpdate bool
|
||||
wantDelete bool
|
||||
}{
|
||||
{
|
||||
name: "any LDAPIdentityProvider",
|
||||
idp: &v1alpha1.LDAPIdentityProvider{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "some-name", Namespace: "some-namespace"},
|
||||
},
|
||||
wantAdd: true,
|
||||
wantUpdate: true,
|
||||
wantDelete: true,
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
test := test
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
fakePinnipedClient := pinnipedfake.NewSimpleClientset()
|
||||
pinnipedInformers := pinnipedinformers.NewSharedInformerFactory(fakePinnipedClient, 0)
|
||||
ldapIDPInformer := pinnipedInformers.IDP().V1alpha1().LDAPIdentityProviders()
|
||||
fakeKubeClient := fake.NewSimpleClientset()
|
||||
kubeInformers := informers.NewSharedInformerFactory(fakeKubeClient, 0)
|
||||
secretInformer := kubeInformers.Core().V1().Secrets()
|
||||
withInformer := testutil.NewObservableWithInformerOption()
|
||||
|
||||
New(nil, nil, ldapIDPInformer, secretInformer, withInformer.WithInformer)
|
||||
|
||||
unrelated := corev1.Secret{}
|
||||
filter := withInformer.GetFilterForInformer(ldapIDPInformer)
|
||||
require.Equal(t, test.wantAdd, filter.Add(test.idp))
|
||||
require.Equal(t, test.wantUpdate, filter.Update(&unrelated, test.idp))
|
||||
require.Equal(t, test.wantUpdate, filter.Update(test.idp, &unrelated))
|
||||
require.Equal(t, test.wantDelete, filter.Delete(test.idp))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Wrap the func into a struct so the test can do deep equal assertions on instances of upstreamldap.Provider.
|
||||
type comparableDialer struct {
|
||||
upstreamldap.LDAPDialerFunc
|
||||
}
|
||||
|
||||
func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
|
||||
t.Parallel()
|
||||
now := metav1.NewTime(time.Now().UTC())
|
||||
|
||||
const (
|
||||
testNamespace = "test-namespace"
|
||||
testName = "test-name"
|
||||
testSecretName = "test-bind-secret"
|
||||
testBindUsername = "test-bind-username"
|
||||
testBindPassword = "test-bind-password"
|
||||
testHost = "ldap.example.com:123"
|
||||
testUserSearchBase = "test-user-search-base"
|
||||
testUserSearchFilter = "test-user-search-filter"
|
||||
testUsernameAttrName = "test-username-attr"
|
||||
testUIDAttrName = "test-uid-attr"
|
||||
)
|
||||
|
||||
testValidSecretData := map[string][]byte{"username": []byte(testBindUsername), "password": []byte(testBindPassword)}
|
||||
|
||||
testCA, err := certauthority.New("test CA", time.Minute)
|
||||
require.NoError(t, err)
|
||||
testCABundle := testCA.Bundle()
|
||||
testCABundleBase64Encoded := base64.StdEncoding.EncodeToString(testCABundle)
|
||||
|
||||
validUpstream := &v1alpha1.LDAPIdentityProvider{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: testName, Namespace: testNamespace, Generation: 1234},
|
||||
Spec: v1alpha1.LDAPIdentityProviderSpec{
|
||||
Host: testHost,
|
||||
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testCABundleBase64Encoded},
|
||||
Bind: v1alpha1.LDAPIdentityProviderBind{SecretName: testSecretName},
|
||||
UserSearch: v1alpha1.LDAPIdentityProviderUserSearch{
|
||||
Base: testUserSearchBase,
|
||||
Filter: testUserSearchFilter,
|
||||
Attributes: v1alpha1.LDAPIdentityProviderUserSearchAttributes{
|
||||
Username: testUsernameAttrName,
|
||||
UID: testUIDAttrName,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
editedValidUpstream := func(editFunc func(*v1alpha1.LDAPIdentityProvider)) *v1alpha1.LDAPIdentityProvider {
|
||||
deepCopy := validUpstream.DeepCopy()
|
||||
editFunc(deepCopy)
|
||||
return deepCopy
|
||||
}
|
||||
|
||||
providerConfigForValidUpstream := &upstreamldap.ProviderConfig{
|
||||
Name: testName,
|
||||
Host: testHost,
|
||||
CABundle: testCABundle,
|
||||
BindUsername: testBindUsername,
|
||||
BindPassword: testBindPassword,
|
||||
UserSearch: upstreamldap.UserSearchConfig{
|
||||
Base: testUserSearchBase,
|
||||
Filter: testUserSearchFilter,
|
||||
UsernameAttribute: testUsernameAttrName,
|
||||
UIDAttribute: testUIDAttrName,
|
||||
},
|
||||
}
|
||||
|
||||
bindSecretValidTrueCondition := func(gen int64) v1alpha1.Condition {
|
||||
return v1alpha1.Condition{
|
||||
Type: "BindSecretValid",
|
||||
Status: "True",
|
||||
LastTransitionTime: now,
|
||||
Reason: "Success",
|
||||
Message: "loaded bind secret",
|
||||
ObservedGeneration: gen,
|
||||
}
|
||||
}
|
||||
ldapConnectionValidTrueCondition := func(gen int64, secretVersion string) v1alpha1.Condition {
|
||||
return v1alpha1.Condition{
|
||||
Type: "LDAPConnectionValid",
|
||||
Status: "True",
|
||||
LastTransitionTime: now,
|
||||
Reason: "Success",
|
||||
Message: fmt.Sprintf(
|
||||
`successfully able to connect to "%s" and bind as user "%s" [validated with Secret "%s" at version "%s"]`,
|
||||
testHost, testBindUsername, testSecretName, secretVersion),
|
||||
ObservedGeneration: gen,
|
||||
}
|
||||
}
|
||||
tlsConfigurationValidLoadedTrueCondition := func(gen int64) v1alpha1.Condition {
|
||||
return v1alpha1.Condition{
|
||||
Type: "TLSConfigurationValid",
|
||||
Status: "True",
|
||||
LastTransitionTime: now,
|
||||
Reason: "Success",
|
||||
Message: "loaded TLS configuration",
|
||||
ObservedGeneration: gen,
|
||||
}
|
||||
}
|
||||
allConditionsTrue := func(gen int64, secretVersion string) []v1alpha1.Condition {
|
||||
return []v1alpha1.Condition{
|
||||
bindSecretValidTrueCondition(gen),
|
||||
ldapConnectionValidTrueCondition(gen, secretVersion),
|
||||
tlsConfigurationValidLoadedTrueCondition(gen),
|
||||
}
|
||||
}
|
||||
|
||||
validBindUserSecret := func(secretVersion string) *corev1.Secret {
|
||||
return &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: testSecretName, Namespace: testNamespace, ResourceVersion: secretVersion},
|
||||
Type: corev1.SecretTypeBasicAuth,
|
||||
Data: testValidSecretData,
|
||||
}
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
initialValidatedSecretVersions map[string]string
|
||||
inputUpstreams []runtime.Object
|
||||
inputSecrets []runtime.Object
|
||||
setupMocks func(conn *mockldapconn.MockConn)
|
||||
dialError error
|
||||
wantErr string
|
||||
wantResultingCache []*upstreamldap.ProviderConfig
|
||||
wantResultingUpstreams []v1alpha1.LDAPIdentityProvider
|
||||
wantValidatedSecretVersions map[string]string
|
||||
}{
|
||||
{
|
||||
name: "no LDAPIdentityProvider upstreams clears the cache",
|
||||
wantResultingCache: []*upstreamldap.ProviderConfig{},
|
||||
},
|
||||
{
|
||||
name: "one valid upstream updates the cache to include only that upstream",
|
||||
inputUpstreams: []runtime.Object{validUpstream},
|
||||
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
|
||||
setupMocks: func(conn *mockldapconn.MockConn) {
|
||||
// Should perform a test dial and bind.
|
||||
conn.EXPECT().Bind(testBindUsername, testBindPassword).Times(1)
|
||||
conn.EXPECT().Close().Times(1)
|
||||
},
|
||||
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstream},
|
||||
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234},
|
||||
Status: v1alpha1.LDAPIdentityProviderStatus{
|
||||
Phase: "Ready",
|
||||
Conditions: allConditionsTrue(1234, "4242"),
|
||||
},
|
||||
}},
|
||||
wantValidatedSecretVersions: map[string]string{testName: "4242"},
|
||||
},
|
||||
{
|
||||
name: "missing secret",
|
||||
inputUpstreams: []runtime.Object{validUpstream},
|
||||
inputSecrets: []runtime.Object{},
|
||||
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
|
||||
wantResultingCache: []*upstreamldap.ProviderConfig{},
|
||||
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234},
|
||||
Status: v1alpha1.LDAPIdentityProviderStatus{
|
||||
Phase: "Error",
|
||||
Conditions: []v1alpha1.Condition{
|
||||
{
|
||||
Type: "BindSecretValid",
|
||||
Status: "False",
|
||||
LastTransitionTime: now,
|
||||
Reason: "SecretNotFound",
|
||||
Message: fmt.Sprintf(`secret "%s" not found`, testSecretName),
|
||||
ObservedGeneration: 1234,
|
||||
},
|
||||
tlsConfigurationValidLoadedTrueCondition(1234),
|
||||
},
|
||||
},
|
||||
}},
|
||||
},
|
||||
{
|
||||
name: "secret has wrong type",
|
||||
inputUpstreams: []runtime.Object{validUpstream},
|
||||
inputSecrets: []runtime.Object{&corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: testSecretName, Namespace: testNamespace},
|
||||
Type: "some-other-type",
|
||||
Data: testValidSecretData,
|
||||
}},
|
||||
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
|
||||
wantResultingCache: []*upstreamldap.ProviderConfig{},
|
||||
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234},
|
||||
Status: v1alpha1.LDAPIdentityProviderStatus{
|
||||
Phase: "Error",
|
||||
Conditions: []v1alpha1.Condition{
|
||||
{
|
||||
Type: "BindSecretValid",
|
||||
Status: "False",
|
||||
LastTransitionTime: now,
|
||||
Reason: "SecretWrongType",
|
||||
Message: fmt.Sprintf(`referenced Secret "%s" has wrong type "some-other-type" (should be "kubernetes.io/basic-auth")`, testSecretName),
|
||||
ObservedGeneration: 1234,
|
||||
},
|
||||
tlsConfigurationValidLoadedTrueCondition(1234),
|
||||
},
|
||||
},
|
||||
}},
|
||||
},
|
||||
{
|
||||
name: "secret is missing key",
|
||||
inputUpstreams: []runtime.Object{validUpstream},
|
||||
inputSecrets: []runtime.Object{&corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: testSecretName, Namespace: testNamespace},
|
||||
Type: corev1.SecretTypeBasicAuth,
|
||||
}},
|
||||
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
|
||||
wantResultingCache: []*upstreamldap.ProviderConfig{},
|
||||
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234},
|
||||
Status: v1alpha1.LDAPIdentityProviderStatus{
|
||||
Phase: "Error",
|
||||
Conditions: []v1alpha1.Condition{
|
||||
{
|
||||
Type: "BindSecretValid",
|
||||
Status: "False",
|
||||
LastTransitionTime: now,
|
||||
Reason: "SecretMissingKeys",
|
||||
Message: fmt.Sprintf(`referenced Secret "%s" is missing required keys ["username" "password"]`, testSecretName),
|
||||
ObservedGeneration: 1234,
|
||||
},
|
||||
tlsConfigurationValidLoadedTrueCondition(1234),
|
||||
},
|
||||
},
|
||||
}},
|
||||
},
|
||||
{
|
||||
name: "CertificateAuthorityData is not base64 encoded",
|
||||
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
|
||||
upstream.Spec.TLS.CertificateAuthorityData = "this-is-not-base64-encoded"
|
||||
})},
|
||||
inputSecrets: []runtime.Object{validBindUserSecret("")},
|
||||
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
|
||||
wantResultingCache: []*upstreamldap.ProviderConfig{},
|
||||
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234},
|
||||
Status: v1alpha1.LDAPIdentityProviderStatus{
|
||||
Phase: "Error",
|
||||
Conditions: []v1alpha1.Condition{
|
||||
bindSecretValidTrueCondition(1234),
|
||||
{
|
||||
Type: "TLSConfigurationValid",
|
||||
Status: "False",
|
||||
LastTransitionTime: now,
|
||||
Reason: "InvalidTLSConfig",
|
||||
Message: "certificateAuthorityData is invalid: illegal base64 data at input byte 4",
|
||||
ObservedGeneration: 1234,
|
||||
},
|
||||
},
|
||||
},
|
||||
}},
|
||||
},
|
||||
{
|
||||
name: "CertificateAuthorityData is not valid pem data",
|
||||
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
|
||||
upstream.Spec.TLS.CertificateAuthorityData = base64.StdEncoding.EncodeToString([]byte("this is not pem data"))
|
||||
})},
|
||||
inputSecrets: []runtime.Object{validBindUserSecret("")},
|
||||
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
|
||||
wantResultingCache: []*upstreamldap.ProviderConfig{},
|
||||
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234},
|
||||
Status: v1alpha1.LDAPIdentityProviderStatus{
|
||||
Phase: "Error",
|
||||
Conditions: []v1alpha1.Condition{
|
||||
bindSecretValidTrueCondition(1234),
|
||||
{
|
||||
Type: "TLSConfigurationValid",
|
||||
Status: "False",
|
||||
LastTransitionTime: now,
|
||||
Reason: "InvalidTLSConfig",
|
||||
Message: "certificateAuthorityData is invalid: no certificates found",
|
||||
ObservedGeneration: 1234,
|
||||
},
|
||||
},
|
||||
},
|
||||
}},
|
||||
},
|
||||
{
|
||||
name: "nil TLS configuration is valid",
|
||||
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
|
||||
upstream.Spec.TLS = nil
|
||||
})},
|
||||
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
|
||||
setupMocks: func(conn *mockldapconn.MockConn) {
|
||||
// Should perform a test dial and bind.
|
||||
conn.EXPECT().Bind(testBindUsername, testBindPassword).Times(1)
|
||||
conn.EXPECT().Close().Times(1)
|
||||
},
|
||||
wantResultingCache: []*upstreamldap.ProviderConfig{
|
||||
{
|
||||
Name: testName,
|
||||
Host: testHost,
|
||||
CABundle: nil,
|
||||
BindUsername: testBindUsername,
|
||||
BindPassword: testBindPassword,
|
||||
UserSearch: upstreamldap.UserSearchConfig{
|
||||
Base: testUserSearchBase,
|
||||
Filter: testUserSearchFilter,
|
||||
UsernameAttribute: testUsernameAttrName,
|
||||
UIDAttribute: testUIDAttrName,
|
||||
},
|
||||
},
|
||||
},
|
||||
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234},
|
||||
Status: v1alpha1.LDAPIdentityProviderStatus{
|
||||
Phase: "Ready",
|
||||
Conditions: []v1alpha1.Condition{
|
||||
bindSecretValidTrueCondition(1234),
|
||||
ldapConnectionValidTrueCondition(1234, "4242"),
|
||||
{
|
||||
Type: "TLSConfigurationValid",
|
||||
Status: "True",
|
||||
LastTransitionTime: now,
|
||||
Reason: "Success",
|
||||
Message: "no TLS configuration provided",
|
||||
ObservedGeneration: 1234,
|
||||
},
|
||||
},
|
||||
},
|
||||
}},
|
||||
wantValidatedSecretVersions: map[string]string{testName: "4242"},
|
||||
},
|
||||
{
|
||||
name: "non-nil TLS configuration with empty CertificateAuthorityData is valid",
|
||||
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
|
||||
upstream.Spec.TLS.CertificateAuthorityData = ""
|
||||
})},
|
||||
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
|
||||
setupMocks: func(conn *mockldapconn.MockConn) {
|
||||
// Should perform a test dial and bind.
|
||||
conn.EXPECT().Bind(testBindUsername, testBindPassword).Times(1)
|
||||
conn.EXPECT().Close().Times(1)
|
||||
},
|
||||
wantResultingCache: []*upstreamldap.ProviderConfig{
|
||||
{
|
||||
Name: testName,
|
||||
Host: testHost,
|
||||
CABundle: nil,
|
||||
BindUsername: testBindUsername,
|
||||
BindPassword: testBindPassword,
|
||||
UserSearch: upstreamldap.UserSearchConfig{
|
||||
Base: testUserSearchBase,
|
||||
Filter: testUserSearchFilter,
|
||||
UsernameAttribute: testUsernameAttrName,
|
||||
UIDAttribute: testUIDAttrName,
|
||||
},
|
||||
},
|
||||
},
|
||||
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234},
|
||||
Status: v1alpha1.LDAPIdentityProviderStatus{
|
||||
Phase: "Ready",
|
||||
Conditions: allConditionsTrue(1234, "4242"),
|
||||
},
|
||||
}},
|
||||
wantValidatedSecretVersions: map[string]string{testName: "4242"},
|
||||
},
|
||||
{
|
||||
name: "one valid upstream and one invalid upstream updates the cache to include only the valid upstream",
|
||||
inputUpstreams: []runtime.Object{validUpstream, editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
|
||||
upstream.Name = "other-upstream"
|
||||
upstream.Generation = 42
|
||||
upstream.Spec.Bind.SecretName = "non-existent-secret"
|
||||
})},
|
||||
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
|
||||
setupMocks: func(conn *mockldapconn.MockConn) {
|
||||
// Should perform a test dial and bind for the one valid upstream configuration.
|
||||
conn.EXPECT().Bind(testBindUsername, testBindPassword).Times(1)
|
||||
conn.EXPECT().Close().Times(1)
|
||||
},
|
||||
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
|
||||
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstream},
|
||||
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: "other-upstream", Generation: 42},
|
||||
Status: v1alpha1.LDAPIdentityProviderStatus{
|
||||
Phase: "Error",
|
||||
Conditions: []v1alpha1.Condition{
|
||||
{
|
||||
Type: "BindSecretValid",
|
||||
Status: "False",
|
||||
LastTransitionTime: now,
|
||||
Reason: "SecretNotFound",
|
||||
Message: fmt.Sprintf(`secret "%s" not found`, "non-existent-secret"),
|
||||
ObservedGeneration: 42,
|
||||
},
|
||||
tlsConfigurationValidLoadedTrueCondition(42),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234},
|
||||
Status: v1alpha1.LDAPIdentityProviderStatus{
|
||||
Phase: "Ready",
|
||||
Conditions: allConditionsTrue(1234, "4242"),
|
||||
},
|
||||
},
|
||||
},
|
||||
wantValidatedSecretVersions: map[string]string{testName: "4242"},
|
||||
},
|
||||
{
|
||||
name: "when testing the connection to the LDAP server fails then the upstream is still added to the cache anyway (treated like a warning)",
|
||||
inputUpstreams: []runtime.Object{validUpstream},
|
||||
inputSecrets: []runtime.Object{validBindUserSecret("")},
|
||||
setupMocks: func(conn *mockldapconn.MockConn) {
|
||||
// Should perform a test dial and bind.
|
||||
conn.EXPECT().Bind(testBindUsername, testBindPassword).Times(1).Return(errors.New("some bind error"))
|
||||
conn.EXPECT().Close().Times(1)
|
||||
},
|
||||
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
|
||||
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstream},
|
||||
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234},
|
||||
Status: v1alpha1.LDAPIdentityProviderStatus{
|
||||
Phase: "Error",
|
||||
Conditions: []v1alpha1.Condition{
|
||||
bindSecretValidTrueCondition(1234),
|
||||
{
|
||||
Type: "LDAPConnectionValid",
|
||||
Status: "False",
|
||||
LastTransitionTime: now,
|
||||
Reason: "LDAPConnectionError",
|
||||
Message: fmt.Sprintf(
|
||||
`could not successfully connect to "%s" and bind as user "%s": error binding as "%s": some bind error`,
|
||||
testHost, testBindUsername, testBindUsername),
|
||||
ObservedGeneration: 1234,
|
||||
},
|
||||
tlsConfigurationValidLoadedTrueCondition(1234),
|
||||
},
|
||||
},
|
||||
}},
|
||||
},
|
||||
{
|
||||
name: "when the LDAP server connection was already validated for the current resource generation and secret version, then do not validate it again",
|
||||
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
|
||||
upstream.Generation = 1234
|
||||
upstream.Status.Conditions = []v1alpha1.Condition{
|
||||
ldapConnectionValidTrueCondition(1234, "4242"),
|
||||
}
|
||||
})},
|
||||
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
|
||||
initialValidatedSecretVersions: map[string]string{testName: "4242"},
|
||||
setupMocks: func(conn *mockldapconn.MockConn) {
|
||||
// Should not perform a test dial and bind. No mocking here means the test will fail if Bind() or Close() are called.
|
||||
},
|
||||
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstream},
|
||||
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234},
|
||||
Status: v1alpha1.LDAPIdentityProviderStatus{
|
||||
Phase: "Ready",
|
||||
Conditions: allConditionsTrue(1234, "4242"),
|
||||
},
|
||||
}},
|
||||
wantValidatedSecretVersions: map[string]string{testName: "4242"},
|
||||
},
|
||||
{
|
||||
name: "when the LDAP server connection was validated for an older resource generation, then try to validate it again",
|
||||
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
|
||||
upstream.Generation = 1234 // current generation
|
||||
upstream.Status.Conditions = []v1alpha1.Condition{
|
||||
ldapConnectionValidTrueCondition(1233, "4242"), // older spec generation!
|
||||
}
|
||||
})},
|
||||
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
|
||||
initialValidatedSecretVersions: map[string]string{testName: "4242"},
|
||||
setupMocks: func(conn *mockldapconn.MockConn) {
|
||||
// Should perform a test dial and bind.
|
||||
conn.EXPECT().Bind(testBindUsername, testBindPassword).Times(1)
|
||||
conn.EXPECT().Close().Times(1)
|
||||
},
|
||||
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstream},
|
||||
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234},
|
||||
Status: v1alpha1.LDAPIdentityProviderStatus{
|
||||
Phase: "Ready",
|
||||
Conditions: allConditionsTrue(1234, "4242"),
|
||||
},
|
||||
}},
|
||||
wantValidatedSecretVersions: map[string]string{testName: "4242"},
|
||||
},
|
||||
{
|
||||
name: "when the LDAP server connection validation previously failed for this resource generation, then try to validate it again",
|
||||
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
|
||||
upstream.Generation = 1234
|
||||
upstream.Status.Conditions = []v1alpha1.Condition{
|
||||
{
|
||||
Type: "LDAPConnectionValid",
|
||||
Status: "False", // failure!
|
||||
LastTransitionTime: now,
|
||||
Reason: "LDAPConnectionError",
|
||||
Message: "some-error-message",
|
||||
ObservedGeneration: 1234, // same (current) generation!
|
||||
},
|
||||
}
|
||||
})},
|
||||
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
|
||||
initialValidatedSecretVersions: map[string]string{testName: "1"},
|
||||
setupMocks: func(conn *mockldapconn.MockConn) {
|
||||
// Should perform a test dial and bind.
|
||||
conn.EXPECT().Bind(testBindUsername, testBindPassword).Times(1)
|
||||
conn.EXPECT().Close().Times(1)
|
||||
},
|
||||
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstream},
|
||||
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234},
|
||||
Status: v1alpha1.LDAPIdentityProviderStatus{
|
||||
Phase: "Ready",
|
||||
Conditions: allConditionsTrue(1234, "4242"),
|
||||
},
|
||||
}},
|
||||
wantValidatedSecretVersions: map[string]string{testName: "4242"},
|
||||
},
|
||||
{
|
||||
name: "when the LDAP server connection was already validated for this resource generation but the bind secret has changed, then try to validate it again",
|
||||
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
|
||||
upstream.Generation = 1234
|
||||
upstream.Status.Conditions = []v1alpha1.Condition{
|
||||
ldapConnectionValidTrueCondition(1234, "4241"), // same spec generation, old secret version
|
||||
}
|
||||
})},
|
||||
inputSecrets: []runtime.Object{validBindUserSecret("4242")}, // newer secret version!
|
||||
initialValidatedSecretVersions: map[string]string{testName: "4241"}, // old version was validated
|
||||
setupMocks: func(conn *mockldapconn.MockConn) {
|
||||
// Should perform a test dial and bind.
|
||||
conn.EXPECT().Bind(testBindUsername, testBindPassword).Times(1)
|
||||
conn.EXPECT().Close().Times(1)
|
||||
},
|
||||
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstream},
|
||||
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234},
|
||||
Status: v1alpha1.LDAPIdentityProviderStatus{
|
||||
Phase: "Ready",
|
||||
Conditions: allConditionsTrue(1234, "4242"),
|
||||
},
|
||||
}},
|
||||
wantValidatedSecretVersions: map[string]string{testName: "4242"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
fakePinnipedClient := pinnipedfake.NewSimpleClientset(tt.inputUpstreams...)
|
||||
pinnipedInformers := pinnipedinformers.NewSharedInformerFactory(fakePinnipedClient, 0)
|
||||
fakeKubeClient := fake.NewSimpleClientset(tt.inputSecrets...)
|
||||
kubeInformers := informers.NewSharedInformerFactory(fakeKubeClient, 0)
|
||||
cache := provider.NewDynamicUpstreamIDPProvider()
|
||||
cache.SetLDAPIdentityProviders([]provider.UpstreamLDAPIdentityProviderI{
|
||||
upstreamldap.New(upstreamldap.ProviderConfig{Name: "initial-entry"}),
|
||||
})
|
||||
|
||||
ctrl := gomock.NewController(t)
|
||||
t.Cleanup(ctrl.Finish)
|
||||
|
||||
conn := mockldapconn.NewMockConn(ctrl)
|
||||
if tt.setupMocks != nil {
|
||||
tt.setupMocks(conn)
|
||||
}
|
||||
|
||||
dialer := &comparableDialer{upstreamldap.LDAPDialerFunc(func(ctx context.Context, _ string) (upstreamldap.Conn, error) {
|
||||
if tt.dialError != nil {
|
||||
return nil, tt.dialError
|
||||
}
|
||||
return conn, nil
|
||||
})}
|
||||
|
||||
validatedSecretVersionCache := newSecretVersionCache()
|
||||
if tt.initialValidatedSecretVersions != nil {
|
||||
validatedSecretVersionCache.ResourceVersionsByName = tt.initialValidatedSecretVersions
|
||||
}
|
||||
|
||||
controller := newInternal(
|
||||
cache,
|
||||
validatedSecretVersionCache,
|
||||
dialer,
|
||||
fakePinnipedClient,
|
||||
pinnipedInformers.IDP().V1alpha1().LDAPIdentityProviders(),
|
||||
kubeInformers.Core().V1().Secrets(),
|
||||
controllerlib.WithInformer,
|
||||
)
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
pinnipedInformers.Start(ctx.Done())
|
||||
kubeInformers.Start(ctx.Done())
|
||||
controllerlib.TestRunSynchronously(t, controller)
|
||||
|
||||
syncCtx := controllerlib.Context{Context: ctx, Key: controllerlib.Key{}}
|
||||
|
||||
if err := controllerlib.TestSync(t, controller, syncCtx); tt.wantErr != "" {
|
||||
require.EqualError(t, err, tt.wantErr)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
actualIDPList := cache.GetLDAPIdentityProviders()
|
||||
require.Equal(t, len(tt.wantResultingCache), len(actualIDPList))
|
||||
for i := range actualIDPList {
|
||||
actualIDP := actualIDPList[i].(*upstreamldap.Provider)
|
||||
copyOfExpectedValue := *tt.wantResultingCache[i] // copy before edit to avoid race because these tests are run in parallel
|
||||
// The dialer that was passed in to the controller's constructor should always have been
|
||||
// passed through to the provider.
|
||||
copyOfExpectedValue.Dialer = dialer
|
||||
require.Equal(t, copyOfExpectedValue, actualIDP.GetConfig())
|
||||
}
|
||||
|
||||
actualUpstreams, err := fakePinnipedClient.IDPV1alpha1().LDAPIdentityProviders(testNamespace).List(ctx, metav1.ListOptions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
// Assert on the expected Status of the upstreams. Preprocess the upstreams a bit so that they're easier to assert against.
|
||||
normalizedActualUpstreams := normalizeLDAPUpstreams(actualUpstreams.Items, now)
|
||||
require.Equal(t, len(tt.wantResultingUpstreams), len(normalizedActualUpstreams))
|
||||
for i := range tt.wantResultingUpstreams {
|
||||
// Require each separately to get a nice diff when the test fails.
|
||||
require.Equal(t, tt.wantResultingUpstreams[i], normalizedActualUpstreams[i])
|
||||
}
|
||||
|
||||
// Check that the controller remembered which version of the secret it most recently validated successfully with.
|
||||
if tt.wantValidatedSecretVersions == nil {
|
||||
tt.wantValidatedSecretVersions = map[string]string{}
|
||||
}
|
||||
require.Equal(t, tt.wantValidatedSecretVersions, validatedSecretVersionCache.ResourceVersionsByName)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func normalizeLDAPUpstreams(upstreams []v1alpha1.LDAPIdentityProvider, now metav1.Time) []v1alpha1.LDAPIdentityProvider {
|
||||
result := make([]v1alpha1.LDAPIdentityProvider, 0, len(upstreams))
|
||||
for _, u := range upstreams {
|
||||
normalized := u.DeepCopy()
|
||||
|
||||
// We're only interested in comparing the status, so zero out the spec.
|
||||
normalized.Spec = v1alpha1.LDAPIdentityProviderSpec{}
|
||||
|
||||
// Round down the LastTransitionTime values to `now` if they were just updated. This makes
|
||||
// it much easier to encode assertions about the expected timestamps.
|
||||
for i := range normalized.Status.Conditions {
|
||||
if time.Since(normalized.Status.Conditions[i].LastTransitionTime.Time) < 5*time.Second {
|
||||
normalized.Status.Conditions[i].LastTransitionTime = now
|
||||
}
|
||||
}
|
||||
result = append(result, *normalized)
|
||||
}
|
||||
|
||||
sort.SliceStable(result, func(i, j int) bool {
|
||||
return result[i].Name < result[j].Name
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package upstreamwatcher implements a controller that watches OIDCIdentityProvider objects.
|
||||
package upstreamwatcher
|
||||
// Package oidcupstreamwatcher implements a controller which watches OIDCIdentityProviders.
|
||||
package oidcupstreamwatcher
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -31,6 +31,8 @@ import (
|
||||
idpinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions/idp/v1alpha1"
|
||||
"go.pinniped.dev/internal/constable"
|
||||
pinnipedcontroller "go.pinniped.dev/internal/controller"
|
||||
"go.pinniped.dev/internal/controller/conditionsutil"
|
||||
"go.pinniped.dev/internal/controller/supervisorconfig/upstreamwatchers"
|
||||
"go.pinniped.dev/internal/controllerlib"
|
||||
"go.pinniped.dev/internal/oidc/provider"
|
||||
"go.pinniped.dev/internal/upstreamoidc"
|
||||
@ -38,7 +40,7 @@ import (
|
||||
|
||||
const (
|
||||
// Setup for the name of our controller in logs.
|
||||
controllerName = "upstream-observer"
|
||||
oidcControllerName = "oidc-upstream-observer"
|
||||
|
||||
// Constants related to the client credentials Secret.
|
||||
oidcClientSecretType corev1.SecretType = "secrets.pinniped.dev/oidc-client"
|
||||
@ -47,27 +49,22 @@ const (
|
||||
clientSecretDataKey = "clientSecret"
|
||||
|
||||
// Constants related to the OIDC provider discovery cache. These do not affect the cache of JWKS.
|
||||
validatorCacheTTL = 15 * time.Minute
|
||||
oidcValidatorCacheTTL = 15 * time.Minute
|
||||
|
||||
// Constants related to conditions.
|
||||
typeClientCredsValid = "ClientCredentialsValid"
|
||||
typeClientCredentialsValid = "ClientCredentialsValid"
|
||||
typeOIDCDiscoverySucceeded = "OIDCDiscoverySucceeded"
|
||||
reasonNotFound = "SecretNotFound"
|
||||
reasonWrongType = "SecretWrongType"
|
||||
reasonMissingKeys = "SecretMissingKeys"
|
||||
reasonSuccess = "Success"
|
||||
reasonUnreachable = "Unreachable"
|
||||
reasonInvalidTLSConfig = "InvalidTLSConfig"
|
||||
reasonInvalidResponse = "InvalidResponse"
|
||||
|
||||
reasonUnreachable = "Unreachable"
|
||||
reasonInvalidResponse = "InvalidResponse"
|
||||
|
||||
// Errors that are generated by our reconcile process.
|
||||
errFailureStatus = constable.Error("OIDCIdentityProvider has a failing condition")
|
||||
errNoCertificates = constable.Error("no certificates found")
|
||||
errOIDCFailureStatus = constable.Error("OIDCIdentityProvider has a failing condition")
|
||||
)
|
||||
|
||||
// IDPCache is a thread safe cache that holds a list of validated upstream OIDC IDP configurations.
|
||||
type IDPCache interface {
|
||||
SetIDPList([]provider.UpstreamOIDCIdentityProviderI)
|
||||
// UpstreamOIDCIdentityProviderICache is a thread safe cache that holds a list of validated upstream OIDC IDP configurations.
|
||||
type UpstreamOIDCIdentityProviderICache interface {
|
||||
SetOIDCIdentityProviders([]provider.UpstreamOIDCIdentityProviderI)
|
||||
}
|
||||
|
||||
// lruValidatorCache caches the *oidc.Provider associated with a particular issuer/TLS configuration.
|
||||
@ -87,7 +84,7 @@ func (c *lruValidatorCache) getProvider(spec *v1alpha1.OIDCIdentityProviderSpec)
|
||||
}
|
||||
|
||||
func (c *lruValidatorCache) putProvider(spec *v1alpha1.OIDCIdentityProviderSpec, provider *oidc.Provider, client *http.Client) {
|
||||
c.cache.Set(c.cacheKey(spec), &lruValidatorCacheEntry{provider: provider, client: client}, validatorCacheTTL)
|
||||
c.cache.Set(c.cacheKey(spec), &lruValidatorCacheEntry{provider: provider, client: client}, oidcValidatorCacheTTL)
|
||||
}
|
||||
|
||||
func (c *lruValidatorCache) cacheKey(spec *v1alpha1.OIDCIdentityProviderSpec) interface{} {
|
||||
@ -99,8 +96,8 @@ func (c *lruValidatorCache) cacheKey(spec *v1alpha1.OIDCIdentityProviderSpec) in
|
||||
return key
|
||||
}
|
||||
|
||||
type controller struct {
|
||||
cache IDPCache
|
||||
type oidcWatcherController struct {
|
||||
cache UpstreamOIDCIdentityProviderICache
|
||||
log logr.Logger
|
||||
client pinnipedclientset.Interface
|
||||
oidcIdentityProviderInformer idpinformers.OIDCIdentityProviderInformer
|
||||
@ -111,25 +108,25 @@ type controller struct {
|
||||
}
|
||||
}
|
||||
|
||||
// New instantiates a new controllerlib.Controller which will populate the provided IDPCache.
|
||||
// New instantiates a new controllerlib.Controller which will populate the provided UpstreamOIDCIdentityProviderICache.
|
||||
func New(
|
||||
idpCache IDPCache,
|
||||
idpCache UpstreamOIDCIdentityProviderICache,
|
||||
client pinnipedclientset.Interface,
|
||||
oidcIdentityProviderInformer idpinformers.OIDCIdentityProviderInformer,
|
||||
secretInformer corev1informers.SecretInformer,
|
||||
log logr.Logger,
|
||||
withInformer pinnipedcontroller.WithInformerOptionFunc,
|
||||
) controllerlib.Controller {
|
||||
c := controller{
|
||||
c := oidcWatcherController{
|
||||
cache: idpCache,
|
||||
log: log.WithName(controllerName),
|
||||
log: log.WithName(oidcControllerName),
|
||||
client: client,
|
||||
oidcIdentityProviderInformer: oidcIdentityProviderInformer,
|
||||
secretInformer: secretInformer,
|
||||
validatorCache: &lruValidatorCache{cache: cache.NewExpiring()},
|
||||
}
|
||||
return controllerlib.New(
|
||||
controllerlib.Config{Name: controllerName, Syncer: &c},
|
||||
controllerlib.Config{Name: oidcControllerName, Syncer: &c},
|
||||
withInformer(
|
||||
oidcIdentityProviderInformer,
|
||||
pinnipedcontroller.MatchAnythingFilter(pinnipedcontroller.SingletonQueue()),
|
||||
@ -144,7 +141,7 @@ func New(
|
||||
}
|
||||
|
||||
// Sync implements controllerlib.Syncer.
|
||||
func (c *controller) Sync(ctx controllerlib.Context) error {
|
||||
func (c *oidcWatcherController) Sync(ctx controllerlib.Context) error {
|
||||
actualUpstreams, err := c.oidcIdentityProviderInformer.Lister().List(labels.Everything())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to list OIDCIdentityProviders: %w", err)
|
||||
@ -160,7 +157,7 @@ func (c *controller) Sync(ctx controllerlib.Context) error {
|
||||
validatedUpstreams = append(validatedUpstreams, provider.UpstreamOIDCIdentityProviderI(valid))
|
||||
}
|
||||
}
|
||||
c.cache.SetIDPList(validatedUpstreams)
|
||||
c.cache.SetOIDCIdentityProviders(validatedUpstreams)
|
||||
if requeue {
|
||||
return controllerlib.ErrSyntheticRequeue
|
||||
}
|
||||
@ -169,7 +166,7 @@ func (c *controller) Sync(ctx controllerlib.Context) error {
|
||||
|
||||
// validateUpstream validates the provided v1alpha1.OIDCIdentityProvider and returns the validated configuration as a
|
||||
// provider.UpstreamOIDCIdentityProvider. As a side effect, it also updates the status of the v1alpha1.OIDCIdentityProvider.
|
||||
func (c *controller) validateUpstream(ctx controllerlib.Context, upstream *v1alpha1.OIDCIdentityProvider) *upstreamoidc.ProviderConfig {
|
||||
func (c *oidcWatcherController) validateUpstream(ctx controllerlib.Context, upstream *v1alpha1.OIDCIdentityProvider) *upstreamoidc.ProviderConfig {
|
||||
result := upstreamoidc.ProviderConfig{
|
||||
Name: upstream.Name,
|
||||
Config: &oauth2.Config{
|
||||
@ -193,7 +190,7 @@ func (c *controller) validateUpstream(ctx controllerlib.Context, upstream *v1alp
|
||||
"type", condition.Type,
|
||||
"reason", condition.Reason,
|
||||
"message", condition.Message,
|
||||
).Error(errFailureStatus, "found failing condition")
|
||||
).Error(errOIDCFailureStatus, "found failing condition")
|
||||
}
|
||||
}
|
||||
if valid {
|
||||
@ -203,16 +200,16 @@ func (c *controller) validateUpstream(ctx controllerlib.Context, upstream *v1alp
|
||||
}
|
||||
|
||||
// validateSecret validates the .spec.client.secretName field and returns the appropriate ClientCredentialsValid condition.
|
||||
func (c *controller) validateSecret(upstream *v1alpha1.OIDCIdentityProvider, result *upstreamoidc.ProviderConfig) *v1alpha1.Condition {
|
||||
func (c *oidcWatcherController) validateSecret(upstream *v1alpha1.OIDCIdentityProvider, result *upstreamoidc.ProviderConfig) *v1alpha1.Condition {
|
||||
secretName := upstream.Spec.Client.SecretName
|
||||
|
||||
// Fetch the Secret from informer cache.
|
||||
secret, err := c.secretInformer.Lister().Secrets(upstream.Namespace).Get(secretName)
|
||||
if err != nil {
|
||||
return &v1alpha1.Condition{
|
||||
Type: typeClientCredsValid,
|
||||
Type: typeClientCredentialsValid,
|
||||
Status: v1alpha1.ConditionFalse,
|
||||
Reason: reasonNotFound,
|
||||
Reason: upstreamwatchers.ReasonNotFound,
|
||||
Message: err.Error(),
|
||||
}
|
||||
}
|
||||
@ -220,9 +217,9 @@ func (c *controller) validateSecret(upstream *v1alpha1.OIDCIdentityProvider, res
|
||||
// Validate the secret .type field.
|
||||
if secret.Type != oidcClientSecretType {
|
||||
return &v1alpha1.Condition{
|
||||
Type: typeClientCredsValid,
|
||||
Type: typeClientCredentialsValid,
|
||||
Status: v1alpha1.ConditionFalse,
|
||||
Reason: reasonWrongType,
|
||||
Reason: upstreamwatchers.ReasonWrongType,
|
||||
Message: fmt.Sprintf("referenced Secret %q has wrong type %q (should be %q)", secretName, secret.Type, oidcClientSecretType),
|
||||
}
|
||||
}
|
||||
@ -232,9 +229,9 @@ func (c *controller) validateSecret(upstream *v1alpha1.OIDCIdentityProvider, res
|
||||
clientSecret := secret.Data[clientSecretDataKey]
|
||||
if len(clientID) == 0 || len(clientSecret) == 0 {
|
||||
return &v1alpha1.Condition{
|
||||
Type: typeClientCredsValid,
|
||||
Type: typeClientCredentialsValid,
|
||||
Status: v1alpha1.ConditionFalse,
|
||||
Reason: reasonMissingKeys,
|
||||
Reason: upstreamwatchers.ReasonMissingKeys,
|
||||
Message: fmt.Sprintf("referenced Secret %q is missing required keys %q", secretName, []string{clientIDDataKey, clientSecretDataKey}),
|
||||
}
|
||||
}
|
||||
@ -243,15 +240,15 @@ func (c *controller) validateSecret(upstream *v1alpha1.OIDCIdentityProvider, res
|
||||
result.Config.ClientID = string(clientID)
|
||||
result.Config.ClientSecret = string(clientSecret)
|
||||
return &v1alpha1.Condition{
|
||||
Type: typeClientCredsValid,
|
||||
Type: typeClientCredentialsValid,
|
||||
Status: v1alpha1.ConditionTrue,
|
||||
Reason: reasonSuccess,
|
||||
Reason: upstreamwatchers.ReasonSuccess,
|
||||
Message: "loaded client credentials",
|
||||
}
|
||||
}
|
||||
|
||||
// validateIssuer validates the .spec.issuer field, performs OIDC discovery, and returns the appropriate OIDCDiscoverySucceeded condition.
|
||||
func (c *controller) validateIssuer(ctx context.Context, upstream *v1alpha1.OIDCIdentityProvider, result *upstreamoidc.ProviderConfig) *v1alpha1.Condition {
|
||||
func (c *oidcWatcherController) validateIssuer(ctx context.Context, upstream *v1alpha1.OIDCIdentityProvider, result *upstreamoidc.ProviderConfig) *v1alpha1.Condition {
|
||||
// Get the provider and HTTP Client from cache if possible.
|
||||
discoveredProvider, httpClient := c.validatorCache.getProvider(&upstream.Spec)
|
||||
|
||||
@ -262,7 +259,7 @@ func (c *controller) validateIssuer(ctx context.Context, upstream *v1alpha1.OIDC
|
||||
return &v1alpha1.Condition{
|
||||
Type: typeOIDCDiscoverySucceeded,
|
||||
Status: v1alpha1.ConditionFalse,
|
||||
Reason: reasonInvalidTLSConfig,
|
||||
Reason: upstreamwatchers.ReasonInvalidTLSConfig,
|
||||
Message: err.Error(),
|
||||
}
|
||||
}
|
||||
@ -314,11 +311,35 @@ func (c *controller) validateIssuer(ctx context.Context, upstream *v1alpha1.OIDC
|
||||
return &v1alpha1.Condition{
|
||||
Type: typeOIDCDiscoverySucceeded,
|
||||
Status: v1alpha1.ConditionTrue,
|
||||
Reason: reasonSuccess,
|
||||
Reason: upstreamwatchers.ReasonSuccess,
|
||||
Message: "discovered issuer configuration",
|
||||
}
|
||||
}
|
||||
|
||||
func (c *oidcWatcherController) updateStatus(ctx context.Context, upstream *v1alpha1.OIDCIdentityProvider, conditions []*v1alpha1.Condition) {
|
||||
log := c.log.WithValues("namespace", upstream.Namespace, "name", upstream.Name)
|
||||
updated := upstream.DeepCopy()
|
||||
|
||||
hadErrorCondition := conditionsutil.Merge(conditions, upstream.Generation, &updated.Status.Conditions, log)
|
||||
|
||||
updated.Status.Phase = v1alpha1.PhaseReady
|
||||
if hadErrorCondition {
|
||||
updated.Status.Phase = v1alpha1.PhaseError
|
||||
}
|
||||
|
||||
if equality.Semantic.DeepEqual(upstream, updated) {
|
||||
return
|
||||
}
|
||||
|
||||
_, err := c.client.
|
||||
IDPV1alpha1().
|
||||
OIDCIdentityProviders(upstream.Namespace).
|
||||
UpdateStatus(ctx, updated, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
log.Error(err, "failed to update status")
|
||||
}
|
||||
}
|
||||
|
||||
func getTLSConfig(upstream *v1alpha1.OIDCIdentityProvider) (*tls.Config, error) {
|
||||
result := tls.Config{
|
||||
MinVersion: tls.VersionTLS12,
|
||||
@ -335,81 +356,12 @@ func getTLSConfig(upstream *v1alpha1.OIDCIdentityProvider) (*tls.Config, error)
|
||||
|
||||
result.RootCAs = x509.NewCertPool()
|
||||
if !result.RootCAs.AppendCertsFromPEM(bundle) {
|
||||
return nil, fmt.Errorf("spec.certificateAuthorityData is invalid: %w", errNoCertificates)
|
||||
return nil, fmt.Errorf("spec.certificateAuthorityData is invalid: %w", upstreamwatchers.ErrNoCertificates)
|
||||
}
|
||||
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *controller) updateStatus(ctx context.Context, upstream *v1alpha1.OIDCIdentityProvider, conditions []*v1alpha1.Condition) {
|
||||
log := c.log.WithValues("namespace", upstream.Namespace, "name", upstream.Name)
|
||||
updated := upstream.DeepCopy()
|
||||
|
||||
updated.Status.Phase = v1alpha1.PhaseReady
|
||||
|
||||
for i := range conditions {
|
||||
cond := conditions[i].DeepCopy()
|
||||
cond.LastTransitionTime = metav1.Now()
|
||||
cond.ObservedGeneration = upstream.Generation
|
||||
if mergeCondition(&updated.Status.Conditions, cond) {
|
||||
log.Info("updated condition", "type", cond.Type, "status", cond.Status, "reason", cond.Reason, "message", cond.Message)
|
||||
}
|
||||
if cond.Status == v1alpha1.ConditionFalse {
|
||||
updated.Status.Phase = v1alpha1.PhaseError
|
||||
}
|
||||
}
|
||||
|
||||
sort.SliceStable(updated.Status.Conditions, func(i, j int) bool {
|
||||
return updated.Status.Conditions[i].Type < updated.Status.Conditions[j].Type
|
||||
})
|
||||
|
||||
if equality.Semantic.DeepEqual(upstream, updated) {
|
||||
return
|
||||
}
|
||||
|
||||
_, err := c.client.
|
||||
IDPV1alpha1().
|
||||
OIDCIdentityProviders(upstream.Namespace).
|
||||
UpdateStatus(ctx, updated, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
log.Error(err, "failed to update status")
|
||||
}
|
||||
}
|
||||
|
||||
// mergeCondition merges a new v1alpha1.Condition into a slice of existing conditions. It returns true
|
||||
// if the condition has meaningfully changed.
|
||||
func mergeCondition(existing *[]v1alpha1.Condition, new *v1alpha1.Condition) bool {
|
||||
// Find any existing condition with a matching type.
|
||||
var old *v1alpha1.Condition
|
||||
for i := range *existing {
|
||||
if (*existing)[i].Type == new.Type {
|
||||
old = &(*existing)[i]
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// If there is no existing condition of this type, append this one and we're done.
|
||||
if old == nil {
|
||||
*existing = append(*existing, *new)
|
||||
return true
|
||||
}
|
||||
|
||||
// Set the LastTransitionTime depending on whether the status has changed.
|
||||
new = new.DeepCopy()
|
||||
if old.Status == new.Status {
|
||||
new.LastTransitionTime = old.LastTransitionTime
|
||||
}
|
||||
|
||||
// If anything has actually changed, update the entry and return true.
|
||||
if !equality.Semantic.DeepEqual(old, new) {
|
||||
*old = *new
|
||||
return true
|
||||
}
|
||||
|
||||
// Otherwise the entry is already up to date.
|
||||
return false
|
||||
}
|
||||
|
||||
func computeScopes(additionalScopes []string) []string {
|
||||
// First compute the unique set of scopes, including "openid" (de-duplicate).
|
||||
set := make(map[string]bool, len(additionalScopes)+1)
|
@ -1,7 +1,7 @@
|
||||
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package upstreamwatcher
|
||||
package oidcupstreamwatcher
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -24,14 +24,14 @@ import (
|
||||
pinnipedfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
|
||||
pinnipedinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions"
|
||||
"go.pinniped.dev/internal/controllerlib"
|
||||
"go.pinniped.dev/internal/oidc/oidctestutil"
|
||||
"go.pinniped.dev/internal/oidc/provider"
|
||||
"go.pinniped.dev/internal/testutil"
|
||||
"go.pinniped.dev/internal/testutil/oidctestutil"
|
||||
"go.pinniped.dev/internal/testutil/testlogger"
|
||||
"go.pinniped.dev/internal/upstreamoidc"
|
||||
)
|
||||
|
||||
func TestControllerFilterSecret(t *testing.T) {
|
||||
func TestOIDCUpstreamWatcherControllerFilterSecret(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
@ -76,7 +76,7 @@ func TestControllerFilterSecret(t *testing.T) {
|
||||
kubeInformers := informers.NewSharedInformerFactory(fakeKubeClient, 0)
|
||||
testLog := testlogger.New(t)
|
||||
cache := provider.NewDynamicUpstreamIDPProvider()
|
||||
cache.SetIDPList([]provider.UpstreamOIDCIdentityProviderI{
|
||||
cache.SetOIDCIdentityProviders([]provider.UpstreamOIDCIdentityProviderI{
|
||||
&upstreamoidc.ProviderConfig{Name: "initial-entry"},
|
||||
})
|
||||
secretInformer := kubeInformers.Core().V1().Secrets()
|
||||
@ -101,7 +101,7 @@ func TestControllerFilterSecret(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestController(t *testing.T) {
|
||||
func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
|
||||
t.Parallel()
|
||||
now := metav1.NewTime(time.Now().UTC())
|
||||
earlier := metav1.NewTime(now.Add(-1 * time.Hour).UTC())
|
||||
@ -150,9 +150,9 @@ func TestController(t *testing.T) {
|
||||
inputSecrets: []runtime.Object{},
|
||||
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
|
||||
wantLogs: []string{
|
||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="secret \"test-client-secret\" not found" "reason"="SecretNotFound" "status"="False" "type"="ClientCredentialsValid"`,
|
||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="discovered issuer configuration" "reason"="Success" "status"="True" "type"="OIDCDiscoverySucceeded"`,
|
||||
`upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="secret \"test-client-secret\" not found" "name"="test-name" "namespace"="test-namespace" "reason"="SecretNotFound" "type"="ClientCredentialsValid"`,
|
||||
`oidc-upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="secret \"test-client-secret\" not found" "reason"="SecretNotFound" "status"="False" "type"="ClientCredentialsValid"`,
|
||||
`oidc-upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="discovered issuer configuration" "reason"="Success" "status"="True" "type"="OIDCDiscoverySucceeded"`,
|
||||
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="secret \"test-client-secret\" not found" "name"="test-name" "namespace"="test-namespace" "reason"="SecretNotFound" "type"="ClientCredentialsValid"`,
|
||||
},
|
||||
wantResultingCache: []provider.UpstreamOIDCIdentityProviderI{},
|
||||
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
|
||||
@ -196,9 +196,9 @@ func TestController(t *testing.T) {
|
||||
}},
|
||||
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
|
||||
wantLogs: []string{
|
||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="referenced Secret \"test-client-secret\" has wrong type \"some-other-type\" (should be \"secrets.pinniped.dev/oidc-client\")" "reason"="SecretWrongType" "status"="False" "type"="ClientCredentialsValid"`,
|
||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="discovered issuer configuration" "reason"="Success" "status"="True" "type"="OIDCDiscoverySucceeded"`,
|
||||
`upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="referenced Secret \"test-client-secret\" has wrong type \"some-other-type\" (should be \"secrets.pinniped.dev/oidc-client\")" "name"="test-name" "namespace"="test-namespace" "reason"="SecretWrongType" "type"="ClientCredentialsValid"`,
|
||||
`oidc-upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="referenced Secret \"test-client-secret\" has wrong type \"some-other-type\" (should be \"secrets.pinniped.dev/oidc-client\")" "reason"="SecretWrongType" "status"="False" "type"="ClientCredentialsValid"`,
|
||||
`oidc-upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="discovered issuer configuration" "reason"="Success" "status"="True" "type"="OIDCDiscoverySucceeded"`,
|
||||
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="referenced Secret \"test-client-secret\" has wrong type \"some-other-type\" (should be \"secrets.pinniped.dev/oidc-client\")" "name"="test-name" "namespace"="test-namespace" "reason"="SecretWrongType" "type"="ClientCredentialsValid"`,
|
||||
},
|
||||
wantResultingCache: []provider.UpstreamOIDCIdentityProviderI{},
|
||||
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
|
||||
@ -241,9 +241,9 @@ func TestController(t *testing.T) {
|
||||
}},
|
||||
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
|
||||
wantLogs: []string{
|
||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="referenced Secret \"test-client-secret\" is missing required keys [\"clientID\" \"clientSecret\"]" "reason"="SecretMissingKeys" "status"="False" "type"="ClientCredentialsValid"`,
|
||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="discovered issuer configuration" "reason"="Success" "status"="True" "type"="OIDCDiscoverySucceeded"`,
|
||||
`upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="referenced Secret \"test-client-secret\" is missing required keys [\"clientID\" \"clientSecret\"]" "name"="test-name" "namespace"="test-namespace" "reason"="SecretMissingKeys" "type"="ClientCredentialsValid"`,
|
||||
`oidc-upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="referenced Secret \"test-client-secret\" is missing required keys [\"clientID\" \"clientSecret\"]" "reason"="SecretMissingKeys" "status"="False" "type"="ClientCredentialsValid"`,
|
||||
`oidc-upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="discovered issuer configuration" "reason"="Success" "status"="True" "type"="OIDCDiscoverySucceeded"`,
|
||||
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="referenced Secret \"test-client-secret\" is missing required keys [\"clientID\" \"clientSecret\"]" "name"="test-name" "namespace"="test-namespace" "reason"="SecretMissingKeys" "type"="ClientCredentialsValid"`,
|
||||
},
|
||||
wantResultingCache: []provider.UpstreamOIDCIdentityProviderI{},
|
||||
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
|
||||
@ -289,9 +289,9 @@ func TestController(t *testing.T) {
|
||||
}},
|
||||
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
|
||||
wantLogs: []string{
|
||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="loaded client credentials" "reason"="Success" "status"="True" "type"="ClientCredentialsValid"`,
|
||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="spec.certificateAuthorityData is invalid: illegal base64 data at input byte 7" "reason"="InvalidTLSConfig" "status"="False" "type"="OIDCDiscoverySucceeded"`,
|
||||
`upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="spec.certificateAuthorityData is invalid: illegal base64 data at input byte 7" "name"="test-name" "namespace"="test-namespace" "reason"="InvalidTLSConfig" "type"="OIDCDiscoverySucceeded"`,
|
||||
`oidc-upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="loaded client credentials" "reason"="Success" "status"="True" "type"="ClientCredentialsValid"`,
|
||||
`oidc-upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="spec.certificateAuthorityData is invalid: illegal base64 data at input byte 7" "reason"="InvalidTLSConfig" "status"="False" "type"="OIDCDiscoverySucceeded"`,
|
||||
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="spec.certificateAuthorityData is invalid: illegal base64 data at input byte 7" "name"="test-name" "namespace"="test-namespace" "reason"="InvalidTLSConfig" "type"="OIDCDiscoverySucceeded"`,
|
||||
},
|
||||
wantResultingCache: []provider.UpstreamOIDCIdentityProviderI{},
|
||||
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
|
||||
@ -337,9 +337,9 @@ func TestController(t *testing.T) {
|
||||
}},
|
||||
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
|
||||
wantLogs: []string{
|
||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="loaded client credentials" "reason"="Success" "status"="True" "type"="ClientCredentialsValid"`,
|
||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="spec.certificateAuthorityData is invalid: no certificates found" "reason"="InvalidTLSConfig" "status"="False" "type"="OIDCDiscoverySucceeded"`,
|
||||
`upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="spec.certificateAuthorityData is invalid: no certificates found" "name"="test-name" "namespace"="test-namespace" "reason"="InvalidTLSConfig" "type"="OIDCDiscoverySucceeded"`,
|
||||
`oidc-upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="loaded client credentials" "reason"="Success" "status"="True" "type"="ClientCredentialsValid"`,
|
||||
`oidc-upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="spec.certificateAuthorityData is invalid: no certificates found" "reason"="InvalidTLSConfig" "status"="False" "type"="OIDCDiscoverySucceeded"`,
|
||||
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="spec.certificateAuthorityData is invalid: no certificates found" "name"="test-name" "namespace"="test-namespace" "reason"="InvalidTLSConfig" "type"="OIDCDiscoverySucceeded"`,
|
||||
},
|
||||
wantResultingCache: []provider.UpstreamOIDCIdentityProviderI{},
|
||||
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
|
||||
@ -382,10 +382,10 @@ func TestController(t *testing.T) {
|
||||
}},
|
||||
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
|
||||
wantLogs: []string{
|
||||
`upstream-observer "msg"="failed to perform OIDC discovery" "error"="Get \"invalid-url-that-is-really-really-long/.well-known/openid-configuration\": unsupported protocol scheme \"\"" "issuer"="invalid-url-that-is-really-really-long" "name"="test-name" "namespace"="test-namespace"`,
|
||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="loaded client credentials" "reason"="Success" "status"="True" "type"="ClientCredentialsValid"`,
|
||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="failed to perform OIDC discovery against \"invalid-url-that-is-really-really-long\":\nGet \"invalid-url-that-is-really-really-long/.well-known/openid-configuration\": unsupported protocol [truncated 9 chars]" "reason"="Unreachable" "status"="False" "type"="OIDCDiscoverySucceeded"`,
|
||||
`upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="failed to perform OIDC discovery against \"invalid-url-that-is-really-really-long\":\nGet \"invalid-url-that-is-really-really-long/.well-known/openid-configuration\": unsupported protocol [truncated 9 chars]" "name"="test-name" "namespace"="test-namespace" "reason"="Unreachable" "type"="OIDCDiscoverySucceeded"`,
|
||||
`oidc-upstream-observer "msg"="failed to perform OIDC discovery" "error"="Get \"invalid-url-that-is-really-really-long/.well-known/openid-configuration\": unsupported protocol scheme \"\"" "issuer"="invalid-url-that-is-really-really-long" "name"="test-name" "namespace"="test-namespace"`,
|
||||
`oidc-upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="loaded client credentials" "reason"="Success" "status"="True" "type"="ClientCredentialsValid"`,
|
||||
`oidc-upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="failed to perform OIDC discovery against \"invalid-url-that-is-really-really-long\":\nGet \"invalid-url-that-is-really-really-long/.well-known/openid-configuration\": unsupported protocol [truncated 9 chars]" "reason"="Unreachable" "status"="False" "type"="OIDCDiscoverySucceeded"`,
|
||||
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="failed to perform OIDC discovery against \"invalid-url-that-is-really-really-long\":\nGet \"invalid-url-that-is-really-really-long/.well-known/openid-configuration\": unsupported protocol [truncated 9 chars]" "name"="test-name" "namespace"="test-namespace" "reason"="Unreachable" "type"="OIDCDiscoverySucceeded"`,
|
||||
},
|
||||
wantResultingCache: []provider.UpstreamOIDCIdentityProviderI{},
|
||||
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
|
||||
@ -430,9 +430,9 @@ Get "invalid-url-that-is-really-really-long/.well-known/openid-configuration": u
|
||||
}},
|
||||
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
|
||||
wantLogs: []string{
|
||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="loaded client credentials" "reason"="Success" "status"="True" "type"="ClientCredentialsValid"`,
|
||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="failed to parse authorization endpoint URL: parse \"%\": invalid URL escape \"%\"" "reason"="InvalidResponse" "status"="False" "type"="OIDCDiscoverySucceeded"`,
|
||||
`upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="failed to parse authorization endpoint URL: parse \"%\": invalid URL escape \"%\"" "name"="test-name" "namespace"="test-namespace" "reason"="InvalidResponse" "type"="OIDCDiscoverySucceeded"`,
|
||||
`oidc-upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="loaded client credentials" "reason"="Success" "status"="True" "type"="ClientCredentialsValid"`,
|
||||
`oidc-upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="failed to parse authorization endpoint URL: parse \"%\": invalid URL escape \"%\"" "reason"="InvalidResponse" "status"="False" "type"="OIDCDiscoverySucceeded"`,
|
||||
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="failed to parse authorization endpoint URL: parse \"%\": invalid URL escape \"%\"" "name"="test-name" "namespace"="test-namespace" "reason"="InvalidResponse" "type"="OIDCDiscoverySucceeded"`,
|
||||
},
|
||||
wantResultingCache: []provider.UpstreamOIDCIdentityProviderI{},
|
||||
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
|
||||
@ -476,9 +476,9 @@ Get "invalid-url-that-is-really-really-long/.well-known/openid-configuration": u
|
||||
}},
|
||||
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
|
||||
wantLogs: []string{
|
||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="loaded client credentials" "reason"="Success" "status"="True" "type"="ClientCredentialsValid"`,
|
||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="authorization endpoint URL scheme must be \"https\", not \"http\"" "reason"="InvalidResponse" "status"="False" "type"="OIDCDiscoverySucceeded"`,
|
||||
`upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="authorization endpoint URL scheme must be \"https\", not \"http\"" "name"="test-name" "namespace"="test-namespace" "reason"="InvalidResponse" "type"="OIDCDiscoverySucceeded"`,
|
||||
`oidc-upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="loaded client credentials" "reason"="Success" "status"="True" "type"="ClientCredentialsValid"`,
|
||||
`oidc-upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="authorization endpoint URL scheme must be \"https\", not \"http\"" "reason"="InvalidResponse" "status"="False" "type"="OIDCDiscoverySucceeded"`,
|
||||
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="authorization endpoint URL scheme must be \"https\", not \"http\"" "name"="test-name" "namespace"="test-namespace" "reason"="InvalidResponse" "type"="OIDCDiscoverySucceeded"`,
|
||||
},
|
||||
wantResultingCache: []provider.UpstreamOIDCIdentityProviderI{},
|
||||
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
|
||||
@ -529,8 +529,8 @@ Get "invalid-url-that-is-really-really-long/.well-known/openid-configuration": u
|
||||
Data: testValidSecretData,
|
||||
}},
|
||||
wantLogs: []string{
|
||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="loaded client credentials" "reason"="Success" "status"="True" "type"="ClientCredentialsValid"`,
|
||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="discovered issuer configuration" "reason"="Success" "status"="True" "type"="OIDCDiscoverySucceeded"`,
|
||||
`oidc-upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="loaded client credentials" "reason"="Success" "status"="True" "type"="ClientCredentialsValid"`,
|
||||
`oidc-upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="discovered issuer configuration" "reason"="Success" "status"="True" "type"="OIDCDiscoverySucceeded"`,
|
||||
},
|
||||
wantResultingCache: []provider.UpstreamOIDCIdentityProviderI{
|
||||
&oidctestutil.TestUpstreamOIDCIdentityProvider{
|
||||
@ -578,8 +578,8 @@ Get "invalid-url-that-is-really-really-long/.well-known/openid-configuration": u
|
||||
Data: testValidSecretData,
|
||||
}},
|
||||
wantLogs: []string{
|
||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="loaded client credentials" "reason"="Success" "status"="True" "type"="ClientCredentialsValid"`,
|
||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="discovered issuer configuration" "reason"="Success" "status"="True" "type"="OIDCDiscoverySucceeded"`,
|
||||
`oidc-upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="loaded client credentials" "reason"="Success" "status"="True" "type"="ClientCredentialsValid"`,
|
||||
`oidc-upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="discovered issuer configuration" "reason"="Success" "status"="True" "type"="OIDCDiscoverySucceeded"`,
|
||||
},
|
||||
wantResultingCache: []provider.UpstreamOIDCIdentityProviderI{
|
||||
&oidctestutil.TestUpstreamOIDCIdentityProvider{
|
||||
@ -627,8 +627,8 @@ Get "invalid-url-that-is-really-really-long/.well-known/openid-configuration": u
|
||||
Data: testValidSecretData,
|
||||
}},
|
||||
wantLogs: []string{
|
||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="loaded client credentials" "reason"="Success" "status"="True" "type"="ClientCredentialsValid"`,
|
||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="discovered issuer configuration" "reason"="Success" "status"="True" "type"="OIDCDiscoverySucceeded"`,
|
||||
`oidc-upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="loaded client credentials" "reason"="Success" "status"="True" "type"="ClientCredentialsValid"`,
|
||||
`oidc-upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="discovered issuer configuration" "reason"="Success" "status"="True" "type"="OIDCDiscoverySucceeded"`,
|
||||
},
|
||||
wantResultingCache: []provider.UpstreamOIDCIdentityProviderI{
|
||||
&oidctestutil.TestUpstreamOIDCIdentityProvider{
|
||||
@ -669,10 +669,10 @@ Get "invalid-url-that-is-really-really-long/.well-known/openid-configuration": u
|
||||
}},
|
||||
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
|
||||
wantLogs: []string{
|
||||
`upstream-observer "msg"="failed to perform OIDC discovery" "error"="oidc: issuer did not match the issuer returned by provider, expected \"` + testIssuerURL + `/ends-with-slash\" got \"` + testIssuerURL + `/ends-with-slash/\"" "issuer"="` + testIssuerURL + `/ends-with-slash" "name"="test-name" "namespace"="test-namespace"`,
|
||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="loaded client credentials" "reason"="Success" "status"="True" "type"="ClientCredentialsValid"`,
|
||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="failed to perform OIDC discovery against \"` + testIssuerURL + `/ends-with-slash\":\noidc: issuer did not match the issuer returned by provider, expected \"` + testIssuerURL + `/ends-with-slash\" got \"` + testIssuerURL + `/ends-with-slash/\"" "reason"="Unreachable" "status"="False" "type"="OIDCDiscoverySucceeded"`,
|
||||
`upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="failed to perform OIDC discovery against \"` + testIssuerURL + `/ends-with-slash\":\noidc: issuer did not match the issuer returned by provider, expected \"` + testIssuerURL + `/ends-with-slash\" got \"` + testIssuerURL + `/ends-with-slash/\"" "name"="test-name" "namespace"="test-namespace" "reason"="Unreachable" "type"="OIDCDiscoverySucceeded"`,
|
||||
`oidc-upstream-observer "msg"="failed to perform OIDC discovery" "error"="oidc: issuer did not match the issuer returned by provider, expected \"` + testIssuerURL + `/ends-with-slash\" got \"` + testIssuerURL + `/ends-with-slash/\"" "issuer"="` + testIssuerURL + `/ends-with-slash" "name"="test-name" "namespace"="test-namespace"`,
|
||||
`oidc-upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="loaded client credentials" "reason"="Success" "status"="True" "type"="ClientCredentialsValid"`,
|
||||
`oidc-upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="failed to perform OIDC discovery against \"` + testIssuerURL + `/ends-with-slash\":\noidc: issuer did not match the issuer returned by provider, expected \"` + testIssuerURL + `/ends-with-slash\" got \"` + testIssuerURL + `/ends-with-slash/\"" "reason"="Unreachable" "status"="False" "type"="OIDCDiscoverySucceeded"`,
|
||||
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="failed to perform OIDC discovery against \"` + testIssuerURL + `/ends-with-slash\":\noidc: issuer did not match the issuer returned by provider, expected \"` + testIssuerURL + `/ends-with-slash\" got \"` + testIssuerURL + `/ends-with-slash/\"" "name"="test-name" "namespace"="test-namespace" "reason"="Unreachable" "type"="OIDCDiscoverySucceeded"`,
|
||||
},
|
||||
wantResultingCache: []provider.UpstreamOIDCIdentityProviderI{},
|
||||
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
|
||||
@ -717,10 +717,10 @@ oidc: issuer did not match the issuer returned by provider, expected "` + testIs
|
||||
}},
|
||||
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
|
||||
wantLogs: []string{
|
||||
`upstream-observer "msg"="failed to perform OIDC discovery" "error"="oidc: issuer did not match the issuer returned by provider, expected \"` + testIssuerURL + `/\" got \"` + testIssuerURL + `\"" "issuer"="` + testIssuerURL + `/" "name"="test-name" "namespace"="test-namespace"`,
|
||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="loaded client credentials" "reason"="Success" "status"="True" "type"="ClientCredentialsValid"`,
|
||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="failed to perform OIDC discovery against \"` + testIssuerURL + `/\":\noidc: issuer did not match the issuer returned by provider, expected \"` + testIssuerURL + `/\" got \"` + testIssuerURL + `\"" "reason"="Unreachable" "status"="False" "type"="OIDCDiscoverySucceeded"`,
|
||||
`upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="failed to perform OIDC discovery against \"` + testIssuerURL + `/\":\noidc: issuer did not match the issuer returned by provider, expected \"` + testIssuerURL + `/\" got \"` + testIssuerURL + `\"" "name"="test-name" "namespace"="test-namespace" "reason"="Unreachable" "type"="OIDCDiscoverySucceeded"`,
|
||||
`oidc-upstream-observer "msg"="failed to perform OIDC discovery" "error"="oidc: issuer did not match the issuer returned by provider, expected \"` + testIssuerURL + `/\" got \"` + testIssuerURL + `\"" "issuer"="` + testIssuerURL + `/" "name"="test-name" "namespace"="test-namespace"`,
|
||||
`oidc-upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="loaded client credentials" "reason"="Success" "status"="True" "type"="ClientCredentialsValid"`,
|
||||
`oidc-upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="failed to perform OIDC discovery against \"` + testIssuerURL + `/\":\noidc: issuer did not match the issuer returned by provider, expected \"` + testIssuerURL + `/\" got \"` + testIssuerURL + `\"" "reason"="Unreachable" "status"="False" "type"="OIDCDiscoverySucceeded"`,
|
||||
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="failed to perform OIDC discovery against \"` + testIssuerURL + `/\":\noidc: issuer did not match the issuer returned by provider, expected \"` + testIssuerURL + `/\" got \"` + testIssuerURL + `\"" "name"="test-name" "namespace"="test-namespace" "reason"="Unreachable" "type"="OIDCDiscoverySucceeded"`,
|
||||
},
|
||||
wantResultingCache: []provider.UpstreamOIDCIdentityProviderI{},
|
||||
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
|
||||
@ -758,7 +758,7 @@ oidc: issuer did not match the issuer returned by provider, expected "` + testIs
|
||||
kubeInformers := informers.NewSharedInformerFactory(fakeKubeClient, 0)
|
||||
testLog := testlogger.New(t)
|
||||
cache := provider.NewDynamicUpstreamIDPProvider()
|
||||
cache.SetIDPList([]provider.UpstreamOIDCIdentityProviderI{
|
||||
cache.SetOIDCIdentityProviders([]provider.UpstreamOIDCIdentityProviderI{
|
||||
&upstreamoidc.ProviderConfig{Name: "initial-entry"},
|
||||
})
|
||||
|
||||
@ -787,7 +787,7 @@ oidc: issuer did not match the issuer returned by provider, expected "` + testIs
|
||||
}
|
||||
require.Equal(t, strings.Join(tt.wantLogs, "\n"), strings.Join(testLog.Lines(), "\n"))
|
||||
|
||||
actualIDPList := cache.GetIDPList()
|
||||
actualIDPList := cache.GetOIDCIdentityProviders()
|
||||
require.Equal(t, len(tt.wantResultingCache), len(actualIDPList))
|
||||
for i := range actualIDPList {
|
||||
actualIDP := actualIDPList[i].(*upstreamoidc.ProviderConfig)
|
||||
@ -802,8 +802,8 @@ oidc: issuer did not match the issuer returned by provider, expected "` + testIs
|
||||
actualUpstreams, err := fakePinnipedClient.IDPV1alpha1().OIDCIdentityProviders(testNamespace).List(ctx, metav1.ListOptions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
// Preprocess the set of upstreams a bit so that they're easier to assert against.
|
||||
require.ElementsMatch(t, tt.wantResultingUpstreams, normalizeUpstreams(actualUpstreams.Items, now))
|
||||
// Assert on the expected Status of the upstreams. Preprocess the upstreams a bit so that they're easier to assert against.
|
||||
require.ElementsMatch(t, tt.wantResultingUpstreams, normalizeOIDCUpstreams(actualUpstreams.Items, now))
|
||||
|
||||
// Running the sync() a second time should be idempotent except for logs, and should return the same error.
|
||||
// This also helps exercise code paths where the OIDC provider discovery hits cache.
|
||||
@ -816,7 +816,7 @@ oidc: issuer did not match the issuer returned by provider, expected "` + testIs
|
||||
}
|
||||
}
|
||||
|
||||
func normalizeUpstreams(upstreams []v1alpha1.OIDCIdentityProvider, now metav1.Time) []v1alpha1.OIDCIdentityProvider {
|
||||
func normalizeOIDCUpstreams(upstreams []v1alpha1.OIDCIdentityProvider, now metav1.Time) []v1alpha1.OIDCIdentityProvider {
|
||||
result := make([]v1alpha1.OIDCIdentityProvider, 0, len(upstreams))
|
||||
for _, u := range upstreams {
|
||||
normalized := u.DeepCopy()
|
@ -0,0 +1,16 @@
|
||||
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package upstreamwatchers
|
||||
|
||||
import "go.pinniped.dev/internal/constable"
|
||||
|
||||
const (
|
||||
ReasonNotFound = "SecretNotFound"
|
||||
ReasonWrongType = "SecretWrongType"
|
||||
ReasonMissingKeys = "SecretMissingKeys"
|
||||
ReasonSuccess = "Success"
|
||||
ReasonInvalidTLSConfig = "InvalidTLSConfig"
|
||||
|
||||
ErrNoCertificates = constable.Error("no certificates found")
|
||||
)
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package supervisorstorage
|
||||
|
21
internal/fositestoragei/fosite_storage_interface.go
Normal file
21
internal/fositestoragei/fosite_storage_interface.go
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package fositestoragei
|
||||
|
||||
import (
|
||||
"github.com/ory/fosite"
|
||||
"github.com/ory/fosite/handler/oauth2"
|
||||
"github.com/ory/fosite/handler/openid"
|
||||
"github.com/ory/fosite/handler/pkce"
|
||||
)
|
||||
|
||||
// This interface seems to be missing from Fosite.
|
||||
// Not having this interface makes it a pain to avoid cyclical test dependencies, so we'll define it.
|
||||
type AllFositeStorage interface {
|
||||
fosite.ClientManager
|
||||
oauth2.CoreStorage
|
||||
oauth2.TokenRevocationStorage
|
||||
openid.OpenIDConnectRequestStorage
|
||||
pkce.PKCERequestStorage
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user