Skip to content

Commit

Permalink
Add support for alpha provider identity support
Browse files Browse the repository at this point in the history
Adds support for enabling provider identity. This feature is unlikely to
graduate from alpha, and will likely be replaced by an implementation of
the runtime interface. It is disabled by default and is only functional
when running on Upbound.

Signed-off-by: hasheddan <georgedanielmangum@gmail.com>
  • Loading branch information
hasheddan committed Feb 10, 2023
1 parent 8d3c640 commit e9d31c7
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 16 deletions.
9 changes: 9 additions & 0 deletions cmd/crossplane/core/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ type startCommand struct {
EnableEnvironmentConfigs bool `group:"Alpha Features:" help:"Enable support for EnvironmentConfigs."`
EnableExternalSecretStores bool `group:"Alpha Features:" help:"Enable support for External Secret Stores."`
EnableCompositionFunctions bool `group:"Alpha Features:" help:"Enable support for Composition Functions."`
// NOTE(hasheddan): this feature is unlikely to graduate from alpha status
// and should be removed when a runtime interface is introduced upstream.
// See https://github.com/crossplane/crossplane/issues/2671 for more
// information.
EnableProviderIdentity bool `group:"Alpha Features:" help:"Enable support for Provider identity."`
}

// Run core Crossplane controllers.
Expand Down Expand Up @@ -129,6 +134,10 @@ func (c *startCommand) Run(s *runtime.Scheme, log logging.Logger) error { //noli
feats.Enable(features.EnableAlphaCompositionFunctions)
log.Info("Alpha feature enabled", "flag", features.EnableAlphaCompositionFunctions)
}
if c.EnableProviderIdentity {
feats.Enable(features.EnableProviderIdentity)
log.Info("Alpha feature enabled", "flag", features.EnableProviderIdentity)
}

o := controller.Options{
Logger: log,
Expand Down
25 changes: 24 additions & 1 deletion internal/controller/pkg/revision/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ var (
allowPrivilegeEscalation = false
privileged = false
runAsNonRoot = true
readOnly = true
)

// Providers are expected to use port 8080 if they expose Prometheus metrics,
Expand All @@ -50,12 +51,16 @@ const (
webhookPortName = "webhook"
webhookPort = 9443

proidcVolumeName = "proidc"
proidcDriverName = "proidc.csi.upbound.io"
proidcMountPath = "/var/run/secrets/upbound.io/provider"

upboundCTXEnv = "UPBOUND_CONTEXT"
upboundCTXValue = "uxp"
)

//nolint:gocyclo // TODO(negz): Can this be refactored for less complexity (and fewer arguments?)
func buildProviderDeployment(provider *pkgmetav1.Provider, revision v1.PackageRevision, cc *v1alpha1.ControllerConfig, namespace string, pullSecrets []corev1.LocalObjectReference) (*corev1.ServiceAccount, *appsv1.Deployment, *corev1.Service) {
func buildProviderDeployment(provider *pkgmetav1.Provider, revision v1.PackageRevision, cc *v1alpha1.ControllerConfig, namespace string, pullSecrets []corev1.LocalObjectReference, providerIdentity bool) (*corev1.ServiceAccount, *appsv1.Deployment, *corev1.Service) {
s := &corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{
Name: revision.GetName(),
Expand Down Expand Up @@ -255,6 +260,24 @@ func buildProviderDeployment(provider *pkgmetav1.Provider, revision v1.PackageRe
d.Spec.Template.Spec.Containers[0].Env = append(d.Spec.Template.Spec.Containers[0].Env, cc.Spec.Env...)
}
}

if providerIdentity {
d.Spec.Template.Spec.Volumes = append(d.Spec.Template.Spec.Volumes, corev1.Volume{
Name: proidcVolumeName,
VolumeSource: corev1.VolumeSource{
CSI: &corev1.CSIVolumeSource{
Driver: proidcDriverName,
ReadOnly: &readOnly,
},
},
})
d.Spec.Template.Spec.Containers[0].VolumeMounts = append(d.Spec.Template.Spec.Containers[0].VolumeMounts, corev1.VolumeMount{
Name: proidcVolumeName,
ReadOnly: readOnly,
MountPath: proidcMountPath,
})
}

for k, v := range d.Spec.Selector.MatchLabels { // ensure the template matches the selector
templateLabels[k] = v
}
Expand Down
38 changes: 34 additions & 4 deletions internal/controller/pkg/revision/deployment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,10 @@ func deployment(provider *pkgmetav1.Provider, revision string, img string, modif

func TestBuildProviderDeployment(t *testing.T) {
type args struct {
provider *pkgmetav1.Provider
revision *v1.ProviderRevision
cc *v1alpha1.ControllerConfig
provider *pkgmetav1.Provider
revision *v1.ProviderRevision
cc *v1alpha1.ControllerConfig
providerIdentity bool
}
type want struct {
sa *corev1.ServiceAccount
Expand Down Expand Up @@ -271,6 +272,35 @@ func TestBuildProviderDeployment(t *testing.T) {
svc: service(providerWithoutImage, revisionWithoutCC),
},
},
"NoImgNoCCWithProviderIdentity": {
reason: "If provider identity is enabled, a proidc volume should be added.",
fields: args{
provider: providerWithoutImage,
revision: revisionWithoutCC,
cc: nil,
providerIdentity: true,
},
want: want{
sa: serviceaccount(revisionWithoutCC),
d: deployment(providerWithoutImage, revisionWithCC.GetName(), pkgImg, withAdditionalVolume(corev1.Volume{
Name: proidcVolumeName,
VolumeSource: corev1.VolumeSource{
CSI: &corev1.CSIVolumeSource{
Driver: proidcDriverName,
ReadOnly: &readOnly,
// TODO(hasheddan): set volume attributes based on package
// contents.
},
},
}),
withAdditionalVolumeMount(corev1.VolumeMount{
Name: proidcVolumeName,
ReadOnly: readOnly,
MountPath: proidcMountPath,
})),
svc: service(providerWithoutImage, revisionWithoutCC),
},
},
"ImgNoCCWithWebhookTLS": {
reason: "If the webhook tls secret name is given, then the deployment should be configured to serve behind the given service.",
fields: args{
Expand Down Expand Up @@ -338,7 +368,7 @@ func TestBuildProviderDeployment(t *testing.T) {

for name, tc := range cases {
t.Run(name, func(t *testing.T) {
sa, d, svc := buildProviderDeployment(tc.fields.provider, tc.fields.revision, tc.fields.cc, namespace, nil)
sa, d, svc := buildProviderDeployment(tc.fields.provider, tc.fields.revision, tc.fields.cc, namespace, nil, tc.fields.providerIdentity)

if diff := cmp.Diff(tc.want.sa, sa, cmpopts.IgnoreTypes([]metav1.OwnerReference{})); diff != "" {
t.Errorf("-want, +got:\n%s\n", diff)
Expand Down
20 changes: 11 additions & 9 deletions internal/controller/pkg/revision/hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,19 @@ type Hooks interface {
// ProviderHooks performs operations for a provider package that requires a
// controller before and after the revision establishes objects.
type ProviderHooks struct {
client resource.ClientApplicator
namespace string
serviceAccount string
client resource.ClientApplicator
namespace string
serviceAccount string
providerIdentity bool
}

// NewProviderHooks creates a new ProviderHooks.
func NewProviderHooks(client resource.ClientApplicator, namespace, serviceAccount string) *ProviderHooks {
func NewProviderHooks(client resource.ClientApplicator, namespace, serviceAccount string, providerIdentity bool) *ProviderHooks {
return &ProviderHooks{
client: client,
namespace: namespace,
serviceAccount: serviceAccount,
client: client,
namespace: namespace,
serviceAccount: serviceAccount,
providerIdentity: providerIdentity,
}
}

Expand Down Expand Up @@ -98,7 +100,7 @@ func (h *ProviderHooks) Pre(ctx context.Context, pkg runtime.Object, pr v1.Packa

// NOTE(hasheddan): we avoid fetching pull secrets and controller config as
// they aren't needed to delete Deployment, ServiceAccount, and Service.
s, d, svc := buildProviderDeployment(pkgProvider, pr, nil, h.namespace, []corev1.LocalObjectReference{})
s, d, svc := buildProviderDeployment(pkgProvider, pr, nil, h.namespace, []corev1.LocalObjectReference{}, h.providerIdentity)
if err := h.client.Delete(ctx, d); resource.IgnoreNotFound(err) != nil {
return errors.Wrap(err, errDeleteProviderDeployment)
}
Expand Down Expand Up @@ -130,7 +132,7 @@ func (h *ProviderHooks) Post(ctx context.Context, pkg runtime.Object, pr v1.Pack
if err != nil {
return err
}
s, d, svc := buildProviderDeployment(pkgProvider, pr, cc, h.namespace, append(pr.GetPackagePullSecrets(), ps...))
s, d, svc := buildProviderDeployment(pkgProvider, pr, cc, h.namespace, append(pr.GetPackagePullSecrets(), ps...), h.providerIdentity)
if err := h.client.Apply(ctx, s); err != nil {
return errors.Wrap(err, errApplyProviderSA)
}
Expand Down
3 changes: 2 additions & 1 deletion internal/controller/pkg/revision/reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import (
"github.com/crossplane/crossplane/apis/pkg/v1beta1"
"github.com/crossplane/crossplane/internal/controller/pkg/controller"
"github.com/crossplane/crossplane/internal/dag"
"github.com/crossplane/crossplane/internal/features"
"github.com/crossplane/crossplane/internal/version"
"github.com/crossplane/crossplane/internal/xpkg"
)
Expand Down Expand Up @@ -248,7 +249,7 @@ func SetupProviderRevision(mgr ctrl.Manager, o controller.Options) error {
WithHooks(NewProviderHooks(resource.ClientApplicator{
Client: mgr.GetClient(),
Applicator: resource.NewAPIPatchingApplicator(mgr.GetClient()),
}, o.Namespace, o.ServiceAccount)),
}, o.Namespace, o.ServiceAccount, o.Features.Enabled(features.EnableProviderIdentity))),
WithEstablisher(NewAPIEstablisher(mgr.GetClient(), o.Namespace)),
WithNewPackageRevisionFn(nr),
WithParser(parser.New(metaScheme, objScheme)),
Expand Down
4 changes: 3 additions & 1 deletion internal/features/features.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,11 @@ const (
// External Secret Stores. See the below design for more details.
// https://github.com/crossplane/crossplane/blob/390ddd/design/design-doc-external-secret-stores.md
EnableAlphaExternalSecretStores feature.Flag = "EnableAlphaExternalSecretStores"

// EnableAlphaCompositionFunctions enables alpha support for composition
// functions. See the below design for more details.
// https://github.com/crossplane/crossplane/blob/9ee7a2/design/design-doc-composition-functions.md
EnableAlphaCompositionFunctions feature.Flag = "EnableAlphaCompositionFunctions"
// EnableProviderIdentity enables alpha support for Provider identity. This
// feature is only available when running on Upbound.
EnableProviderIdentity feature.Flag = "EnableProviderIdentity"
)

0 comments on commit e9d31c7

Please sign in to comment.