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)
|
||||
}
|
||||
|
||||
_ = *cfg.APIGroupSuffix // TODO: wire API group into kubeclient.
|
||||
client, err := kubeclient.New(dref)
|
||||
if err != nil {
|
||||
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
|
||||
|
||||
package cmd
|
||||
@ -70,6 +70,7 @@ func legacyGetKubeconfigCommand(deps kubeconfigDeps) *cobra.Command {
|
||||
namespace: namespace,
|
||||
authenticatorName: authenticatorName,
|
||||
authenticatorType: authenticatorType,
|
||||
apiGroupSuffix: "pinniped.dev",
|
||||
},
|
||||
})
|
||||
}
|
||||
|
@ -73,6 +73,7 @@ type getKubeconfigConciergeParams struct {
|
||||
namespace string
|
||||
authenticatorName string
|
||||
authenticatorType string
|
||||
apiGroupSuffix string
|
||||
}
|
||||
|
||||
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.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.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.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.
|
||||
execConfig.Args = append(execConfig.Args,
|
||||
"--enable-concierge",
|
||||
"--concierge-api-group-suffix="+flags.concierge.apiGroupSuffix,
|
||||
"--concierge-namespace="+flags.concierge.namespace,
|
||||
"--concierge-authenticator-name="+flags.concierge.authenticatorName,
|
||||
"--concierge-authenticator-type="+flags.concierge.authenticatorType,
|
||||
|
@ -57,6 +57,7 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
kubeconfig [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-type string Concierge authenticator type (e.g., 'webhook', 'jwt') (default: autodiscover)
|
||||
--concierge-namespace string Namespace in which the concierge was installed (default "pinniped-concierge")
|
||||
@ -313,6 +314,7 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
- login
|
||||
- static
|
||||
- --enable-concierge
|
||||
- --concierge-api-group-suffix=pinniped.dev
|
||||
- --concierge-namespace=test-namespace
|
||||
- --concierge-authenticator-name=test-authenticator
|
||||
- --concierge-authenticator-type=webhook
|
||||
@ -358,6 +360,7 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
- login
|
||||
- static
|
||||
- --enable-concierge
|
||||
- --concierge-api-group-suffix=pinniped.dev
|
||||
- --concierge-namespace=test-namespace
|
||||
- --concierge-authenticator-name=test-authenticator
|
||||
- --concierge-authenticator-type=webhook
|
||||
@ -410,6 +413,7 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
- login
|
||||
- oidc
|
||||
- --enable-concierge
|
||||
- --concierge-api-group-suffix=pinniped.dev
|
||||
- --concierge-namespace=pinniped-concierge
|
||||
- --concierge-authenticator-name=test-authenticator
|
||||
- --concierge-authenticator-type=jwt
|
||||
@ -429,6 +433,7 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
name: "autodetect nothing, set a bunch of options",
|
||||
args: []string{
|
||||
"--kubeconfig", "./testdata/kubeconfig.yaml",
|
||||
"--concierge-api-group-suffix", "tuna.io",
|
||||
"--concierge-authenticator-type", "webhook",
|
||||
"--concierge-authenticator-name", "test-authenticator",
|
||||
"--oidc-issuer", "https://example.com/issuer",
|
||||
@ -468,6 +473,7 @@ func TestGetKubeconfig(t *testing.T) {
|
||||
- login
|
||||
- oidc
|
||||
- --enable-concierge
|
||||
- --concierge-api-group-suffix=tuna.io
|
||||
- --concierge-namespace=pinniped-concierge
|
||||
- --concierge-authenticator-name=test-authenticator
|
||||
- --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
|
||||
|
||||
package cmd
|
||||
@ -64,6 +64,7 @@ type oidcLoginFlags struct {
|
||||
conciergeAuthenticatorName string
|
||||
conciergeEndpoint string
|
||||
conciergeCABundle string
|
||||
conciergeAPIGroupSuffix string
|
||||
}
|
||||
|
||||
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.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.conciergeAPIGroupSuffix, "concierge-api-group-suffix", "pinniped.dev", "Concierge API group suffix")
|
||||
|
||||
mustMarkHidden(&cmd, "debug-session-cache")
|
||||
mustMarkRequired(&cmd, "issuer")
|
||||
@ -135,6 +137,7 @@ func runOIDCLogin(cmd *cobra.Command, deps oidcLoginCommandDeps, flags oidcLogin
|
||||
conciergeclient.WithEndpoint(flags.conciergeEndpoint),
|
||||
conciergeclient.WithBase64CABundle(flags.conciergeCABundle),
|
||||
conciergeclient.WithAuthenticator(flags.conciergeAuthenticatorType, flags.conciergeAuthenticatorName),
|
||||
conciergeclient.WithAPIGroupSuffix(flags.conciergeAPIGroupSuffix),
|
||||
)
|
||||
if err != nil {
|
||||
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
|
||||
|
||||
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-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")
|
||||
--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
|
||||
@ -175,6 +176,7 @@ func TestLoginOIDCCommand(t *testing.T) {
|
||||
"--concierge-authenticator-name", "test-authenticator",
|
||||
"--concierge-endpoint", "https://127.0.0.1:1234/",
|
||||
"--concierge-ca-bundle-data", base64.StdEncoding.EncodeToString(testCA.Bundle()),
|
||||
"--concierge-api-group-suffix", "some.suffix.com",
|
||||
},
|
||||
wantOptionsCount: 7,
|
||||
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
|
||||
|
||||
package cmd
|
||||
@ -46,6 +46,7 @@ type staticLoginParams struct {
|
||||
conciergeAuthenticatorName string
|
||||
conciergeEndpoint string
|
||||
conciergeCABundle string
|
||||
conciergeAPIGroupSuffix string
|
||||
}
|
||||
|
||||
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.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.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) }
|
||||
return &cmd
|
||||
}
|
||||
@ -83,6 +85,7 @@ func runStaticLogin(out io.Writer, deps staticLoginDeps, flags staticLoginParams
|
||||
conciergeclient.WithEndpoint(flags.conciergeEndpoint),
|
||||
conciergeclient.WithBase64CABundle(flags.conciergeCABundle),
|
||||
conciergeclient.WithAuthenticator(flags.conciergeAuthenticatorType, flags.conciergeAuthenticatorName),
|
||||
conciergeclient.WithAPIGroupSuffix(flags.conciergeAPIGroupSuffix),
|
||||
)
|
||||
if err != nil {
|
||||
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
|
||||
|
||||
package cmd
|
||||
@ -51,6 +51,7 @@ func TestLoginStaticCommand(t *testing.T) {
|
||||
static [--token TOKEN] [--token-env TOKEN_NAME] [flags]
|
||||
|
||||
Flags:
|
||||
--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
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#@ load("@ytt:data", "data")
|
||||
#@ 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:
|
||||
---
|
||||
@ -37,6 +37,7 @@ data:
|
||||
servingCertificate:
|
||||
durationSeconds: (@= str(data.values.api_serving_certificate_duration_seconds) @)
|
||||
renewBeforeSeconds: (@= str(data.values.api_serving_certificate_renew_before_seconds) @)
|
||||
apiGroupSuffix: (@= data.values.api_group_suffix @)
|
||||
names:
|
||||
servingCertificateSecret: (@= defaultResourceNameWithSuffix("api-tls-serving-certificate") @)
|
||||
credentialIssuer: (@= defaultResourceNameWithSuffix("config") @)
|
||||
@ -191,11 +192,11 @@ spec:
|
||||
apiVersion: apiregistration.k8s.io/v1
|
||||
kind: APIService
|
||||
metadata:
|
||||
name: v1alpha1.login.concierge.pinniped.dev
|
||||
name: #@ pinnipedDevAPIGroupWithPrefix("v1alpha1.login.concierge")
|
||||
labels: #@ labels()
|
||||
spec:
|
||||
version: v1alpha1
|
||||
group: login.concierge.pinniped.dev
|
||||
group: #@ pinnipedDevAPIGroupWithPrefix("login.concierge")
|
||||
groupPriorityMinimum: 2500
|
||||
versionPriority: 10
|
||||
#! 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
|
||||
|
||||
#@ load("@ytt:data", "data")
|
||||
@ -12,6 +12,10 @@
|
||||
#@ return data.values.app_name + "-" + suffix
|
||||
#@ end
|
||||
|
||||
#@ def pinnipedDevAPIGroupWithPrefix(prefix):
|
||||
#@ return prefix + "." + data.values.api_group_suffix
|
||||
#@ end
|
||||
|
||||
#@ def namespace():
|
||||
#@ if data.values.into_namespace:
|
||||
#@ return data.values.into_namespace
|
||||
|
@ -2,7 +2,7 @@
|
||||
#! SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#@ 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
|
||||
---
|
||||
@ -66,7 +66,9 @@ rules:
|
||||
- apiGroups: [ "" ]
|
||||
resources: [ pods/exec ]
|
||||
verbs: [ create ]
|
||||
- apiGroups: [ config.concierge.pinniped.dev, authentication.concierge.pinniped.dev ]
|
||||
- apiGroups:
|
||||
- #@ pinnipedDevAPIGroupWithPrefix("config.concierge")
|
||||
- #@ pinnipedDevAPIGroupWithPrefix("authentication.concierge")
|
||||
resources: [ "*" ]
|
||||
verbs: [ create, get, list, update, watch ]
|
||||
- apiGroups: [apps]
|
||||
@ -124,7 +126,8 @@ metadata:
|
||||
name: #@ defaultResourceNameWithSuffix("create-token-credential-requests")
|
||||
labels: #@ labels()
|
||||
rules:
|
||||
- apiGroups: [ login.concierge.pinniped.dev ]
|
||||
- apiGroups:
|
||||
- #@ pinnipedDevAPIGroupWithPrefix("login.concierge")
|
||||
resources: [ tokencredentialrequests ]
|
||||
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_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
|
||||
|
||||
#@ 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
|
||||
---
|
||||
metadata:
|
||||
#@overlay/match missing_ok=True
|
||||
labels: #@ labels()
|
||||
name: #@ pinnipedDevAPIGroupWithPrefix("credentialissuers.config.concierge")
|
||||
spec:
|
||||
group: #@ pinnipedDevAPIGroupWithPrefix("config.concierge")
|
||||
|
||||
#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"webhookauthenticators.authentication.concierge.pinniped.dev"}}), expects=1
|
||||
---
|
||||
metadata:
|
||||
#@overlay/match missing_ok=True
|
||||
labels: #@ labels()
|
||||
name: #@ pinnipedDevAPIGroupWithPrefix("webhookauthenticators.authentication.concierge")
|
||||
spec:
|
||||
group: #@ pinnipedDevAPIGroupWithPrefix("authentication.concierge")
|
||||
|
||||
#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"jwtauthenticators.authentication.concierge.pinniped.dev"}}), expects=1
|
||||
---
|
||||
metadata:
|
||||
#@overlay/match missing_ok=True
|
||||
labels: #@ labels()
|
||||
name: #@ pinnipedDevAPIGroupWithPrefix("jwtauthenticators.authentication.concierge")
|
||||
spec:
|
||||
group: #@ pinnipedDevAPIGroupWithPrefix("authentication.concierge")
|
||||
|
@ -30,6 +30,7 @@ metadata:
|
||||
data:
|
||||
#@yaml/text-templated-strings
|
||||
pinniped.yaml: |
|
||||
apiGroupSuffix: (@= data.values.api_group_suffix @)
|
||||
names:
|
||||
defaultTLSCertificateSecret: (@= defaultResourceNameWithSuffix("default-tls-certificate") @)
|
||||
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
|
||||
|
||||
#@ load("@ytt:data", "data")
|
||||
@ -12,6 +12,10 @@
|
||||
#@ return data.values.app_name + "-" + suffix
|
||||
#@ end
|
||||
|
||||
#@ def pinnipedDevAPIGroupWithPrefix(prefix):
|
||||
#@ return prefix + "." + data.values.api_group_suffix
|
||||
#@ end
|
||||
|
||||
#@ def namespace():
|
||||
#@ if data.values.into_namespace:
|
||||
#@ return data.values.into_namespace
|
||||
|
@ -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
|
||||
|
||||
#@ 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
|
||||
---
|
||||
@ -16,13 +16,16 @@ rules:
|
||||
- apiGroups: [""]
|
||||
resources: [secrets]
|
||||
verbs: [create, get, list, patch, update, watch, delete]
|
||||
- apiGroups: [config.supervisor.pinniped.dev]
|
||||
- apiGroups:
|
||||
- #@ pinnipedDevAPIGroupWithPrefix("config.supervisor")
|
||||
resources: [federationdomains]
|
||||
verbs: [update, get, list, watch]
|
||||
- apiGroups: [idp.supervisor.pinniped.dev]
|
||||
- apiGroups:
|
||||
- #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor")
|
||||
resources: [oidcidentityproviders]
|
||||
verbs: [get, list, watch]
|
||||
- apiGroups: [idp.supervisor.pinniped.dev]
|
||||
- apiGroups:
|
||||
- #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor")
|
||||
resources: [oidcidentityproviders/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
|
||||
|
@ -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_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
|
||||
|
||||
#@ 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
|
||||
---
|
||||
metadata:
|
||||
#@overlay/match missing_ok=True
|
||||
labels: #@ labels()
|
||||
name: #@ pinnipedDevAPIGroupWithPrefix("federationdomains.config.supervisor")
|
||||
spec:
|
||||
group: #@ pinnipedDevAPIGroupWithPrefix("config.supervisor")
|
||||
|
||||
#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"oidcidentityproviders.idp.supervisor.pinniped.dev"}}), expects=1
|
||||
---
|
||||
metadata:
|
||||
#@overlay/match missing_ok=True
|
||||
labels: #@ labels()
|
||||
name: #@ pinnipedDevAPIGroupWithPrefix("oidcidentityproviders.idp.supervisor")
|
||||
spec:
|
||||
group: #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor")
|
||||
|
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"
|
||||
|
||||
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/concierge/apiserver"
|
||||
"go.pinniped.dev/internal/config/concierge"
|
||||
@ -36,10 +37,6 @@ type App struct {
|
||||
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.
|
||||
func New(ctx context.Context, args []string, stdout, stderr io.Writer) *App {
|
||||
app := &App{}
|
||||
@ -125,6 +122,7 @@ func (a *App) runServer(ctx context.Context) error {
|
||||
startControllersFunc, err := controllermanager.PrepareControllers(
|
||||
&controllermanager.Config{
|
||||
ServerInstallationInfo: podInfo,
|
||||
APIGroupSuffix: *cfg.APIGroupSuffix,
|
||||
NamesConfig: &cfg.NamesConfig,
|
||||
Labels: cfg.Labels,
|
||||
KubeCertAgentConfig: &cfg.KubeCertAgentConfig,
|
||||
@ -146,6 +144,7 @@ func (a *App) runServer(ctx context.Context) error {
|
||||
authenticators,
|
||||
dynamiccertauthority.New(dynamicSigningCertProvider),
|
||||
startControllersFunc,
|
||||
*cfg.APIGroupSuffix,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not configure aggregated API server: %w", err)
|
||||
@ -167,7 +166,16 @@ func getAggregatedAPIServerConfig(
|
||||
authenticator credentialrequest.TokenCredentialRequestAuthenticator,
|
||||
issuer credentialrequest.CertIssuer,
|
||||
startControllersPostStartHook func(context.Context),
|
||||
apiGroupSuffix string,
|
||||
) (*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(
|
||||
defaultEtcdPathPrefix,
|
||||
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
|
||||
|
||||
// Package concierge contains functionality to load/store Config's from/to
|
||||
@ -40,6 +40,7 @@ func FromPath(path string) (*Config, error) {
|
||||
}
|
||||
|
||||
maybeSetAPIDefaults(&config.APIConfig)
|
||||
maybeSetAPIGroupSuffixDefault(&config.APIGroupSuffix)
|
||||
maybeSetKubeCertAgentDefaults(&config.KubeCertAgentConfig)
|
||||
|
||||
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) {
|
||||
if cfg.NamePrefix == nil {
|
||||
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
|
||||
|
||||
package concierge
|
||||
@ -30,6 +30,7 @@ func TestFromPath(t *testing.T) {
|
||||
servingCertificate:
|
||||
durationSeconds: 3600
|
||||
renewBeforeSeconds: 2400
|
||||
apiGroupSuffix: some.suffix.com
|
||||
names:
|
||||
servingCertificateSecret: pinniped-concierge-api-tls-serving-certificate
|
||||
credentialIssuer: pinniped-config
|
||||
@ -53,6 +54,7 @@ func TestFromPath(t *testing.T) {
|
||||
RenewBeforeSeconds: int64Ptr(2400),
|
||||
},
|
||||
},
|
||||
APIGroupSuffix: stringPtr("some.suffix.com"),
|
||||
NamesConfig: NamesConfigSpec{
|
||||
ServingCertificateSecret: "pinniped-concierge-api-tls-serving-certificate",
|
||||
CredentialIssuer: "pinniped-config",
|
||||
@ -82,6 +84,7 @@ func TestFromPath(t *testing.T) {
|
||||
DiscoveryInfo: DiscoveryInfoSpec{
|
||||
URL: nil,
|
||||
},
|
||||
APIGroupSuffix: stringPtr("pinniped.dev"),
|
||||
APIConfig: APIConfigSpec{
|
||||
ServingCertificateConfig: ServingCertificateConfigSpec{
|
||||
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
|
||||
|
||||
package concierge
|
||||
@ -9,6 +9,7 @@ import "go.pinniped.dev/internal/plog"
|
||||
type Config struct {
|
||||
DiscoveryInfo DiscoveryInfoSpec `json:"discovery"`
|
||||
APIConfig APIConfigSpec `json:"api"`
|
||||
APIGroupSuffix *string `json:"apiGroupSuffix,omitempty"`
|
||||
NamesConfig NamesConfigSpec `json:"names"`
|
||||
KubeCertAgentConfig KubeCertAgentSpec `json:"kubeCertAgent"`
|
||||
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
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
maybeSetAPIGroupSuffixDefault(&config.APIGroupSuffix)
|
||||
|
||||
if err := validateNames(&config.NamesConfig); err != nil {
|
||||
return nil, fmt.Errorf("validate names: %w", err)
|
||||
}
|
||||
@ -45,6 +47,12 @@ func FromPath(path string) (*Config, error) {
|
||||
return &config, nil
|
||||
}
|
||||
|
||||
func maybeSetAPIGroupSuffixDefault(apiGroupSuffix **string) {
|
||||
if *apiGroupSuffix == nil {
|
||||
*apiGroupSuffix = stringPtr("pinniped.dev")
|
||||
}
|
||||
}
|
||||
|
||||
func validateNames(names *NamesConfigSpec) error {
|
||||
missingNames := []string{}
|
||||
if names.DefaultTLSCertificateSecret == "" {
|
||||
@ -55,3 +63,7 @@ func validateNames(names *NamesConfigSpec) error {
|
||||
}
|
||||
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
|
||||
|
||||
package supervisor
|
||||
@ -24,6 +24,7 @@ func TestFromPath(t *testing.T) {
|
||||
name: "Happy",
|
||||
yaml: here.Doc(`
|
||||
---
|
||||
apiGroupSuffix: some.suffix.com
|
||||
labels:
|
||||
myLabelKey1: myLabelValue1
|
||||
myLabelKey2: myLabelValue2
|
||||
@ -31,6 +32,7 @@ func TestFromPath(t *testing.T) {
|
||||
defaultTLSCertificateSecret: my-secret-name
|
||||
`),
|
||||
wantConfig: &Config{
|
||||
APIGroupSuffix: stringPtr("some.suffix.com"),
|
||||
Labels: map[string]string{
|
||||
"myLabelKey1": "myLabelValue1",
|
||||
"myLabelKey2": "myLabelValue2",
|
||||
@ -48,6 +50,7 @@ func TestFromPath(t *testing.T) {
|
||||
defaultTLSCertificateSecret: my-secret-name
|
||||
`),
|
||||
wantConfig: &Config{
|
||||
APIGroupSuffix: stringPtr("pinniped.dev"),
|
||||
Labels: map[string]string{},
|
||||
NamesConfig: NamesConfigSpec{
|
||||
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
|
||||
|
||||
package supervisor
|
||||
@ -7,6 +7,7 @@ import "go.pinniped.dev/internal/plog"
|
||||
|
||||
// Config contains knobs to setup an instance of the Pinniped Supervisor.
|
||||
type Config struct {
|
||||
APIGroupSuffix *string `json:"apiGroupSuffix,omitempty"`
|
||||
Labels map[string]string `json:"labels"`
|
||||
NamesConfig NamesConfigSpec `json:"names"`
|
||||
LogLevel plog.LogLevel `json:"logLevel"`
|
||||
|
@ -18,6 +18,7 @@ import (
|
||||
loginv1alpha1 "go.pinniped.dev/generated/1.20/apis/concierge/login/v1alpha1"
|
||||
pinnipedclientset "go.pinniped.dev/generated/1.20/client/concierge/clientset/versioned"
|
||||
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/controller/apicerts"
|
||||
"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 *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
|
||||
// objects should be named.
|
||||
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)
|
||||
}
|
||||
|
||||
_ = c.APIGroupSuffix // TODO: wire API group into kubeclient.
|
||||
client, err := kubeclient.New(dref)
|
||||
if err != nil {
|
||||
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,
|
||||
}
|
||||
|
||||
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.
|
||||
controllerManager := controllerlib.
|
||||
NewManager().
|
||||
@ -145,7 +156,7 @@ func PrepareControllers(c *Config) (func(ctx context.Context), error) {
|
||||
apicerts.NewAPIServiceUpdaterController(
|
||||
c.ServerInstallationInfo.Namespace,
|
||||
c.NamesConfig.ServingCertificateSecret,
|
||||
loginv1alpha1.SchemeGroupVersion.Version+"."+loginv1alpha1.GroupName,
|
||||
apiServiceName,
|
||||
client.Aggregation,
|
||||
informers.installationNamespaceK8s.Core().V1().Secrets(),
|
||||
controllerlib.WithInformer,
|
||||
|
@ -37,6 +37,7 @@ type Client struct {
|
||||
authenticator *corev1.TypedLocalObjectReference
|
||||
caBundle string
|
||||
endpoint *url.URL
|
||||
apiGroupSuffix string
|
||||
}
|
||||
|
||||
// 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.
|
||||
func New(opts ...Option) (*Client, error) {
|
||||
c := Client{namespace: "pinniped-concierge"}
|
||||
c := Client{namespace: "pinniped-concierge", apiGroupSuffix: "pinniped.dev"}
|
||||
for _, opt := range opts {
|
||||
if err := opt(&c); err != nil {
|
||||
return nil, err
|
||||
@ -151,6 +163,7 @@ func (c *Client) clientset() (conciergeclientset.Interface, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_ = c.apiGroupSuffix // TODO: wire API group into kubeclient.
|
||||
client, err := kubeclient.New(kubeclient.WithConfig(cfg))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -104,6 +104,15 @@ func TestNew(t *testing.T) {
|
||||
},
|
||||
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",
|
||||
opts: []Option{
|
||||
@ -114,6 +123,7 @@ func TestNew(t *testing.T) {
|
||||
WithBase64CABundle(base64.StdEncoding.EncodeToString(testCA.Bundle())),
|
||||
WithAuthenticator("jwt", "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
|
||||
package integration
|
||||
|
||||
@ -65,6 +65,7 @@ func TestCLIGetKubeconfigStaticToken(t *testing.T) {
|
||||
args: []string{
|
||||
"get", "kubeconfig",
|
||||
"--static-token", env.TestUser.Token,
|
||||
"--concierge-api-group-suffix", env.APIGroupSuffix,
|
||||
"--concierge-namespace", env.ConciergeNamespace,
|
||||
"--concierge-authenticator-type", "webhook",
|
||||
"--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
|
||||
|
||||
package integration
|
||||
@ -13,8 +13,8 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
clientauthenticationv1beta1 "k8s.io/client-go/pkg/apis/clientauthentication/v1beta1"
|
||||
|
||||
"go.pinniped.dev/internal/client"
|
||||
"go.pinniped.dev/internal/here"
|
||||
"go.pinniped.dev/pkg/conciergeclient"
|
||||
"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.
|
||||
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
|
||||
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
|
||||
}, 10*time.Second, 500*time.Millisecond)
|
||||
require.NoError(t, err)
|
||||
|
@ -79,7 +79,7 @@ func TestAPIServingCertificateAutoCreationAndRotation(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
||||
defer cancel()
|
||||
|
||||
const apiServiceName = "v1alpha1.login.concierge.pinniped.dev"
|
||||
apiServiceName := "v1alpha1.login.concierge." + env.APIGroupSuffix
|
||||
|
||||
// Get the initial auto-generated version of the Secret.
|
||||
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.
|
||||
kubeconfigYAML, stderr := runPinnipedCLI(t, pinnipedExe, "get", "kubeconfig",
|
||||
"--concierge-api-group-suffix", env.APIGroupSuffix,
|
||||
"--concierge-namespace", env.ConciergeNamespace,
|
||||
"--concierge-authenticator-type", "jwt",
|
||||
"--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
|
||||
|
||||
package integration
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
"go.pinniped.dev/test/library"
|
||||
)
|
||||
|
||||
func TestGetAPIResourceList(t *testing.T) {
|
||||
library.SkipUnlessIntegration(t)
|
||||
env := library.IntegrationEnv(t)
|
||||
|
||||
client := library.NewClientset(t)
|
||||
groups, resources, err := client.Discovery().ServerGroupsAndResources()
|
||||
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 {
|
||||
group metav1.APIGroup
|
||||
resourceByVersion map[string][]metav1.APIResource
|
||||
}{
|
||||
{
|
||||
group: metav1.APIGroup{
|
||||
Name: "login.concierge.pinniped.dev",
|
||||
Name: loginConciergeGV.Group,
|
||||
Versions: []metav1.GroupVersionForDiscovery{
|
||||
{
|
||||
GroupVersion: "login.concierge.pinniped.dev/v1alpha1",
|
||||
Version: "v1alpha1",
|
||||
GroupVersion: loginConciergeGV.String(),
|
||||
Version: loginConciergeGV.Version,
|
||||
},
|
||||
},
|
||||
PreferredVersion: metav1.GroupVersionForDiscovery{
|
||||
GroupVersion: "login.concierge.pinniped.dev/v1alpha1",
|
||||
Version: "v1alpha1",
|
||||
GroupVersion: loginConciergeGV.String(),
|
||||
Version: loginConciergeGV.Version,
|
||||
},
|
||||
},
|
||||
resourceByVersion: map[string][]metav1.APIResource{
|
||||
"login.concierge.pinniped.dev/v1alpha1": {
|
||||
loginConciergeGV.String(): {
|
||||
{
|
||||
Name: "tokencredentialrequests",
|
||||
Kind: "TokenCredentialRequest",
|
||||
@ -53,20 +67,20 @@ func TestGetAPIResourceList(t *testing.T) {
|
||||
},
|
||||
{
|
||||
group: metav1.APIGroup{
|
||||
Name: "config.supervisor.pinniped.dev",
|
||||
Name: configSupervisorGV.Group,
|
||||
Versions: []metav1.GroupVersionForDiscovery{
|
||||
{
|
||||
GroupVersion: "config.supervisor.pinniped.dev/v1alpha1",
|
||||
Version: "v1alpha1",
|
||||
GroupVersion: configSupervisorGV.String(),
|
||||
Version: configSupervisorGV.Version,
|
||||
},
|
||||
},
|
||||
PreferredVersion: metav1.GroupVersionForDiscovery{
|
||||
GroupVersion: "config.supervisor.pinniped.dev/v1alpha1",
|
||||
Version: "v1alpha1",
|
||||
GroupVersion: configSupervisorGV.String(),
|
||||
Version: configSupervisorGV.Version,
|
||||
},
|
||||
},
|
||||
resourceByVersion: map[string][]metav1.APIResource{
|
||||
"config.supervisor.pinniped.dev/v1alpha1": {
|
||||
configSupervisorGV.String(): {
|
||||
{
|
||||
Name: "federationdomains",
|
||||
SingularName: "federationdomain",
|
||||
@ -80,20 +94,20 @@ func TestGetAPIResourceList(t *testing.T) {
|
||||
},
|
||||
{
|
||||
group: metav1.APIGroup{
|
||||
Name: "idp.supervisor.pinniped.dev",
|
||||
Name: idpSupervisorGV.Group,
|
||||
Versions: []metav1.GroupVersionForDiscovery{
|
||||
{
|
||||
GroupVersion: "idp.supervisor.pinniped.dev/v1alpha1",
|
||||
Version: "v1alpha1",
|
||||
GroupVersion: idpSupervisorGV.String(),
|
||||
Version: idpSupervisorGV.Version,
|
||||
},
|
||||
},
|
||||
PreferredVersion: metav1.GroupVersionForDiscovery{
|
||||
GroupVersion: "idp.supervisor.pinniped.dev/v1alpha1",
|
||||
Version: "v1alpha1",
|
||||
GroupVersion: idpSupervisorGV.String(),
|
||||
Version: idpSupervisorGV.Version,
|
||||
},
|
||||
},
|
||||
resourceByVersion: map[string][]metav1.APIResource{
|
||||
"idp.supervisor.pinniped.dev/v1alpha1": {
|
||||
idpSupervisorGV.String(): {
|
||||
{
|
||||
Name: "oidcidentityproviders",
|
||||
SingularName: "oidcidentityprovider",
|
||||
@ -113,20 +127,20 @@ func TestGetAPIResourceList(t *testing.T) {
|
||||
},
|
||||
{
|
||||
group: metav1.APIGroup{
|
||||
Name: "config.concierge.pinniped.dev",
|
||||
Name: configConciergeGV.Group,
|
||||
Versions: []metav1.GroupVersionForDiscovery{
|
||||
{
|
||||
GroupVersion: "config.concierge.pinniped.dev/v1alpha1",
|
||||
Version: "v1alpha1",
|
||||
GroupVersion: configConciergeGV.String(),
|
||||
Version: configConciergeGV.Version,
|
||||
},
|
||||
},
|
||||
PreferredVersion: metav1.GroupVersionForDiscovery{
|
||||
GroupVersion: "config.concierge.pinniped.dev/v1alpha1",
|
||||
Version: "v1alpha1",
|
||||
GroupVersion: configConciergeGV.String(),
|
||||
Version: configConciergeGV.Version,
|
||||
},
|
||||
},
|
||||
resourceByVersion: map[string][]metav1.APIResource{
|
||||
"config.concierge.pinniped.dev/v1alpha1": {
|
||||
configConciergeGV.String(): {
|
||||
{
|
||||
Name: "credentialissuers",
|
||||
SingularName: "credentialissuer",
|
||||
@ -140,20 +154,20 @@ func TestGetAPIResourceList(t *testing.T) {
|
||||
},
|
||||
{
|
||||
group: metav1.APIGroup{
|
||||
Name: "authentication.concierge.pinniped.dev",
|
||||
Name: authenticationConciergeGV.Group,
|
||||
Versions: []metav1.GroupVersionForDiscovery{
|
||||
{
|
||||
GroupVersion: "authentication.concierge.pinniped.dev/v1alpha1",
|
||||
Version: "v1alpha1",
|
||||
GroupVersion: authenticationConciergeGV.String(),
|
||||
Version: authenticationConciergeGV.Version,
|
||||
},
|
||||
},
|
||||
PreferredVersion: metav1.GroupVersionForDiscovery{
|
||||
GroupVersion: "authentication.concierge.pinniped.dev/v1alpha1",
|
||||
Version: "v1alpha1",
|
||||
GroupVersion: authenticationConciergeGV.String(),
|
||||
Version: authenticationConciergeGV.Version,
|
||||
},
|
||||
},
|
||||
resourceByVersion: map[string][]metav1.APIResource{
|
||||
"authentication.concierge.pinniped.dev/v1alpha1": {
|
||||
authenticationConciergeGV.String(): {
|
||||
{
|
||||
Name: "webhookauthenticators",
|
||||
SingularName: "webhookauthenticator",
|
||||
@ -182,7 +196,7 @@ func TestGetAPIResourceList(t *testing.T) {
|
||||
testedGroups[tt.group.Name] = true
|
||||
}
|
||||
for _, g := range groups {
|
||||
if !strings.Contains(g.Name, "pinniped.dev") {
|
||||
if !strings.Contains(g.Name, env.APIGroupSuffix) {
|
||||
continue
|
||||
}
|
||||
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.Parallel()
|
||||
for _, r := range resources {
|
||||
if !strings.Contains(r.GroupVersion, "pinniped.dev") {
|
||||
if !strings.Contains(r.GroupVersion, env.APIGroupSuffix) {
|
||||
continue
|
||||
}
|
||||
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.Parallel()
|
||||
for _, r := range resources {
|
||||
if !strings.Contains(r.GroupVersion, "pinniped.dev") {
|
||||
if !strings.Contains(r.GroupVersion, env.APIGroupSuffix) {
|
||||
continue
|
||||
}
|
||||
for _, a := range r.APIResources {
|
||||
|
@ -69,6 +69,7 @@ func TestKubeClientOwnerRef(t *testing.T) {
|
||||
Name: parentSecret.Name,
|
||||
UID: parentSecret.UID,
|
||||
}
|
||||
_ = env.APIGroupSuffix // TODO: wire API group into kubeclient.
|
||||
ownerRefClient, err := kubeclient.New(
|
||||
kubeclient.WithMiddleware(ownerref.New(ref)),
|
||||
kubeclient.WithConfig(library.NewClientConfig(t)),
|
||||
|
@ -31,6 +31,7 @@ import (
|
||||
idpv1alpha1 "go.pinniped.dev/generated/1.20/apis/supervisor/idp/v1alpha1"
|
||||
conciergeclientset "go.pinniped.dev/generated/1.20/client/concierge/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
|
||||
// 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 {
|
||||
t.Helper()
|
||||
|
||||
return supervisorclientset.NewForConfigOrDie(NewClientConfig(t))
|
||||
return newKubeclient(t, NewClientConfig(t)).PinnipedSupervisor
|
||||
}
|
||||
|
||||
func NewConciergeClientset(t *testing.T) conciergeclientset.Interface {
|
||||
t.Helper()
|
||||
|
||||
return conciergeclientset.NewForConfigOrDie(NewClientConfig(t))
|
||||
return newKubeclient(t, NewClientConfig(t)).PinnipedConcierge
|
||||
}
|
||||
|
||||
func NewAnonymousConciergeClientset(t *testing.T) conciergeclientset.Interface {
|
||||
t.Helper()
|
||||
|
||||
return conciergeclientset.NewForConfigOrDie(newAnonymousClientRestConfig(t))
|
||||
return newKubeclient(t, newAnonymousClientRestConfig(t)).PinnipedConcierge
|
||||
}
|
||||
|
||||
func NewAggregatedClientset(t *testing.T) aggregatorclient.Interface {
|
||||
@ -132,6 +133,14 @@ func newAnonymousClientRestConfigWithCertAndKeyAdded(t *testing.T, clientCertifi
|
||||
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
|
||||
// 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.
|
||||
|
@ -38,6 +38,7 @@ type TestEnv struct {
|
||||
SupervisorHTTPSIngressAddress string `json:"supervisorHttpsIngressAddress"`
|
||||
SupervisorHTTPSIngressCABundle string `json:"supervisorHttpsIngressCABundle"`
|
||||
Proxy string `json:"proxy"`
|
||||
APIGroupSuffix string `json:"apiGroupSuffix"`
|
||||
|
||||
TestUser struct {
|
||||
Token string `json:"token"`
|
||||
@ -106,6 +107,14 @@ func needEnv(t *testing.T, key string) string {
|
||||
return value
|
||||
}
|
||||
|
||||
func wantEnv(key, dephault string) string {
|
||||
value, ok := os.LookupEnv(key)
|
||||
if !ok {
|
||||
return dephault
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
func filterEmpty(ss []string) []string {
|
||||
filtered := []string{}
|
||||
for _, s := range ss {
|
||||
@ -154,6 +163,7 @@ func loadEnvVars(t *testing.T, result *TestEnv) {
|
||||
result.SupervisorCustomLabels = supervisorCustomLabels
|
||||
require.NotEmpty(t, result.SupervisorCustomLabels, "PINNIPED_TEST_SUPERVISOR_CUSTOM_LABELS cannot be empty")
|
||||
result.Proxy = os.Getenv("PINNIPED_TEST_PROXY")
|
||||
result.APIGroupSuffix = wantEnv("PINNIPED_TEST_API_GROUP_SUFFIX", "pinniped.dev")
|
||||
|
||||
result.CLITestUpstream = TestOIDCUpstream{
|
||||
Issuer: needEnv(t, "PINNIPED_TEST_CLI_OIDC_ISSUER"),
|
||||
|
Loading…
Reference in New Issue
Block a user