Merge pull request #344 from vmware-tanzu/wire-api-group-suffix
Wire api group suffix through YTT/server components/CLI/integration tests
This commit is contained in:
commit
5486427d88
@ -264,6 +264,7 @@ func run(podInfo *downward.PodInfo, cfg *supervisor.Config) error {
|
|||||||
return fmt.Errorf("cannot create deployment ref: %w", err)
|
return fmt.Errorf("cannot create deployment ref: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_ = *cfg.APIGroupSuffix // TODO: wire API group into kubeclient.
|
||||||
client, err := kubeclient.New(dref)
|
client, err := kubeclient.New(dref)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot create k8s client: %w", err)
|
return fmt.Errorf("cannot create k8s client: %w", err)
|
||||||
|
@ -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
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package cmd
|
package cmd
|
||||||
@ -70,6 +70,7 @@ func legacyGetKubeconfigCommand(deps kubeconfigDeps) *cobra.Command {
|
|||||||
namespace: namespace,
|
namespace: namespace,
|
||||||
authenticatorName: authenticatorName,
|
authenticatorName: authenticatorName,
|
||||||
authenticatorType: authenticatorType,
|
authenticatorType: authenticatorType,
|
||||||
|
apiGroupSuffix: "pinniped.dev",
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -73,6 +73,7 @@ type getKubeconfigConciergeParams struct {
|
|||||||
namespace string
|
namespace string
|
||||||
authenticatorName string
|
authenticatorName string
|
||||||
authenticatorType string
|
authenticatorType string
|
||||||
|
apiGroupSuffix string
|
||||||
}
|
}
|
||||||
|
|
||||||
type getKubeconfigParams struct {
|
type getKubeconfigParams struct {
|
||||||
@ -103,6 +104,7 @@ func kubeconfigCommand(deps kubeconfigDeps) *cobra.Command {
|
|||||||
f.StringVar(&flags.concierge.namespace, "concierge-namespace", "pinniped-concierge", "Namespace in which the concierge was installed")
|
f.StringVar(&flags.concierge.namespace, "concierge-namespace", "pinniped-concierge", "Namespace in which the concierge was installed")
|
||||||
f.StringVar(&flags.concierge.authenticatorType, "concierge-authenticator-type", "", "Concierge authenticator type (e.g., 'webhook', 'jwt') (default: autodiscover)")
|
f.StringVar(&flags.concierge.authenticatorType, "concierge-authenticator-type", "", "Concierge authenticator type (e.g., 'webhook', 'jwt') (default: autodiscover)")
|
||||||
f.StringVar(&flags.concierge.authenticatorName, "concierge-authenticator-name", "", "Concierge authenticator name (default: autodiscover)")
|
f.StringVar(&flags.concierge.authenticatorName, "concierge-authenticator-name", "", "Concierge authenticator name (default: autodiscover)")
|
||||||
|
f.StringVar(&flags.concierge.apiGroupSuffix, "concierge-api-group-suffix", "pinniped.dev", "Concierge API group suffix")
|
||||||
|
|
||||||
f.StringVar(&flags.oidc.issuer, "oidc-issuer", "", "OpenID Connect issuer URL (default: autodiscover)")
|
f.StringVar(&flags.oidc.issuer, "oidc-issuer", "", "OpenID Connect issuer URL (default: autodiscover)")
|
||||||
f.StringVar(&flags.oidc.clientID, "oidc-client-id", "pinniped-cli", "OpenID Connect client ID (default: autodiscover)")
|
f.StringVar(&flags.oidc.clientID, "oidc-client-id", "pinniped-cli", "OpenID Connect client ID (default: autodiscover)")
|
||||||
@ -258,6 +260,7 @@ func configureConcierge(authenticator metav1.Object, flags *getKubeconfigParams,
|
|||||||
// Append the flags to configure the Concierge credential exchange at runtime.
|
// Append the flags to configure the Concierge credential exchange at runtime.
|
||||||
execConfig.Args = append(execConfig.Args,
|
execConfig.Args = append(execConfig.Args,
|
||||||
"--enable-concierge",
|
"--enable-concierge",
|
||||||
|
"--concierge-api-group-suffix="+flags.concierge.apiGroupSuffix,
|
||||||
"--concierge-namespace="+flags.concierge.namespace,
|
"--concierge-namespace="+flags.concierge.namespace,
|
||||||
"--concierge-authenticator-name="+flags.concierge.authenticatorName,
|
"--concierge-authenticator-name="+flags.concierge.authenticatorName,
|
||||||
"--concierge-authenticator-type="+flags.concierge.authenticatorType,
|
"--concierge-authenticator-type="+flags.concierge.authenticatorType,
|
||||||
|
@ -57,6 +57,7 @@ func TestGetKubeconfig(t *testing.T) {
|
|||||||
kubeconfig [flags]
|
kubeconfig [flags]
|
||||||
|
|
||||||
Flags:
|
Flags:
|
||||||
|
--concierge-api-group-suffix string Concierge API group suffix (default "pinniped.dev")
|
||||||
--concierge-authenticator-name string Concierge authenticator name (default: autodiscover)
|
--concierge-authenticator-name string Concierge authenticator name (default: autodiscover)
|
||||||
--concierge-authenticator-type string Concierge authenticator type (e.g., 'webhook', 'jwt') (default: autodiscover)
|
--concierge-authenticator-type string Concierge authenticator type (e.g., 'webhook', 'jwt') (default: autodiscover)
|
||||||
--concierge-namespace string Namespace in which the concierge was installed (default "pinniped-concierge")
|
--concierge-namespace string Namespace in which the concierge was installed (default "pinniped-concierge")
|
||||||
@ -313,6 +314,7 @@ func TestGetKubeconfig(t *testing.T) {
|
|||||||
- login
|
- login
|
||||||
- static
|
- static
|
||||||
- --enable-concierge
|
- --enable-concierge
|
||||||
|
- --concierge-api-group-suffix=pinniped.dev
|
||||||
- --concierge-namespace=test-namespace
|
- --concierge-namespace=test-namespace
|
||||||
- --concierge-authenticator-name=test-authenticator
|
- --concierge-authenticator-name=test-authenticator
|
||||||
- --concierge-authenticator-type=webhook
|
- --concierge-authenticator-type=webhook
|
||||||
@ -358,6 +360,7 @@ func TestGetKubeconfig(t *testing.T) {
|
|||||||
- login
|
- login
|
||||||
- static
|
- static
|
||||||
- --enable-concierge
|
- --enable-concierge
|
||||||
|
- --concierge-api-group-suffix=pinniped.dev
|
||||||
- --concierge-namespace=test-namespace
|
- --concierge-namespace=test-namespace
|
||||||
- --concierge-authenticator-name=test-authenticator
|
- --concierge-authenticator-name=test-authenticator
|
||||||
- --concierge-authenticator-type=webhook
|
- --concierge-authenticator-type=webhook
|
||||||
@ -410,6 +413,7 @@ func TestGetKubeconfig(t *testing.T) {
|
|||||||
- login
|
- login
|
||||||
- oidc
|
- oidc
|
||||||
- --enable-concierge
|
- --enable-concierge
|
||||||
|
- --concierge-api-group-suffix=pinniped.dev
|
||||||
- --concierge-namespace=pinniped-concierge
|
- --concierge-namespace=pinniped-concierge
|
||||||
- --concierge-authenticator-name=test-authenticator
|
- --concierge-authenticator-name=test-authenticator
|
||||||
- --concierge-authenticator-type=jwt
|
- --concierge-authenticator-type=jwt
|
||||||
@ -429,6 +433,7 @@ func TestGetKubeconfig(t *testing.T) {
|
|||||||
name: "autodetect nothing, set a bunch of options",
|
name: "autodetect nothing, set a bunch of options",
|
||||||
args: []string{
|
args: []string{
|
||||||
"--kubeconfig", "./testdata/kubeconfig.yaml",
|
"--kubeconfig", "./testdata/kubeconfig.yaml",
|
||||||
|
"--concierge-api-group-suffix", "tuna.io",
|
||||||
"--concierge-authenticator-type", "webhook",
|
"--concierge-authenticator-type", "webhook",
|
||||||
"--concierge-authenticator-name", "test-authenticator",
|
"--concierge-authenticator-name", "test-authenticator",
|
||||||
"--oidc-issuer", "https://example.com/issuer",
|
"--oidc-issuer", "https://example.com/issuer",
|
||||||
@ -468,6 +473,7 @@ func TestGetKubeconfig(t *testing.T) {
|
|||||||
- login
|
- login
|
||||||
- oidc
|
- oidc
|
||||||
- --enable-concierge
|
- --enable-concierge
|
||||||
|
- --concierge-api-group-suffix=tuna.io
|
||||||
- --concierge-namespace=pinniped-concierge
|
- --concierge-namespace=pinniped-concierge
|
||||||
- --concierge-authenticator-name=test-authenticator
|
- --concierge-authenticator-name=test-authenticator
|
||||||
- --concierge-authenticator-type=webhook
|
- --concierge-authenticator-type=webhook
|
||||||
|
@ -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
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package cmd
|
package cmd
|
||||||
@ -64,6 +64,7 @@ type oidcLoginFlags struct {
|
|||||||
conciergeAuthenticatorName string
|
conciergeAuthenticatorName string
|
||||||
conciergeEndpoint string
|
conciergeEndpoint string
|
||||||
conciergeCABundle string
|
conciergeCABundle string
|
||||||
|
conciergeAPIGroupSuffix string
|
||||||
}
|
}
|
||||||
|
|
||||||
func oidcLoginCommand(deps oidcLoginCommandDeps) *cobra.Command {
|
func oidcLoginCommand(deps oidcLoginCommandDeps) *cobra.Command {
|
||||||
@ -92,6 +93,7 @@ func oidcLoginCommand(deps oidcLoginCommandDeps) *cobra.Command {
|
|||||||
cmd.Flags().StringVar(&flags.conciergeAuthenticatorName, "concierge-authenticator-name", "", "Concierge authenticator name")
|
cmd.Flags().StringVar(&flags.conciergeAuthenticatorName, "concierge-authenticator-name", "", "Concierge authenticator name")
|
||||||
cmd.Flags().StringVar(&flags.conciergeEndpoint, "concierge-endpoint", "", "API base for the Pinniped concierge endpoint")
|
cmd.Flags().StringVar(&flags.conciergeEndpoint, "concierge-endpoint", "", "API base for the Pinniped concierge endpoint")
|
||||||
cmd.Flags().StringVar(&flags.conciergeCABundle, "concierge-ca-bundle-data", "", "CA bundle to use when connecting to the concierge")
|
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", "pinniped.dev", "Concierge API group suffix")
|
||||||
|
|
||||||
mustMarkHidden(&cmd, "debug-session-cache")
|
mustMarkHidden(&cmd, "debug-session-cache")
|
||||||
mustMarkRequired(&cmd, "issuer")
|
mustMarkRequired(&cmd, "issuer")
|
||||||
@ -135,6 +137,7 @@ func runOIDCLogin(cmd *cobra.Command, deps oidcLoginCommandDeps, flags oidcLogin
|
|||||||
conciergeclient.WithEndpoint(flags.conciergeEndpoint),
|
conciergeclient.WithEndpoint(flags.conciergeEndpoint),
|
||||||
conciergeclient.WithBase64CABundle(flags.conciergeCABundle),
|
conciergeclient.WithBase64CABundle(flags.conciergeCABundle),
|
||||||
conciergeclient.WithAuthenticator(flags.conciergeAuthenticatorType, flags.conciergeAuthenticatorName),
|
conciergeclient.WithAuthenticator(flags.conciergeAuthenticatorType, flags.conciergeAuthenticatorName),
|
||||||
|
conciergeclient.WithAPIGroupSuffix(flags.conciergeAPIGroupSuffix),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("invalid concierge parameters: %w", err)
|
return fmt.Errorf("invalid concierge parameters: %w", err)
|
||||||
|
@ -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
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package cmd
|
package cmd
|
||||||
@ -60,6 +60,7 @@ func TestLoginOIDCCommand(t *testing.T) {
|
|||||||
--ca-bundle strings Path to TLS certificate authority bundle (PEM format, optional, can be repeated)
|
--ca-bundle strings Path to TLS certificate authority bundle (PEM format, optional, can be repeated)
|
||||||
--ca-bundle-data strings Base64 endcoded TLS certificate authority bundle (base64 encoded PEM format, optional, can be repeated)
|
--ca-bundle-data strings Base64 endcoded TLS certificate authority bundle (base64 encoded PEM format, optional, can be repeated)
|
||||||
--client-id string OpenID Connect client ID (default "pinniped-cli")
|
--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-name string Concierge authenticator name
|
||||||
--concierge-authenticator-type string Concierge authenticator type (e.g., 'webhook', 'jwt')
|
--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-ca-bundle-data string CA bundle to use when connecting to the concierge
|
||||||
@ -175,6 +176,7 @@ func TestLoginOIDCCommand(t *testing.T) {
|
|||||||
"--concierge-authenticator-name", "test-authenticator",
|
"--concierge-authenticator-name", "test-authenticator",
|
||||||
"--concierge-endpoint", "https://127.0.0.1:1234/",
|
"--concierge-endpoint", "https://127.0.0.1:1234/",
|
||||||
"--concierge-ca-bundle-data", base64.StdEncoding.EncodeToString(testCA.Bundle()),
|
"--concierge-ca-bundle-data", base64.StdEncoding.EncodeToString(testCA.Bundle()),
|
||||||
|
"--concierge-api-group-suffix", "some.suffix.com",
|
||||||
},
|
},
|
||||||
wantOptionsCount: 7,
|
wantOptionsCount: 7,
|
||||||
wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{},"status":{"token":"exchanged-token"}}` + "\n",
|
wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{},"status":{"token":"exchanged-token"}}` + "\n",
|
||||||
|
@ -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
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package cmd
|
package cmd
|
||||||
@ -46,6 +46,7 @@ type staticLoginParams struct {
|
|||||||
conciergeAuthenticatorName string
|
conciergeAuthenticatorName string
|
||||||
conciergeEndpoint string
|
conciergeEndpoint string
|
||||||
conciergeCABundle string
|
conciergeCABundle string
|
||||||
|
conciergeAPIGroupSuffix string
|
||||||
}
|
}
|
||||||
|
|
||||||
func staticLoginCommand(deps staticLoginDeps) *cobra.Command {
|
func staticLoginCommand(deps staticLoginDeps) *cobra.Command {
|
||||||
@ -66,6 +67,7 @@ func staticLoginCommand(deps staticLoginDeps) *cobra.Command {
|
|||||||
cmd.Flags().StringVar(&flags.conciergeAuthenticatorName, "concierge-authenticator-name", "", "Concierge authenticator name")
|
cmd.Flags().StringVar(&flags.conciergeAuthenticatorName, "concierge-authenticator-name", "", "Concierge authenticator name")
|
||||||
cmd.Flags().StringVar(&flags.conciergeEndpoint, "concierge-endpoint", "", "API base for the Pinniped concierge endpoint")
|
cmd.Flags().StringVar(&flags.conciergeEndpoint, "concierge-endpoint", "", "API base for the Pinniped concierge endpoint")
|
||||||
cmd.Flags().StringVar(&flags.conciergeCABundle, "concierge-ca-bundle-data", "", "CA bundle to use when connecting to the concierge")
|
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", "pinniped.dev", "Concierge API group suffix")
|
||||||
cmd.RunE = func(cmd *cobra.Command, args []string) error { return runStaticLogin(cmd.OutOrStdout(), deps, flags) }
|
cmd.RunE = func(cmd *cobra.Command, args []string) error { return runStaticLogin(cmd.OutOrStdout(), deps, flags) }
|
||||||
return &cmd
|
return &cmd
|
||||||
}
|
}
|
||||||
@ -83,6 +85,7 @@ func runStaticLogin(out io.Writer, deps staticLoginDeps, flags staticLoginParams
|
|||||||
conciergeclient.WithEndpoint(flags.conciergeEndpoint),
|
conciergeclient.WithEndpoint(flags.conciergeEndpoint),
|
||||||
conciergeclient.WithBase64CABundle(flags.conciergeCABundle),
|
conciergeclient.WithBase64CABundle(flags.conciergeCABundle),
|
||||||
conciergeclient.WithAuthenticator(flags.conciergeAuthenticatorType, flags.conciergeAuthenticatorName),
|
conciergeclient.WithAuthenticator(flags.conciergeAuthenticatorType, flags.conciergeAuthenticatorName),
|
||||||
|
conciergeclient.WithAPIGroupSuffix(flags.conciergeAPIGroupSuffix),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("invalid concierge parameters: %w", err)
|
return fmt.Errorf("invalid concierge parameters: %w", err)
|
||||||
|
@ -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
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package cmd
|
package cmd
|
||||||
@ -51,6 +51,7 @@ func TestLoginStaticCommand(t *testing.T) {
|
|||||||
static [--token TOKEN] [--token-env TOKEN_NAME] [flags]
|
static [--token TOKEN] [--token-env TOKEN_NAME] [flags]
|
||||||
|
|
||||||
Flags:
|
Flags:
|
||||||
|
--concierge-api-group-suffix string Concierge API group suffix (default "pinniped.dev")
|
||||||
--concierge-authenticator-name string Concierge authenticator name
|
--concierge-authenticator-name string Concierge authenticator name
|
||||||
--concierge-authenticator-type string Concierge authenticator type (e.g., 'webhook', 'jwt')
|
--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-ca-bundle-data string CA bundle to use when connecting to the concierge
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#@ load("@ytt:data", "data")
|
#@ load("@ytt:data", "data")
|
||||||
#@ load("@ytt:json", "json")
|
#@ load("@ytt:json", "json")
|
||||||
#@ load("helpers.lib.yaml", "defaultLabel", "labels", "namespace", "defaultResourceName", "defaultResourceNameWithSuffix", "getAndValidateLogLevel")
|
#@ load("helpers.lib.yaml", "defaultLabel", "labels", "namespace", "defaultResourceName", "defaultResourceNameWithSuffix", "getAndValidateLogLevel", "pinnipedDevAPIGroupWithPrefix")
|
||||||
|
|
||||||
#@ if not data.values.into_namespace:
|
#@ if not data.values.into_namespace:
|
||||||
---
|
---
|
||||||
@ -37,6 +37,7 @@ data:
|
|||||||
servingCertificate:
|
servingCertificate:
|
||||||
durationSeconds: (@= str(data.values.api_serving_certificate_duration_seconds) @)
|
durationSeconds: (@= str(data.values.api_serving_certificate_duration_seconds) @)
|
||||||
renewBeforeSeconds: (@= str(data.values.api_serving_certificate_renew_before_seconds) @)
|
renewBeforeSeconds: (@= str(data.values.api_serving_certificate_renew_before_seconds) @)
|
||||||
|
apiGroupSuffix: (@= data.values.api_group_suffix @)
|
||||||
names:
|
names:
|
||||||
servingCertificateSecret: (@= defaultResourceNameWithSuffix("api-tls-serving-certificate") @)
|
servingCertificateSecret: (@= defaultResourceNameWithSuffix("api-tls-serving-certificate") @)
|
||||||
credentialIssuer: (@= defaultResourceNameWithSuffix("config") @)
|
credentialIssuer: (@= defaultResourceNameWithSuffix("config") @)
|
||||||
@ -191,11 +192,11 @@ spec:
|
|||||||
apiVersion: apiregistration.k8s.io/v1
|
apiVersion: apiregistration.k8s.io/v1
|
||||||
kind: APIService
|
kind: APIService
|
||||||
metadata:
|
metadata:
|
||||||
name: v1alpha1.login.concierge.pinniped.dev
|
name: #@ pinnipedDevAPIGroupWithPrefix("v1alpha1.login.concierge")
|
||||||
labels: #@ labels()
|
labels: #@ labels()
|
||||||
spec:
|
spec:
|
||||||
version: v1alpha1
|
version: v1alpha1
|
||||||
group: login.concierge.pinniped.dev
|
group: #@ pinnipedDevAPIGroupWithPrefix("login.concierge")
|
||||||
groupPriorityMinimum: 2500
|
groupPriorityMinimum: 2500
|
||||||
versionPriority: 10
|
versionPriority: 10
|
||||||
#! caBundle: Do not include this key here. Starts out null, will be updated/owned by the golang code.
|
#! caBundle: Do not include this key here. Starts out null, will be updated/owned by the golang code.
|
||||||
|
@ -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
|
#! SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
#@ load("@ytt:data", "data")
|
#@ load("@ytt:data", "data")
|
||||||
@ -12,6 +12,10 @@
|
|||||||
#@ return data.values.app_name + "-" + suffix
|
#@ return data.values.app_name + "-" + suffix
|
||||||
#@ end
|
#@ end
|
||||||
|
|
||||||
|
#@ def pinnipedDevAPIGroupWithPrefix(prefix):
|
||||||
|
#@ return prefix + "." + data.values.api_group_suffix
|
||||||
|
#@ end
|
||||||
|
|
||||||
#@ def namespace():
|
#@ def namespace():
|
||||||
#@ if data.values.into_namespace:
|
#@ if data.values.into_namespace:
|
||||||
#@ return data.values.into_namespace
|
#@ return data.values.into_namespace
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#! SPDX-License-Identifier: Apache-2.0
|
#! SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
#@ load("@ytt:data", "data")
|
#@ load("@ytt:data", "data")
|
||||||
#@ load("helpers.lib.yaml", "labels", "namespace", "defaultResourceName", "defaultResourceNameWithSuffix")
|
#@ load("helpers.lib.yaml", "labels", "namespace", "defaultResourceName", "defaultResourceNameWithSuffix", "pinnipedDevAPIGroupWithPrefix")
|
||||||
|
|
||||||
#! Give permission to various cluster-scoped objects
|
#! Give permission to various cluster-scoped objects
|
||||||
---
|
---
|
||||||
@ -66,7 +66,9 @@ rules:
|
|||||||
- apiGroups: [ "" ]
|
- apiGroups: [ "" ]
|
||||||
resources: [ pods/exec ]
|
resources: [ pods/exec ]
|
||||||
verbs: [ create ]
|
verbs: [ create ]
|
||||||
- apiGroups: [ config.concierge.pinniped.dev, authentication.concierge.pinniped.dev ]
|
- apiGroups:
|
||||||
|
- #@ pinnipedDevAPIGroupWithPrefix("config.concierge")
|
||||||
|
- #@ pinnipedDevAPIGroupWithPrefix("authentication.concierge")
|
||||||
resources: [ "*" ]
|
resources: [ "*" ]
|
||||||
verbs: [ create, get, list, update, watch ]
|
verbs: [ create, get, list, update, watch ]
|
||||||
- apiGroups: [apps]
|
- apiGroups: [apps]
|
||||||
@ -124,7 +126,8 @@ metadata:
|
|||||||
name: #@ defaultResourceNameWithSuffix("create-token-credential-requests")
|
name: #@ defaultResourceNameWithSuffix("create-token-credential-requests")
|
||||||
labels: #@ labels()
|
labels: #@ labels()
|
||||||
rules:
|
rules:
|
||||||
- apiGroups: [ login.concierge.pinniped.dev ]
|
- apiGroups:
|
||||||
|
- #@ pinnipedDevAPIGroupWithPrefix("login.concierge")
|
||||||
resources: [ tokencredentialrequests ]
|
resources: [ tokencredentialrequests ]
|
||||||
verbs: [ create ]
|
verbs: [ create ]
|
||||||
---
|
---
|
||||||
|
@ -57,3 +57,9 @@ log_level: #! By default, when this value is left unset, only warnings and error
|
|||||||
|
|
||||||
run_as_user: 1001 #! run_as_user specifies the user ID that will own the local-user-authenticator process
|
run_as_user: 1001 #! run_as_user specifies the user ID that will own the local-user-authenticator process
|
||||||
run_as_group: 1001 #! run_as_group specifies the group ID that will own the local-user-authenticator process
|
run_as_group: 1001 #! run_as_group specifies the group ID that will own the local-user-authenticator process
|
||||||
|
|
||||||
|
#! Specify the API group suffix for all Pinniped API groups. By default, this is set to
|
||||||
|
#! pinniped.dev, so Pinniped API groups will look like foo.pinniped.dev,
|
||||||
|
#! authentication.concierge.pinniped.dev, etc. As an example, if this is set to tuna.io, then
|
||||||
|
#! Pinniped API groups will look like foo.tuna.io. authentication.concierge.tuna.io, etc.
|
||||||
|
api_group_suffix: pinniped.dev
|
||||||
|
@ -1,23 +1,33 @@
|
|||||||
#! Copyright 2020 the Pinniped contributors. All Rights Reserved.
|
#! Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||||
#! SPDX-License-Identifier: Apache-2.0
|
#! SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
#@ load("@ytt:overlay", "overlay")
|
#@ load("@ytt:overlay", "overlay")
|
||||||
#@ load("helpers.lib.yaml", "labels")
|
#@ load("helpers.lib.yaml", "labels", "pinnipedDevAPIGroupWithPrefix")
|
||||||
|
#@ load("@ytt:data", "data")
|
||||||
|
|
||||||
#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"credentialissuers.config.concierge.pinniped.dev"}}), expects=1
|
#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"credentialissuers.config.concierge.pinniped.dev"}}), expects=1
|
||||||
---
|
---
|
||||||
metadata:
|
metadata:
|
||||||
#@overlay/match missing_ok=True
|
#@overlay/match missing_ok=True
|
||||||
labels: #@ labels()
|
labels: #@ labels()
|
||||||
|
name: #@ pinnipedDevAPIGroupWithPrefix("credentialissuers.config.concierge")
|
||||||
|
spec:
|
||||||
|
group: #@ pinnipedDevAPIGroupWithPrefix("config.concierge")
|
||||||
|
|
||||||
#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"webhookauthenticators.authentication.concierge.pinniped.dev"}}), expects=1
|
#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"webhookauthenticators.authentication.concierge.pinniped.dev"}}), expects=1
|
||||||
---
|
---
|
||||||
metadata:
|
metadata:
|
||||||
#@overlay/match missing_ok=True
|
#@overlay/match missing_ok=True
|
||||||
labels: #@ labels()
|
labels: #@ labels()
|
||||||
|
name: #@ pinnipedDevAPIGroupWithPrefix("webhookauthenticators.authentication.concierge")
|
||||||
|
spec:
|
||||||
|
group: #@ pinnipedDevAPIGroupWithPrefix("authentication.concierge")
|
||||||
|
|
||||||
#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"jwtauthenticators.authentication.concierge.pinniped.dev"}}), expects=1
|
#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"jwtauthenticators.authentication.concierge.pinniped.dev"}}), expects=1
|
||||||
---
|
---
|
||||||
metadata:
|
metadata:
|
||||||
#@overlay/match missing_ok=True
|
#@overlay/match missing_ok=True
|
||||||
labels: #@ labels()
|
labels: #@ labels()
|
||||||
|
name: #@ pinnipedDevAPIGroupWithPrefix("jwtauthenticators.authentication.concierge")
|
||||||
|
spec:
|
||||||
|
group: #@ pinnipedDevAPIGroupWithPrefix("authentication.concierge")
|
||||||
|
@ -30,6 +30,7 @@ metadata:
|
|||||||
data:
|
data:
|
||||||
#@yaml/text-templated-strings
|
#@yaml/text-templated-strings
|
||||||
pinniped.yaml: |
|
pinniped.yaml: |
|
||||||
|
apiGroupSuffix: (@= data.values.api_group_suffix @)
|
||||||
names:
|
names:
|
||||||
defaultTLSCertificateSecret: (@= defaultResourceNameWithSuffix("default-tls-certificate") @)
|
defaultTLSCertificateSecret: (@= defaultResourceNameWithSuffix("default-tls-certificate") @)
|
||||||
labels: (@= json.encode(labels()).rstrip() @)
|
labels: (@= json.encode(labels()).rstrip() @)
|
||||||
|
@ -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
|
#! SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
#@ load("@ytt:data", "data")
|
#@ load("@ytt:data", "data")
|
||||||
@ -12,6 +12,10 @@
|
|||||||
#@ return data.values.app_name + "-" + suffix
|
#@ return data.values.app_name + "-" + suffix
|
||||||
#@ end
|
#@ end
|
||||||
|
|
||||||
|
#@ def pinnipedDevAPIGroupWithPrefix(prefix):
|
||||||
|
#@ return prefix + "." + data.values.api_group_suffix
|
||||||
|
#@ end
|
||||||
|
|
||||||
#@ def namespace():
|
#@ def namespace():
|
||||||
#@ if data.values.into_namespace:
|
#@ if data.values.into_namespace:
|
||||||
#@ return data.values.into_namespace
|
#@ return data.values.into_namespace
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#! Copyright 2020 the Pinniped contributors. All Rights Reserved.
|
#! Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||||
#! SPDX-License-Identifier: Apache-2.0
|
#! SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
#@ load("@ytt:data", "data")
|
#@ load("@ytt:data", "data")
|
||||||
#@ load("helpers.lib.yaml", "labels", "namespace", "defaultResourceName", "defaultResourceNameWithSuffix")
|
#@ load("helpers.lib.yaml", "labels", "namespace", "defaultResourceName", "defaultResourceNameWithSuffix", "pinnipedDevAPIGroupWithPrefix")
|
||||||
|
|
||||||
#! Give permission to various objects within the app's own namespace
|
#! Give permission to various objects within the app's own namespace
|
||||||
---
|
---
|
||||||
@ -16,13 +16,16 @@ rules:
|
|||||||
- apiGroups: [""]
|
- apiGroups: [""]
|
||||||
resources: [secrets]
|
resources: [secrets]
|
||||||
verbs: [create, get, list, patch, update, watch, delete]
|
verbs: [create, get, list, patch, update, watch, delete]
|
||||||
- apiGroups: [config.supervisor.pinniped.dev]
|
- apiGroups:
|
||||||
|
- #@ pinnipedDevAPIGroupWithPrefix("config.supervisor")
|
||||||
resources: [federationdomains]
|
resources: [federationdomains]
|
||||||
verbs: [update, get, list, watch]
|
verbs: [update, get, list, watch]
|
||||||
- apiGroups: [idp.supervisor.pinniped.dev]
|
- apiGroups:
|
||||||
|
- #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor")
|
||||||
resources: [oidcidentityproviders]
|
resources: [oidcidentityproviders]
|
||||||
verbs: [get, list, watch]
|
verbs: [get, list, watch]
|
||||||
- apiGroups: [idp.supervisor.pinniped.dev]
|
- apiGroups:
|
||||||
|
- #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor")
|
||||||
resources: [oidcidentityproviders/status]
|
resources: [oidcidentityproviders/status]
|
||||||
verbs: [get, patch, update]
|
verbs: [get, patch, update]
|
||||||
#! We want to be able to read pods/replicasets/deployment so we can learn who our deployment is to set
|
#! We want to be able to read pods/replicasets/deployment so we can learn who our deployment is to set
|
||||||
|
@ -59,3 +59,9 @@ log_level: #! By default, when this value is left unset, only warnings and error
|
|||||||
|
|
||||||
run_as_user: 1001 #! run_as_user specifies the user ID that will own the local-user-authenticator process
|
run_as_user: 1001 #! run_as_user specifies the user ID that will own the local-user-authenticator process
|
||||||
run_as_group: 1001 #! run_as_group specifies the group ID that will own the local-user-authenticator process
|
run_as_group: 1001 #! run_as_group specifies the group ID that will own the local-user-authenticator process
|
||||||
|
|
||||||
|
#! Specify the API group suffix for all Pinniped API groups. By default, this is set to
|
||||||
|
#! pinniped.dev, so Pinniped API groups will look like foo.pinniped.dev,
|
||||||
|
#! authentication.concierge.pinniped.dev, etc. As an example, if this is set to tuna.io, then
|
||||||
|
#! Pinniped API groups will look like foo.tuna.io. authentication.concierge.tuna.io, etc.
|
||||||
|
api_group_suffix: pinniped.dev
|
||||||
|
@ -1,17 +1,24 @@
|
|||||||
#! Copyright 2020 the Pinniped contributors. All Rights Reserved.
|
#! Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||||
#! SPDX-License-Identifier: Apache-2.0
|
#! SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
#@ load("@ytt:overlay", "overlay")
|
#@ load("@ytt:overlay", "overlay")
|
||||||
#@ load("helpers.lib.yaml", "labels")
|
#@ load("helpers.lib.yaml", "labels", "pinnipedDevAPIGroupWithPrefix")
|
||||||
|
#@ load("@ytt:data", "data")
|
||||||
|
|
||||||
#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"federationdomains.config.supervisor.pinniped.dev"}}), expects=1
|
#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"federationdomains.config.supervisor.pinniped.dev"}}), expects=1
|
||||||
---
|
---
|
||||||
metadata:
|
metadata:
|
||||||
#@overlay/match missing_ok=True
|
#@overlay/match missing_ok=True
|
||||||
labels: #@ labels()
|
labels: #@ labels()
|
||||||
|
name: #@ pinnipedDevAPIGroupWithPrefix("federationdomains.config.supervisor")
|
||||||
|
spec:
|
||||||
|
group: #@ pinnipedDevAPIGroupWithPrefix("config.supervisor")
|
||||||
|
|
||||||
#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"oidcidentityproviders.idp.supervisor.pinniped.dev"}}), expects=1
|
#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"oidcidentityproviders.idp.supervisor.pinniped.dev"}}), expects=1
|
||||||
---
|
---
|
||||||
metadata:
|
metadata:
|
||||||
#@overlay/match missing_ok=True
|
#@overlay/match missing_ok=True
|
||||||
labels: #@ labels()
|
labels: #@ labels()
|
||||||
|
name: #@ pinnipedDevAPIGroupWithPrefix("oidcidentityproviders.idp.supervisor")
|
||||||
|
spec:
|
||||||
|
group: #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor")
|
||||||
|
29
internal/apigroup/apigroup.go
Normal file
29
internal/apigroup/apigroup.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
// Package apigroup provides centralized logic around Pinniped's API group parameterization.
|
||||||
|
package apigroup
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// defaultAPIGroupSuffix is the default suffix of the Concierge API group. Our generated code uses
|
||||||
|
// this suffix, so we know that we can replace this suffix with the configured API group suffix.
|
||||||
|
const defaultAPIGroupSuffix = "pinniped.dev"
|
||||||
|
|
||||||
|
// Make constructs an API group from a baseAPIGroup and a parameterized apiGroupSuffix.
|
||||||
|
//
|
||||||
|
// We assume that all apiGroup's will end in "pinniped.dev", and therefore we can safely replace the
|
||||||
|
// reference to "pinniped.dev" with the provided apiGroupSuffix. If the provided baseAPIGroup does
|
||||||
|
// not end in "pinniped.dev", then this function will return an empty string and false.
|
||||||
|
//
|
||||||
|
// See Example_loginv1alpha1 and Example_string for more information on input/output pairs.
|
||||||
|
func Make(baseAPIGroup, apiGroupSuffix string) (string, bool) {
|
||||||
|
if !strings.HasSuffix(baseAPIGroup, defaultAPIGroupSuffix) {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
i := strings.LastIndex(baseAPIGroup, defaultAPIGroupSuffix)
|
||||||
|
return fmt.Sprintf("%s%s", baseAPIGroup[:i], apiGroupSuffix), true
|
||||||
|
}
|
36
internal/apigroup/apigroup_test.go
Normal file
36
internal/apigroup/apigroup_test.go
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
package apigroup
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
loginv1alpha1 "go.pinniped.dev/generated/1.20/apis/concierge/login/v1alpha1"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMakeError(t *testing.T) {
|
||||||
|
_, ok := Make("bad-suffix", "shouldnt-matter.com")
|
||||||
|
require.False(t, ok)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMakeSuffix(t *testing.T) {
|
||||||
|
s, ok := Make("something.pinniped.dev.something-else.pinniped.dev", "tuna.io")
|
||||||
|
require.Equal(t, "something.pinniped.dev.something-else.tuna.io", s)
|
||||||
|
require.True(t, ok)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Example_loginv1alpha1() {
|
||||||
|
s, _ := Make(loginv1alpha1.GroupName, "tuna.fish.io")
|
||||||
|
fmt.Println(s)
|
||||||
|
// Output: login.concierge.tuna.fish.io
|
||||||
|
}
|
||||||
|
|
||||||
|
func Example_string() {
|
||||||
|
s, _ := Make("idp.supervisor.pinniped.dev", "marlin.io")
|
||||||
|
fmt.Println(s)
|
||||||
|
// Output: idp.supervisor.marlin.io
|
||||||
|
}
|
@ -15,6 +15,7 @@ import (
|
|||||||
genericoptions "k8s.io/apiserver/pkg/server/options"
|
genericoptions "k8s.io/apiserver/pkg/server/options"
|
||||||
|
|
||||||
loginv1alpha1 "go.pinniped.dev/generated/1.20/apis/concierge/login/v1alpha1"
|
loginv1alpha1 "go.pinniped.dev/generated/1.20/apis/concierge/login/v1alpha1"
|
||||||
|
"go.pinniped.dev/internal/apigroup"
|
||||||
"go.pinniped.dev/internal/certauthority/dynamiccertauthority"
|
"go.pinniped.dev/internal/certauthority/dynamiccertauthority"
|
||||||
"go.pinniped.dev/internal/concierge/apiserver"
|
"go.pinniped.dev/internal/concierge/apiserver"
|
||||||
"go.pinniped.dev/internal/config/concierge"
|
"go.pinniped.dev/internal/config/concierge"
|
||||||
@ -36,10 +37,6 @@ type App struct {
|
|||||||
downwardAPIPath string
|
downwardAPIPath string
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is ignored for now because we turn off etcd storage below, but this is
|
|
||||||
// the right prefix in case we turn it back on.
|
|
||||||
const defaultEtcdPathPrefix = "/registry/" + loginv1alpha1.GroupName
|
|
||||||
|
|
||||||
// New constructs a new App with command line args, stdout and stderr.
|
// New constructs a new App with command line args, stdout and stderr.
|
||||||
func New(ctx context.Context, args []string, stdout, stderr io.Writer) *App {
|
func New(ctx context.Context, args []string, stdout, stderr io.Writer) *App {
|
||||||
app := &App{}
|
app := &App{}
|
||||||
@ -125,6 +122,7 @@ func (a *App) runServer(ctx context.Context) error {
|
|||||||
startControllersFunc, err := controllermanager.PrepareControllers(
|
startControllersFunc, err := controllermanager.PrepareControllers(
|
||||||
&controllermanager.Config{
|
&controllermanager.Config{
|
||||||
ServerInstallationInfo: podInfo,
|
ServerInstallationInfo: podInfo,
|
||||||
|
APIGroupSuffix: *cfg.APIGroupSuffix,
|
||||||
NamesConfig: &cfg.NamesConfig,
|
NamesConfig: &cfg.NamesConfig,
|
||||||
Labels: cfg.Labels,
|
Labels: cfg.Labels,
|
||||||
KubeCertAgentConfig: &cfg.KubeCertAgentConfig,
|
KubeCertAgentConfig: &cfg.KubeCertAgentConfig,
|
||||||
@ -146,6 +144,7 @@ func (a *App) runServer(ctx context.Context) error {
|
|||||||
authenticators,
|
authenticators,
|
||||||
dynamiccertauthority.New(dynamicSigningCertProvider),
|
dynamiccertauthority.New(dynamicSigningCertProvider),
|
||||||
startControllersFunc,
|
startControllersFunc,
|
||||||
|
*cfg.APIGroupSuffix,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not configure aggregated API server: %w", err)
|
return fmt.Errorf("could not configure aggregated API server: %w", err)
|
||||||
@ -167,7 +166,16 @@ func getAggregatedAPIServerConfig(
|
|||||||
authenticator credentialrequest.TokenCredentialRequestAuthenticator,
|
authenticator credentialrequest.TokenCredentialRequestAuthenticator,
|
||||||
issuer credentialrequest.CertIssuer,
|
issuer credentialrequest.CertIssuer,
|
||||||
startControllersPostStartHook func(context.Context),
|
startControllersPostStartHook func(context.Context),
|
||||||
|
apiGroupSuffix string,
|
||||||
) (*apiserver.Config, error) {
|
) (*apiserver.Config, error) {
|
||||||
|
// This is ignored for now because we turn off etcd storage below, but this is
|
||||||
|
// the right prefix in case we turn it back on.
|
||||||
|
apiGroup, ok := apigroup.Make(loginv1alpha1.GroupName, apiGroupSuffix)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("cannot make api group from %s/%s", loginv1alpha1.GroupName, apiGroupSuffix)
|
||||||
|
}
|
||||||
|
defaultEtcdPathPrefix := fmt.Sprintf("/registry/%s", apiGroup)
|
||||||
|
|
||||||
recommendedOptions := genericoptions.NewRecommendedOptions(
|
recommendedOptions := genericoptions.NewRecommendedOptions(
|
||||||
defaultEtcdPathPrefix,
|
defaultEtcdPathPrefix,
|
||||||
apiserver.Codecs.LegacyCodec(loginv1alpha1.SchemeGroupVersion),
|
apiserver.Codecs.LegacyCodec(loginv1alpha1.SchemeGroupVersion),
|
||||||
|
@ -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
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
// Package concierge contains functionality to load/store Config's from/to
|
// Package concierge contains functionality to load/store Config's from/to
|
||||||
@ -40,6 +40,7 @@ func FromPath(path string) (*Config, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
maybeSetAPIDefaults(&config.APIConfig)
|
maybeSetAPIDefaults(&config.APIConfig)
|
||||||
|
maybeSetAPIGroupSuffixDefault(&config.APIGroupSuffix)
|
||||||
maybeSetKubeCertAgentDefaults(&config.KubeCertAgentConfig)
|
maybeSetKubeCertAgentDefaults(&config.KubeCertAgentConfig)
|
||||||
|
|
||||||
if err := validateAPI(&config.APIConfig); err != nil {
|
if err := validateAPI(&config.APIConfig); err != nil {
|
||||||
@ -71,6 +72,12 @@ func maybeSetAPIDefaults(apiConfig *APIConfigSpec) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func maybeSetAPIGroupSuffixDefault(apiGroupSuffix **string) {
|
||||||
|
if *apiGroupSuffix == nil {
|
||||||
|
*apiGroupSuffix = stringPtr("pinniped.dev")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func maybeSetKubeCertAgentDefaults(cfg *KubeCertAgentSpec) {
|
func maybeSetKubeCertAgentDefaults(cfg *KubeCertAgentSpec) {
|
||||||
if cfg.NamePrefix == nil {
|
if cfg.NamePrefix == nil {
|
||||||
cfg.NamePrefix = stringPtr("pinniped-kube-cert-agent-")
|
cfg.NamePrefix = stringPtr("pinniped-kube-cert-agent-")
|
||||||
|
@ -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
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package concierge
|
package concierge
|
||||||
@ -30,6 +30,7 @@ func TestFromPath(t *testing.T) {
|
|||||||
servingCertificate:
|
servingCertificate:
|
||||||
durationSeconds: 3600
|
durationSeconds: 3600
|
||||||
renewBeforeSeconds: 2400
|
renewBeforeSeconds: 2400
|
||||||
|
apiGroupSuffix: some.suffix.com
|
||||||
names:
|
names:
|
||||||
servingCertificateSecret: pinniped-concierge-api-tls-serving-certificate
|
servingCertificateSecret: pinniped-concierge-api-tls-serving-certificate
|
||||||
credentialIssuer: pinniped-config
|
credentialIssuer: pinniped-config
|
||||||
@ -53,6 +54,7 @@ func TestFromPath(t *testing.T) {
|
|||||||
RenewBeforeSeconds: int64Ptr(2400),
|
RenewBeforeSeconds: int64Ptr(2400),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
APIGroupSuffix: stringPtr("some.suffix.com"),
|
||||||
NamesConfig: NamesConfigSpec{
|
NamesConfig: NamesConfigSpec{
|
||||||
ServingCertificateSecret: "pinniped-concierge-api-tls-serving-certificate",
|
ServingCertificateSecret: "pinniped-concierge-api-tls-serving-certificate",
|
||||||
CredentialIssuer: "pinniped-config",
|
CredentialIssuer: "pinniped-config",
|
||||||
@ -82,6 +84,7 @@ func TestFromPath(t *testing.T) {
|
|||||||
DiscoveryInfo: DiscoveryInfoSpec{
|
DiscoveryInfo: DiscoveryInfoSpec{
|
||||||
URL: nil,
|
URL: nil,
|
||||||
},
|
},
|
||||||
|
APIGroupSuffix: stringPtr("pinniped.dev"),
|
||||||
APIConfig: APIConfigSpec{
|
APIConfig: APIConfigSpec{
|
||||||
ServingCertificateConfig: ServingCertificateConfigSpec{
|
ServingCertificateConfig: ServingCertificateConfigSpec{
|
||||||
DurationSeconds: int64Ptr(60 * 60 * 24 * 365), // about a year
|
DurationSeconds: int64Ptr(60 * 60 * 24 * 365), // about a year
|
||||||
|
@ -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
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package concierge
|
package concierge
|
||||||
@ -9,6 +9,7 @@ import "go.pinniped.dev/internal/plog"
|
|||||||
type Config struct {
|
type Config struct {
|
||||||
DiscoveryInfo DiscoveryInfoSpec `json:"discovery"`
|
DiscoveryInfo DiscoveryInfoSpec `json:"discovery"`
|
||||||
APIConfig APIConfigSpec `json:"api"`
|
APIConfig APIConfigSpec `json:"api"`
|
||||||
|
APIGroupSuffix *string `json:"apiGroupSuffix,omitempty"`
|
||||||
NamesConfig NamesConfigSpec `json:"names"`
|
NamesConfig NamesConfigSpec `json:"names"`
|
||||||
KubeCertAgentConfig KubeCertAgentSpec `json:"kubeCertAgent"`
|
KubeCertAgentConfig KubeCertAgentSpec `json:"kubeCertAgent"`
|
||||||
Labels map[string]string `json:"labels"`
|
Labels map[string]string `json:"labels"`
|
||||||
|
@ -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
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
// Package supervisor contains functionality to load/store Config's from/to
|
// Package supervisor contains functionality to load/store Config's from/to
|
||||||
@ -34,6 +34,8 @@ func FromPath(path string) (*Config, error) {
|
|||||||
config.Labels = make(map[string]string)
|
config.Labels = make(map[string]string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
maybeSetAPIGroupSuffixDefault(&config.APIGroupSuffix)
|
||||||
|
|
||||||
if err := validateNames(&config.NamesConfig); err != nil {
|
if err := validateNames(&config.NamesConfig); err != nil {
|
||||||
return nil, fmt.Errorf("validate names: %w", err)
|
return nil, fmt.Errorf("validate names: %w", err)
|
||||||
}
|
}
|
||||||
@ -45,6 +47,12 @@ func FromPath(path string) (*Config, error) {
|
|||||||
return &config, nil
|
return &config, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func maybeSetAPIGroupSuffixDefault(apiGroupSuffix **string) {
|
||||||
|
if *apiGroupSuffix == nil {
|
||||||
|
*apiGroupSuffix = stringPtr("pinniped.dev")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func validateNames(names *NamesConfigSpec) error {
|
func validateNames(names *NamesConfigSpec) error {
|
||||||
missingNames := []string{}
|
missingNames := []string{}
|
||||||
if names.DefaultTLSCertificateSecret == "" {
|
if names.DefaultTLSCertificateSecret == "" {
|
||||||
@ -55,3 +63,7 @@ func validateNames(names *NamesConfigSpec) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func stringPtr(s string) *string {
|
||||||
|
return &s
|
||||||
|
}
|
||||||
|
@ -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
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package supervisor
|
package supervisor
|
||||||
@ -24,6 +24,7 @@ func TestFromPath(t *testing.T) {
|
|||||||
name: "Happy",
|
name: "Happy",
|
||||||
yaml: here.Doc(`
|
yaml: here.Doc(`
|
||||||
---
|
---
|
||||||
|
apiGroupSuffix: some.suffix.com
|
||||||
labels:
|
labels:
|
||||||
myLabelKey1: myLabelValue1
|
myLabelKey1: myLabelValue1
|
||||||
myLabelKey2: myLabelValue2
|
myLabelKey2: myLabelValue2
|
||||||
@ -31,6 +32,7 @@ func TestFromPath(t *testing.T) {
|
|||||||
defaultTLSCertificateSecret: my-secret-name
|
defaultTLSCertificateSecret: my-secret-name
|
||||||
`),
|
`),
|
||||||
wantConfig: &Config{
|
wantConfig: &Config{
|
||||||
|
APIGroupSuffix: stringPtr("some.suffix.com"),
|
||||||
Labels: map[string]string{
|
Labels: map[string]string{
|
||||||
"myLabelKey1": "myLabelValue1",
|
"myLabelKey1": "myLabelValue1",
|
||||||
"myLabelKey2": "myLabelValue2",
|
"myLabelKey2": "myLabelValue2",
|
||||||
@ -48,7 +50,8 @@ func TestFromPath(t *testing.T) {
|
|||||||
defaultTLSCertificateSecret: my-secret-name
|
defaultTLSCertificateSecret: my-secret-name
|
||||||
`),
|
`),
|
||||||
wantConfig: &Config{
|
wantConfig: &Config{
|
||||||
Labels: map[string]string{},
|
APIGroupSuffix: stringPtr("pinniped.dev"),
|
||||||
|
Labels: map[string]string{},
|
||||||
NamesConfig: NamesConfigSpec{
|
NamesConfig: NamesConfigSpec{
|
||||||
DefaultTLSCertificateSecret: "my-secret-name",
|
DefaultTLSCertificateSecret: "my-secret-name",
|
||||||
},
|
},
|
||||||
|
@ -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
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package supervisor
|
package supervisor
|
||||||
@ -7,9 +7,10 @@ import "go.pinniped.dev/internal/plog"
|
|||||||
|
|
||||||
// Config contains knobs to setup an instance of the Pinniped Supervisor.
|
// Config contains knobs to setup an instance of the Pinniped Supervisor.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Labels map[string]string `json:"labels"`
|
APIGroupSuffix *string `json:"apiGroupSuffix,omitempty"`
|
||||||
NamesConfig NamesConfigSpec `json:"names"`
|
Labels map[string]string `json:"labels"`
|
||||||
LogLevel plog.LogLevel `json:"logLevel"`
|
NamesConfig NamesConfigSpec `json:"names"`
|
||||||
|
LogLevel plog.LogLevel `json:"logLevel"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NamesConfigSpec configures the names of some Kubernetes resources for the Supervisor.
|
// NamesConfigSpec configures the names of some Kubernetes resources for the Supervisor.
|
||||||
|
@ -18,6 +18,7 @@ import (
|
|||||||
loginv1alpha1 "go.pinniped.dev/generated/1.20/apis/concierge/login/v1alpha1"
|
loginv1alpha1 "go.pinniped.dev/generated/1.20/apis/concierge/login/v1alpha1"
|
||||||
pinnipedclientset "go.pinniped.dev/generated/1.20/client/concierge/clientset/versioned"
|
pinnipedclientset "go.pinniped.dev/generated/1.20/client/concierge/clientset/versioned"
|
||||||
pinnipedinformers "go.pinniped.dev/generated/1.20/client/concierge/informers/externalversions"
|
pinnipedinformers "go.pinniped.dev/generated/1.20/client/concierge/informers/externalversions"
|
||||||
|
"go.pinniped.dev/internal/apigroup"
|
||||||
"go.pinniped.dev/internal/config/concierge"
|
"go.pinniped.dev/internal/config/concierge"
|
||||||
"go.pinniped.dev/internal/controller/apicerts"
|
"go.pinniped.dev/internal/controller/apicerts"
|
||||||
"go.pinniped.dev/internal/controller/authenticator/authncache"
|
"go.pinniped.dev/internal/controller/authenticator/authncache"
|
||||||
@ -45,6 +46,9 @@ type Config struct {
|
|||||||
// ServerInstallationInfo provides the name of the pod in which Pinniped is running and the namespace in which Pinniped is deployed.
|
// ServerInstallationInfo provides the name of the pod in which Pinniped is running and the namespace in which Pinniped is deployed.
|
||||||
ServerInstallationInfo *downward.PodInfo
|
ServerInstallationInfo *downward.PodInfo
|
||||||
|
|
||||||
|
// APIGroupSuffix is the suffix of the Pinniped API that should be targeted by these controllers.
|
||||||
|
APIGroupSuffix string
|
||||||
|
|
||||||
// NamesConfig comes from the Pinniped config API (see api.Config). It specifies how Kubernetes
|
// NamesConfig comes from the Pinniped config API (see api.Config). It specifies how Kubernetes
|
||||||
// objects should be named.
|
// objects should be named.
|
||||||
NamesConfig *concierge.NamesConfigSpec
|
NamesConfig *concierge.NamesConfigSpec
|
||||||
@ -85,6 +89,7 @@ func PrepareControllers(c *Config) (func(ctx context.Context), error) {
|
|||||||
return nil, fmt.Errorf("cannot create deployment ref: %w", err)
|
return nil, fmt.Errorf("cannot create deployment ref: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_ = c.APIGroupSuffix // TODO: wire API group into kubeclient.
|
||||||
client, err := kubeclient.New(dref)
|
client, err := kubeclient.New(dref)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("could not create clients for the controllers: %w", err)
|
return nil, fmt.Errorf("could not create clients for the controllers: %w", err)
|
||||||
@ -106,6 +111,12 @@ func PrepareControllers(c *Config) (func(ctx context.Context), error) {
|
|||||||
Name: c.NamesConfig.CredentialIssuer,
|
Name: c.NamesConfig.CredentialIssuer,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
groupName, ok := apigroup.Make(loginv1alpha1.GroupName, c.APIGroupSuffix)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("cannot make api group from %s/%s", loginv1alpha1.GroupName, c.APIGroupSuffix)
|
||||||
|
}
|
||||||
|
apiServiceName := loginv1alpha1.SchemeGroupVersion.Version + "." + groupName
|
||||||
|
|
||||||
// Create controller manager.
|
// Create controller manager.
|
||||||
controllerManager := controllerlib.
|
controllerManager := controllerlib.
|
||||||
NewManager().
|
NewManager().
|
||||||
@ -145,7 +156,7 @@ func PrepareControllers(c *Config) (func(ctx context.Context), error) {
|
|||||||
apicerts.NewAPIServiceUpdaterController(
|
apicerts.NewAPIServiceUpdaterController(
|
||||||
c.ServerInstallationInfo.Namespace,
|
c.ServerInstallationInfo.Namespace,
|
||||||
c.NamesConfig.ServingCertificateSecret,
|
c.NamesConfig.ServingCertificateSecret,
|
||||||
loginv1alpha1.SchemeGroupVersion.Version+"."+loginv1alpha1.GroupName,
|
apiServiceName,
|
||||||
client.Aggregation,
|
client.Aggregation,
|
||||||
informers.installationNamespaceK8s.Core().V1().Secrets(),
|
informers.installationNamespaceK8s.Core().V1().Secrets(),
|
||||||
controllerlib.WithInformer,
|
controllerlib.WithInformer,
|
||||||
|
@ -33,10 +33,11 @@ type Option func(*Client) error
|
|||||||
|
|
||||||
// Client is a configuration for talking to the Pinniped concierge.
|
// Client is a configuration for talking to the Pinniped concierge.
|
||||||
type Client struct {
|
type Client struct {
|
||||||
namespace string
|
namespace string
|
||||||
authenticator *corev1.TypedLocalObjectReference
|
authenticator *corev1.TypedLocalObjectReference
|
||||||
caBundle string
|
caBundle string
|
||||||
endpoint *url.URL
|
endpoint *url.URL
|
||||||
|
apiGroupSuffix string
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithNamespace configures the namespace where the TokenCredentialRequest is to be sent.
|
// WithNamespace configures the namespace where the TokenCredentialRequest is to be sent.
|
||||||
@ -112,9 +113,20 @@ func WithEndpoint(endpoint string) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithAPIGroupSuffix configures the concierge's API group suffix (e.g., "pinniped.dev").
|
||||||
|
func WithAPIGroupSuffix(apiGroupSuffix string) Option {
|
||||||
|
return func(c *Client) error {
|
||||||
|
if apiGroupSuffix == "" {
|
||||||
|
return fmt.Errorf("api group suffix must not be empty")
|
||||||
|
}
|
||||||
|
c.apiGroupSuffix = apiGroupSuffix
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// New validates the specified options and returns a newly initialized *Client.
|
// New validates the specified options and returns a newly initialized *Client.
|
||||||
func New(opts ...Option) (*Client, error) {
|
func New(opts ...Option) (*Client, error) {
|
||||||
c := Client{namespace: "pinniped-concierge"}
|
c := Client{namespace: "pinniped-concierge", apiGroupSuffix: "pinniped.dev"}
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
if err := opt(&c); err != nil {
|
if err := opt(&c); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -151,6 +163,7 @@ func (c *Client) clientset() (conciergeclientset.Interface, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
_ = c.apiGroupSuffix // TODO: wire API group into kubeclient.
|
||||||
client, err := kubeclient.New(kubeclient.WithConfig(cfg))
|
client, err := kubeclient.New(kubeclient.WithConfig(cfg))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -104,6 +104,15 @@ func TestNew(t *testing.T) {
|
|||||||
},
|
},
|
||||||
wantErr: "WithEndpoint must be specified",
|
wantErr: "WithEndpoint must be specified",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "empty api group suffix",
|
||||||
|
opts: []Option{
|
||||||
|
WithAuthenticator("jwt", "test-authenticator"),
|
||||||
|
WithEndpoint("https://example.com"),
|
||||||
|
WithAPIGroupSuffix(""),
|
||||||
|
},
|
||||||
|
wantErr: "api group suffix must not be empty",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "valid",
|
name: "valid",
|
||||||
opts: []Option{
|
opts: []Option{
|
||||||
@ -114,6 +123,7 @@ func TestNew(t *testing.T) {
|
|||||||
WithBase64CABundle(base64.StdEncoding.EncodeToString(testCA.Bundle())),
|
WithBase64CABundle(base64.StdEncoding.EncodeToString(testCA.Bundle())),
|
||||||
WithAuthenticator("jwt", "test-authenticator"),
|
WithAuthenticator("jwt", "test-authenticator"),
|
||||||
WithAuthenticator("webhook", "test-authenticator"),
|
WithAuthenticator("webhook", "test-authenticator"),
|
||||||
|
WithAPIGroupSuffix("suffix.com"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -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
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
package integration
|
package integration
|
||||||
|
|
||||||
@ -65,6 +65,7 @@ func TestCLIGetKubeconfigStaticToken(t *testing.T) {
|
|||||||
args: []string{
|
args: []string{
|
||||||
"get", "kubeconfig",
|
"get", "kubeconfig",
|
||||||
"--static-token", env.TestUser.Token,
|
"--static-token", env.TestUser.Token,
|
||||||
|
"--concierge-api-group-suffix", env.APIGroupSuffix,
|
||||||
"--concierge-namespace", env.ConciergeNamespace,
|
"--concierge-namespace", env.ConciergeNamespace,
|
||||||
"--concierge-authenticator-type", "webhook",
|
"--concierge-authenticator-type", "webhook",
|
||||||
"--concierge-authenticator-name", authenticator.Name,
|
"--concierge-authenticator-name", authenticator.Name,
|
||||||
|
@ -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
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package integration
|
package integration
|
||||||
@ -13,8 +13,8 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
clientauthenticationv1beta1 "k8s.io/client-go/pkg/apis/clientauthentication/v1beta1"
|
clientauthenticationv1beta1 "k8s.io/client-go/pkg/apis/clientauthentication/v1beta1"
|
||||||
|
|
||||||
"go.pinniped.dev/internal/client"
|
|
||||||
"go.pinniped.dev/internal/here"
|
"go.pinniped.dev/internal/here"
|
||||||
|
"go.pinniped.dev/pkg/conciergeclient"
|
||||||
"go.pinniped.dev/test/library"
|
"go.pinniped.dev/test/library"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -69,10 +69,18 @@ func TestClient(t *testing.T) {
|
|||||||
|
|
||||||
// Using the CA bundle and host from the current (admin) kubeconfig, do the token exchange.
|
// Using the CA bundle and host from the current (admin) kubeconfig, do the token exchange.
|
||||||
clientConfig := library.NewClientConfig(t)
|
clientConfig := library.NewClientConfig(t)
|
||||||
|
client, err := conciergeclient.New(
|
||||||
|
conciergeclient.WithNamespace(env.ConciergeNamespace),
|
||||||
|
conciergeclient.WithCABundle(string(clientConfig.CAData)),
|
||||||
|
conciergeclient.WithEndpoint(clientConfig.Host),
|
||||||
|
conciergeclient.WithAuthenticator("webhook", webhook.Name),
|
||||||
|
conciergeclient.WithAPIGroupSuffix(env.APIGroupSuffix),
|
||||||
|
)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
var resp *clientauthenticationv1beta1.ExecCredential
|
var resp *clientauthenticationv1beta1.ExecCredential
|
||||||
assert.Eventually(t, func() bool {
|
assert.Eventually(t, func() bool {
|
||||||
resp, err = client.ExchangeToken(ctx, env.ConciergeNamespace, webhook, env.TestUser.Token, string(clientConfig.CAData), clientConfig.Host)
|
resp, err = client.ExchangeToken(ctx, env.TestUser.Token)
|
||||||
return err == nil
|
return err == nil
|
||||||
}, 10*time.Second, 500*time.Millisecond)
|
}, 10*time.Second, 500*time.Millisecond)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -79,7 +79,7 @@ func TestAPIServingCertificateAutoCreationAndRotation(t *testing.T) {
|
|||||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
const apiServiceName = "v1alpha1.login.concierge.pinniped.dev"
|
apiServiceName := "v1alpha1.login.concierge." + env.APIGroupSuffix
|
||||||
|
|
||||||
// Get the initial auto-generated version of the Secret.
|
// Get the initial auto-generated version of the Secret.
|
||||||
secret, err := kubeClient.CoreV1().Secrets(env.ConciergeNamespace).Get(ctx, defaultServingCertResourceName, metav1.GetOptions{})
|
secret, err := kubeClient.CoreV1().Secrets(env.ConciergeNamespace).Get(ctx, defaultServingCertResourceName, metav1.GetOptions{})
|
||||||
|
@ -138,6 +138,7 @@ func TestE2EFullIntegration(t *testing.T) {
|
|||||||
|
|
||||||
// Run "pinniped get kubeconfig" to get a kubeconfig YAML.
|
// Run "pinniped get kubeconfig" to get a kubeconfig YAML.
|
||||||
kubeconfigYAML, stderr := runPinnipedCLI(t, pinnipedExe, "get", "kubeconfig",
|
kubeconfigYAML, stderr := runPinnipedCLI(t, pinnipedExe, "get", "kubeconfig",
|
||||||
|
"--concierge-api-group-suffix", env.APIGroupSuffix,
|
||||||
"--concierge-namespace", env.ConciergeNamespace,
|
"--concierge-namespace", env.ConciergeNamespace,
|
||||||
"--concierge-authenticator-type", "jwt",
|
"--concierge-authenticator-type", "jwt",
|
||||||
"--concierge-authenticator-name", authenticator.Name,
|
"--concierge-authenticator-name", authenticator.Name,
|
||||||
|
@ -1,46 +1,60 @@
|
|||||||
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
|
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package integration
|
package integration
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
|
||||||
"go.pinniped.dev/test/library"
|
"go.pinniped.dev/test/library"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGetAPIResourceList(t *testing.T) {
|
func TestGetAPIResourceList(t *testing.T) {
|
||||||
library.SkipUnlessIntegration(t)
|
env := library.IntegrationEnv(t)
|
||||||
|
|
||||||
client := library.NewClientset(t)
|
client := library.NewClientset(t)
|
||||||
groups, resources, err := client.Discovery().ServerGroupsAndResources()
|
groups, resources, err := client.Discovery().ServerGroupsAndResources()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
makeGV := func(firstSegment, secondSegment string) schema.GroupVersion {
|
||||||
|
return schema.GroupVersion{
|
||||||
|
Group: fmt.Sprintf("%s.%s.%s", firstSegment, secondSegment, env.APIGroupSuffix),
|
||||||
|
Version: "v1alpha1",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
loginConciergeGV := makeGV("login", "concierge")
|
||||||
|
authenticationConciergeGV := makeGV("authentication", "concierge")
|
||||||
|
configConciergeGV := makeGV("config", "concierge")
|
||||||
|
idpSupervisorGV := makeGV("idp", "supervisor")
|
||||||
|
configSupervisorGV := makeGV("config", "supervisor")
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
group metav1.APIGroup
|
group metav1.APIGroup
|
||||||
resourceByVersion map[string][]metav1.APIResource
|
resourceByVersion map[string][]metav1.APIResource
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
group: metav1.APIGroup{
|
group: metav1.APIGroup{
|
||||||
Name: "login.concierge.pinniped.dev",
|
Name: loginConciergeGV.Group,
|
||||||
Versions: []metav1.GroupVersionForDiscovery{
|
Versions: []metav1.GroupVersionForDiscovery{
|
||||||
{
|
{
|
||||||
GroupVersion: "login.concierge.pinniped.dev/v1alpha1",
|
GroupVersion: loginConciergeGV.String(),
|
||||||
Version: "v1alpha1",
|
Version: loginConciergeGV.Version,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
PreferredVersion: metav1.GroupVersionForDiscovery{
|
PreferredVersion: metav1.GroupVersionForDiscovery{
|
||||||
GroupVersion: "login.concierge.pinniped.dev/v1alpha1",
|
GroupVersion: loginConciergeGV.String(),
|
||||||
Version: "v1alpha1",
|
Version: loginConciergeGV.Version,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
resourceByVersion: map[string][]metav1.APIResource{
|
resourceByVersion: map[string][]metav1.APIResource{
|
||||||
"login.concierge.pinniped.dev/v1alpha1": {
|
loginConciergeGV.String(): {
|
||||||
{
|
{
|
||||||
Name: "tokencredentialrequests",
|
Name: "tokencredentialrequests",
|
||||||
Kind: "TokenCredentialRequest",
|
Kind: "TokenCredentialRequest",
|
||||||
@ -53,20 +67,20 @@ func TestGetAPIResourceList(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
group: metav1.APIGroup{
|
group: metav1.APIGroup{
|
||||||
Name: "config.supervisor.pinniped.dev",
|
Name: configSupervisorGV.Group,
|
||||||
Versions: []metav1.GroupVersionForDiscovery{
|
Versions: []metav1.GroupVersionForDiscovery{
|
||||||
{
|
{
|
||||||
GroupVersion: "config.supervisor.pinniped.dev/v1alpha1",
|
GroupVersion: configSupervisorGV.String(),
|
||||||
Version: "v1alpha1",
|
Version: configSupervisorGV.Version,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
PreferredVersion: metav1.GroupVersionForDiscovery{
|
PreferredVersion: metav1.GroupVersionForDiscovery{
|
||||||
GroupVersion: "config.supervisor.pinniped.dev/v1alpha1",
|
GroupVersion: configSupervisorGV.String(),
|
||||||
Version: "v1alpha1",
|
Version: configSupervisorGV.Version,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
resourceByVersion: map[string][]metav1.APIResource{
|
resourceByVersion: map[string][]metav1.APIResource{
|
||||||
"config.supervisor.pinniped.dev/v1alpha1": {
|
configSupervisorGV.String(): {
|
||||||
{
|
{
|
||||||
Name: "federationdomains",
|
Name: "federationdomains",
|
||||||
SingularName: "federationdomain",
|
SingularName: "federationdomain",
|
||||||
@ -80,20 +94,20 @@ func TestGetAPIResourceList(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
group: metav1.APIGroup{
|
group: metav1.APIGroup{
|
||||||
Name: "idp.supervisor.pinniped.dev",
|
Name: idpSupervisorGV.Group,
|
||||||
Versions: []metav1.GroupVersionForDiscovery{
|
Versions: []metav1.GroupVersionForDiscovery{
|
||||||
{
|
{
|
||||||
GroupVersion: "idp.supervisor.pinniped.dev/v1alpha1",
|
GroupVersion: idpSupervisorGV.String(),
|
||||||
Version: "v1alpha1",
|
Version: idpSupervisorGV.Version,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
PreferredVersion: metav1.GroupVersionForDiscovery{
|
PreferredVersion: metav1.GroupVersionForDiscovery{
|
||||||
GroupVersion: "idp.supervisor.pinniped.dev/v1alpha1",
|
GroupVersion: idpSupervisorGV.String(),
|
||||||
Version: "v1alpha1",
|
Version: idpSupervisorGV.Version,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
resourceByVersion: map[string][]metav1.APIResource{
|
resourceByVersion: map[string][]metav1.APIResource{
|
||||||
"idp.supervisor.pinniped.dev/v1alpha1": {
|
idpSupervisorGV.String(): {
|
||||||
{
|
{
|
||||||
Name: "oidcidentityproviders",
|
Name: "oidcidentityproviders",
|
||||||
SingularName: "oidcidentityprovider",
|
SingularName: "oidcidentityprovider",
|
||||||
@ -113,20 +127,20 @@ func TestGetAPIResourceList(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
group: metav1.APIGroup{
|
group: metav1.APIGroup{
|
||||||
Name: "config.concierge.pinniped.dev",
|
Name: configConciergeGV.Group,
|
||||||
Versions: []metav1.GroupVersionForDiscovery{
|
Versions: []metav1.GroupVersionForDiscovery{
|
||||||
{
|
{
|
||||||
GroupVersion: "config.concierge.pinniped.dev/v1alpha1",
|
GroupVersion: configConciergeGV.String(),
|
||||||
Version: "v1alpha1",
|
Version: configConciergeGV.Version,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
PreferredVersion: metav1.GroupVersionForDiscovery{
|
PreferredVersion: metav1.GroupVersionForDiscovery{
|
||||||
GroupVersion: "config.concierge.pinniped.dev/v1alpha1",
|
GroupVersion: configConciergeGV.String(),
|
||||||
Version: "v1alpha1",
|
Version: configConciergeGV.Version,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
resourceByVersion: map[string][]metav1.APIResource{
|
resourceByVersion: map[string][]metav1.APIResource{
|
||||||
"config.concierge.pinniped.dev/v1alpha1": {
|
configConciergeGV.String(): {
|
||||||
{
|
{
|
||||||
Name: "credentialissuers",
|
Name: "credentialissuers",
|
||||||
SingularName: "credentialissuer",
|
SingularName: "credentialissuer",
|
||||||
@ -140,20 +154,20 @@ func TestGetAPIResourceList(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
group: metav1.APIGroup{
|
group: metav1.APIGroup{
|
||||||
Name: "authentication.concierge.pinniped.dev",
|
Name: authenticationConciergeGV.Group,
|
||||||
Versions: []metav1.GroupVersionForDiscovery{
|
Versions: []metav1.GroupVersionForDiscovery{
|
||||||
{
|
{
|
||||||
GroupVersion: "authentication.concierge.pinniped.dev/v1alpha1",
|
GroupVersion: authenticationConciergeGV.String(),
|
||||||
Version: "v1alpha1",
|
Version: authenticationConciergeGV.Version,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
PreferredVersion: metav1.GroupVersionForDiscovery{
|
PreferredVersion: metav1.GroupVersionForDiscovery{
|
||||||
GroupVersion: "authentication.concierge.pinniped.dev/v1alpha1",
|
GroupVersion: authenticationConciergeGV.String(),
|
||||||
Version: "v1alpha1",
|
Version: authenticationConciergeGV.Version,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
resourceByVersion: map[string][]metav1.APIResource{
|
resourceByVersion: map[string][]metav1.APIResource{
|
||||||
"authentication.concierge.pinniped.dev/v1alpha1": {
|
authenticationConciergeGV.String(): {
|
||||||
{
|
{
|
||||||
Name: "webhookauthenticators",
|
Name: "webhookauthenticators",
|
||||||
SingularName: "webhookauthenticator",
|
SingularName: "webhookauthenticator",
|
||||||
@ -182,7 +196,7 @@ func TestGetAPIResourceList(t *testing.T) {
|
|||||||
testedGroups[tt.group.Name] = true
|
testedGroups[tt.group.Name] = true
|
||||||
}
|
}
|
||||||
for _, g := range groups {
|
for _, g := range groups {
|
||||||
if !strings.Contains(g.Name, "pinniped.dev") {
|
if !strings.Contains(g.Name, env.APIGroupSuffix) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
assert.Truef(t, testedGroups[g.Name], "expected group %q to have assertions defined", g.Name)
|
assert.Truef(t, testedGroups[g.Name], "expected group %q to have assertions defined", g.Name)
|
||||||
@ -192,7 +206,7 @@ func TestGetAPIResourceList(t *testing.T) {
|
|||||||
t.Run("every API categorized appropriately", func(t *testing.T) {
|
t.Run("every API categorized appropriately", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
for _, r := range resources {
|
for _, r := range resources {
|
||||||
if !strings.Contains(r.GroupVersion, "pinniped.dev") {
|
if !strings.Contains(r.GroupVersion, env.APIGroupSuffix) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for _, a := range r.APIResources {
|
for _, a := range r.APIResources {
|
||||||
@ -208,7 +222,7 @@ func TestGetAPIResourceList(t *testing.T) {
|
|||||||
t.Run("Pinniped resources do not have short names", func(t *testing.T) {
|
t.Run("Pinniped resources do not have short names", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
for _, r := range resources {
|
for _, r := range resources {
|
||||||
if !strings.Contains(r.GroupVersion, "pinniped.dev") {
|
if !strings.Contains(r.GroupVersion, env.APIGroupSuffix) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for _, a := range r.APIResources {
|
for _, a := range r.APIResources {
|
||||||
|
@ -69,6 +69,7 @@ func TestKubeClientOwnerRef(t *testing.T) {
|
|||||||
Name: parentSecret.Name,
|
Name: parentSecret.Name,
|
||||||
UID: parentSecret.UID,
|
UID: parentSecret.UID,
|
||||||
}
|
}
|
||||||
|
_ = env.APIGroupSuffix // TODO: wire API group into kubeclient.
|
||||||
ownerRefClient, err := kubeclient.New(
|
ownerRefClient, err := kubeclient.New(
|
||||||
kubeclient.WithMiddleware(ownerref.New(ref)),
|
kubeclient.WithMiddleware(ownerref.New(ref)),
|
||||||
kubeclient.WithConfig(library.NewClientConfig(t)),
|
kubeclient.WithConfig(library.NewClientConfig(t)),
|
||||||
|
@ -31,6 +31,7 @@ import (
|
|||||||
idpv1alpha1 "go.pinniped.dev/generated/1.20/apis/supervisor/idp/v1alpha1"
|
idpv1alpha1 "go.pinniped.dev/generated/1.20/apis/supervisor/idp/v1alpha1"
|
||||||
conciergeclientset "go.pinniped.dev/generated/1.20/client/concierge/clientset/versioned"
|
conciergeclientset "go.pinniped.dev/generated/1.20/client/concierge/clientset/versioned"
|
||||||
supervisorclientset "go.pinniped.dev/generated/1.20/client/supervisor/clientset/versioned"
|
supervisorclientset "go.pinniped.dev/generated/1.20/client/supervisor/clientset/versioned"
|
||||||
|
"go.pinniped.dev/internal/kubeclient"
|
||||||
|
|
||||||
// Import to initialize client auth plugins - the kubeconfig that we use for
|
// Import to initialize client auth plugins - the kubeconfig that we use for
|
||||||
// testing may use gcloud, az, oidc, etc.
|
// testing may use gcloud, az, oidc, etc.
|
||||||
@ -76,19 +77,19 @@ func NewClientsetWithCertAndKey(t *testing.T, clientCertificateData, clientKeyDa
|
|||||||
func NewSupervisorClientset(t *testing.T) supervisorclientset.Interface {
|
func NewSupervisorClientset(t *testing.T) supervisorclientset.Interface {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
return supervisorclientset.NewForConfigOrDie(NewClientConfig(t))
|
return newKubeclient(t, NewClientConfig(t)).PinnipedSupervisor
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConciergeClientset(t *testing.T) conciergeclientset.Interface {
|
func NewConciergeClientset(t *testing.T) conciergeclientset.Interface {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
return conciergeclientset.NewForConfigOrDie(NewClientConfig(t))
|
return newKubeclient(t, NewClientConfig(t)).PinnipedConcierge
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAnonymousConciergeClientset(t *testing.T) conciergeclientset.Interface {
|
func NewAnonymousConciergeClientset(t *testing.T) conciergeclientset.Interface {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
return conciergeclientset.NewForConfigOrDie(newAnonymousClientRestConfig(t))
|
return newKubeclient(t, newAnonymousClientRestConfig(t)).PinnipedConcierge
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAggregatedClientset(t *testing.T) aggregatorclient.Interface {
|
func NewAggregatedClientset(t *testing.T) aggregatorclient.Interface {
|
||||||
@ -132,6 +133,14 @@ func newAnonymousClientRestConfigWithCertAndKeyAdded(t *testing.T, clientCertifi
|
|||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newKubeclient(t *testing.T, config *rest.Config) *kubeclient.Client {
|
||||||
|
t.Helper()
|
||||||
|
_ = IntegrationEnv(t).APIGroupSuffix // TODO: wire API group into kubeclient.
|
||||||
|
client, err := kubeclient.New(kubeclient.WithConfig(config))
|
||||||
|
require.NoError(t, err)
|
||||||
|
return client
|
||||||
|
}
|
||||||
|
|
||||||
// CreateTestWebhookAuthenticator creates and returns a test WebhookAuthenticator in $PINNIPED_TEST_CONCIERGE_NAMESPACE, which will be
|
// CreateTestWebhookAuthenticator creates and returns a test WebhookAuthenticator in $PINNIPED_TEST_CONCIERGE_NAMESPACE, which will be
|
||||||
// automatically deleted at the end of the current test's lifetime. It returns a corev1.TypedLocalObjectReference which
|
// automatically deleted at the end of the current test's lifetime. It returns a corev1.TypedLocalObjectReference which
|
||||||
// describes the test webhook authenticator within the test namespace.
|
// describes the test webhook authenticator within the test namespace.
|
||||||
|
@ -38,6 +38,7 @@ type TestEnv struct {
|
|||||||
SupervisorHTTPSIngressAddress string `json:"supervisorHttpsIngressAddress"`
|
SupervisorHTTPSIngressAddress string `json:"supervisorHttpsIngressAddress"`
|
||||||
SupervisorHTTPSIngressCABundle string `json:"supervisorHttpsIngressCABundle"`
|
SupervisorHTTPSIngressCABundle string `json:"supervisorHttpsIngressCABundle"`
|
||||||
Proxy string `json:"proxy"`
|
Proxy string `json:"proxy"`
|
||||||
|
APIGroupSuffix string `json:"apiGroupSuffix"`
|
||||||
|
|
||||||
TestUser struct {
|
TestUser struct {
|
||||||
Token string `json:"token"`
|
Token string `json:"token"`
|
||||||
@ -106,6 +107,14 @@ func needEnv(t *testing.T, key string) string {
|
|||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func wantEnv(key, dephault string) string {
|
||||||
|
value, ok := os.LookupEnv(key)
|
||||||
|
if !ok {
|
||||||
|
return dephault
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
func filterEmpty(ss []string) []string {
|
func filterEmpty(ss []string) []string {
|
||||||
filtered := []string{}
|
filtered := []string{}
|
||||||
for _, s := range ss {
|
for _, s := range ss {
|
||||||
@ -154,6 +163,7 @@ func loadEnvVars(t *testing.T, result *TestEnv) {
|
|||||||
result.SupervisorCustomLabels = supervisorCustomLabels
|
result.SupervisorCustomLabels = supervisorCustomLabels
|
||||||
require.NotEmpty(t, result.SupervisorCustomLabels, "PINNIPED_TEST_SUPERVISOR_CUSTOM_LABELS cannot be empty")
|
require.NotEmpty(t, result.SupervisorCustomLabels, "PINNIPED_TEST_SUPERVISOR_CUSTOM_LABELS cannot be empty")
|
||||||
result.Proxy = os.Getenv("PINNIPED_TEST_PROXY")
|
result.Proxy = os.Getenv("PINNIPED_TEST_PROXY")
|
||||||
|
result.APIGroupSuffix = wantEnv("PINNIPED_TEST_API_GROUP_SUFFIX", "pinniped.dev")
|
||||||
|
|
||||||
result.CLITestUpstream = TestOIDCUpstream{
|
result.CLITestUpstream = TestOIDCUpstream{
|
||||||
Issuer: needEnv(t, "PINNIPED_TEST_CLI_OIDC_ISSUER"),
|
Issuer: needEnv(t, "PINNIPED_TEST_CLI_OIDC_ISSUER"),
|
||||||
|
Loading…
Reference in New Issue
Block a user