Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Certificate support for image registry #956

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions api/v1alpha1/clusterextension_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,25 @@ const (
UpgradeConstraintPolicyIgnore UpgradeConstraintPolicy = "Ignore"
)

// Similar to NamespacedName, but with json
type ClusterExtensionSecretRef struct {
// Name of the secret
Name string `json:"name"`
// Namespace of the secret
Namespace string `json:"namespace,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we force this to be the install namespace?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually disagree, the registry and it's secret are likely in a separate namespace from the installation namespace.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we allow for specification of the namespace here? I'm wondering if using the install namespace as a point where all other resources referenced should exist is more reasonable?

Copy link
Contributor Author

@tmshort tmshort Jun 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The secret is associated with the image registry, not the installation of the bundle itself. This secret is independent of the installation namespace. If we do not allow specifying the namespace, it would possibly require copying the secret to various namespaces, which then causes issues when the secret (which is a TLS certificate) needs to be updated.

Also, the service account for installation does need access to the secret.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The secret is associated with the image registry

I think my comment about cert configuration being on ClusterExtension is relevant to this discussion: #956 (comment)

TLDR: I think we should not ask users to specify certs on every installation.

Copy link
Contributor Author

@tmshort tmshort Jun 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be clear, it's not required on every installation.

If the docker-registry's certificate is signed by a system CA, this option is not required. This requires additional setup (i.e. cert-manager/trust-manager/deployment updates).

Also, if the docker-registry is public, and uses a certificate signed by a "public CA", then this option is not necessary.

If the operator-controller's deployment includes mounted certificates for the system CAs, then those will be used.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be clear, it's not required on every installation.

You are right. But it is required on every installation if you use a registry with self-signed certs (like we do in our own tests: see addCertToSpec in this PR). I would expect it to be quite a common pattern.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would actually expect it to be an exception, not a rule. The operator-controller deployment can be modified to include CAs used by the cluster.

}

type ClusterExtensionTLS struct {
//+optional
// InsecureSkipTLSVerify allows the HTTPS client to ignore the server certificate
InsecureSkipTLSVerify bool `json:"insecureSkipTLSVerify,omitempty"`
// +optional
// CertificateSecretRef references a Secret that contains the tls.crt certificate that
// can verify the server certificate.
// This fits the definition of NamespacedName (but that doesn't have json tags)
CertificateSecretRef *ClusterExtensionSecretRef `json:"certificateSecretRef,omitempty"`
}

// ClusterExtensionSpec defines the desired state of ClusterExtension
type ClusterExtensionSpec struct {
//+kubebuilder:validation:MaxLength:=48
Expand Down Expand Up @@ -78,6 +97,10 @@ type ClusterExtensionSpec struct {
// the bundle may contain resources that are cluster-scoped or that are
// installed in a different namespace. This namespace is expected to exist.
InstallNamespace string `json:"installNamespace"`

//+optional
// RegistryTLS defines the connection parameters to retrieve an image from a registry
RegistryTLS *ClusterExtensionTLS `json:"registryTLS,omitempty"`
Comment on lines +100 to +103
Copy link
Member

@m1kola m1kola Jun 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels like it does not belong in ClusterExtension. At least in the use case when we install packages from a catalog it feels like specifying this every time we create a ClusterExtension is excessive.

We need to think about UX for the following use cases:

  1. We install extensions from a catalog. I think in this case we probably don't want users to specify certs in ClusterExtension every time they install something from a catalog. Feels like some configuration should be done on ClusterCatalog level once and re-used.
  2. We install something directly (like future support for direct helm installation).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this was the intent. This is the certificate used to verify the connection to the image-registry from which we get the bundle. The certificate can't be part of the catalog, as it may expire, and it could be an external repository or other location as you point out.

HOWEVER, this is optional, as the operator-controller will load the system certificates, and if the image registry's certificate is signed by a system certificate, then it's not necessary.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The more I think about this - the more I think we should not have this on ClusterExtension. Another reason - we do not specify specific catalog in ClusterExtension. If on ClusterExtension you say you want to install argocd-operator - it can come from any catalog installed on the cluster: it might come from a catalog which uses an image registry where certs are issued by a public CA, but it might also come from a catalog which uses an image registry with a self-signed cert. We don't know on the ClusterExtension level.

I can totally see that some users are not going to know what to specific in registryTLS because they don't know how argocd-operator will resolve.

This is the certificate used to verify the connection to the image-registry from which we get the bundle.

I understand that. But whoever configures ClusterCatalog probably knows better about what image registries the catalog uses. So they can provide a ref to a relevant CA on ClusterCatalog level.

The certificate can't be part of the catalog, as it may expire, and it could be an external repository or other location as you point out.

Not sure that I'm following this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the certificate is part of the catalog metadata, it could easily become stale - especially if a separate image-registry is used. And as you point out, the argocd could come from any catalog, and subsequently any docker-registry.

Again, this is optional, and is intended for those specific docker-registries which may be private (e.g. our e2e docker-registries) or for which don't use a system certificate.

This should really be considered an exception, not the rule.

@joelanford, I believe it was your idea to add a certificate to the ClusterExtension, do you have an additional response?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the certificate is part of the catalog metadata

I'm not suggesting to put a certificate into catalog metadata. I'm suggesting to potentially do what you did for ClusterExtension, but for catalogd's ClusterCatalog API instead.

My idea is that people using ClusterExtension should not be forced to specify CA every time they install something on a cluster where self-signed certs are used. The cluster admins should be able to specify refs to secrets containing required CAs once (when adding a catalog to their cluster) and ClusterExtension API can remain the same.

What I suggest might also not be the right approach, but it is clear to me that we as a group need to spend some more time on the design for this.

This should really be considered an exception, not the rule.

If we provide this API - we and our users will be stuck with it for long time. We will have to support it and users will be forced to use it.

I agree with you - it won't affect people who use image registry with certs signed by public CAs. But it will result in a terrible user experience for people who install something on a cluster with self-signed certs. For them I see at least the following UX issues:

  1. They will have to specify registryTLS for every ClusterExtension.
  2. It is not clear what CA to specify on ClusterExtension. You have to know in advance how your package & version are going to resolve (is it going to use a registry with self-signed certs?). I think it is going to be more of a pain if people using ClusterExtension are not the same people configuring catalogs on the cluster.

IMO - we should either not support this use case at all or design so that we provide nice UX for all the use cases.

Let me know if you want to discuss this on a call. We should probably invite @joelanford as the author of the original idea.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I spoke with Joe Tuesday night and we are going to abandon the addition to the API for now and re-evaluate it later. This PR will still remove the annotations and fix the e2e to properly use certificates (and not use InsecureSkipTLSVerify).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good!

This PR will still remove the annotations and fix the e2e to properly use certificates

Could you please create a new PR for this instead? This one has quite a lot comments about the original registryTLS implementation. I think it will be easier to review in a fresh PR.

}

const (
Expand Down
42 changes: 41 additions & 1 deletion api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion cmd/manager/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,6 @@ func main() {
setupLog.Error(err, "unable to start manager")
os.Exit(1)
}

httpClient, err := httputil.BuildHTTPClient(caCert)
if err != nil {
setupLog.Error(err, "unable to create catalogd http client")
Expand Down Expand Up @@ -210,6 +209,7 @@ func main() {

if err = (&controllers.ClusterExtensionReconciler{
Client: cl,
Reader: mgr.GetAPIReader(),
tmshort marked this conversation as resolved.
Show resolved Hide resolved
BundleProvider: catalogClient,
ActionClientGetter: acg,
Unpacker: unpacker,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,30 @@ spec:
maxLength: 48
pattern: ^[a-z0-9]+(-[a-z0-9]+)*$
type: string
registryTLS:
description: RegistryTLS defines the connection parameters to retrieve
an image from a registry
properties:
certificateSecretRef:
description: |-
CertificateSecretRef references a Secret that contains the tls.crt certificate that
can verify the server certificate.
This fits the definition of NamespacedName (but that doesn't have json tags)
properties:
name:
description: Name of the secret
type: string
namespace:
description: Namespace of the secret
type: string
required:
- name
type: object
insecureSkipTLSVerify:
description: InsecureSkipTLSVerify allows the HTTPS client to
ignore the server certificate
type: boolean
type: object
upgradeConstraintPolicy:
default: Enforce
description: Defines the policy for how to handle upgrade constraints
Expand Down
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ require (
github.com/operator-framework/catalogd v0.14.0
github.com/operator-framework/helm-operator-plugins v0.2.2-0.20240520180534-f463c36fedf9
github.com/operator-framework/operator-registry v1.43.1
github.com/operator-framework/rukpak v0.23.1
github.com/operator-framework/rukpak v0.24.0
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.9.0
go.uber.org/zap v1.27.0
Expand Down Expand Up @@ -123,7 +123,7 @@ require (
github.com/google/btree v1.1.2 // indirect
github.com/google/cel-go v0.17.8 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-containerregistry v0.19.1 // indirect
github.com/google/go-containerregistry v0.19.2 // indirect
github.com/google/go-containerregistry/pkg/authn/k8schain v0.0.0-20240505154900-ff385a972813 // indirect
github.com/google/go-containerregistry/pkg/authn/kubernetes v0.0.0-20240505154900-ff385a972813 // indirect
github.com/google/gofuzz v1.2.0 // indirect
Expand Down Expand Up @@ -195,7 +195,7 @@ require (
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/skeema/knownhosts v1.2.2 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/cobra v1.8.0 // indirect
github.com/spf13/cobra v1.8.1 // indirect
github.com/stoewer/go-strcase v1.3.0 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect
Expand Down
14 changes: 7 additions & 7 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr
github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/cyphar/filepath-securejoin v0.2.5 h1:6iR5tXJ/e6tJZzzdMc1km3Sa7RRIVBKAK32O2s7AYfo=
Expand Down Expand Up @@ -305,8 +305,8 @@ github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-containerregistry v0.19.1 h1:yMQ62Al6/V0Z7CqIrrS1iYoA5/oQCm88DeNujc7C1KY=
github.com/google/go-containerregistry v0.19.1/go.mod h1:YCMFNQeeXeLF+dnhhWkqDItx/JSkH01j1Kis4PsjzFI=
github.com/google/go-containerregistry v0.19.2 h1:TannFKE1QSajsP6hPWb5oJNgKe1IKjHukIKDUmvsV6w=
github.com/google/go-containerregistry v0.19.2/go.mod h1:YCMFNQeeXeLF+dnhhWkqDItx/JSkH01j1Kis4PsjzFI=
github.com/google/go-containerregistry/pkg/authn/k8schain v0.0.0-20240505154900-ff385a972813 h1:PNR/Dkh697bQVCKLUekdd6LSNU9XkmXjrUbvH+wpfTg=
github.com/google/go-containerregistry/pkg/authn/k8schain v0.0.0-20240505154900-ff385a972813/go.mod h1:5UXYZJNyCPf2YD+6J76geTiLAXA8fJbDy7mGQa5m5Vc=
github.com/google/go-containerregistry/pkg/authn/kubernetes v0.0.0-20240505154900-ff385a972813 h1:irEChX0pAmED+6auieJELA0JKeCakr6iDCTLjJUiT8k=
Expand Down Expand Up @@ -483,8 +483,8 @@ github.com/operator-framework/operator-lib v0.14.0 h1:er+BgZymZD1im2wytLJiPLZpGA
github.com/operator-framework/operator-lib v0.14.0/go.mod h1:wUu4Xb9xzXnIpglvaZ3yucTMSlqGXHIoUEH9+5gWiu0=
github.com/operator-framework/operator-registry v1.43.1 h1:ACahVHGIL/hINBXd3RKWqSFR5SmSM6L5/n9xXqpR51s=
github.com/operator-framework/operator-registry v1.43.1/go.mod h1:qhssAIYWXDIW+nTg0C5i4iD9zpMtiXtfXqGUuUmGz5c=
github.com/operator-framework/rukpak v0.23.1 h1:lam6+wysaVjZVpMdtl7DUbc+8ibCdlCfp+nB62K0aSU=
github.com/operator-framework/rukpak v0.23.1/go.mod h1:DrQRNduAm0DWRSXpFhz8FA5g2GrJJ88sWpG5GiWmvPU=
github.com/operator-framework/rukpak v0.24.0 h1:zxLyk931w4isFiTPox4soXxh/eQJr5sjq15gHcb6dlE=
github.com/operator-framework/rukpak v0.24.0/go.mod h1:peTAGzf4gmU+in2RJen84ZQ8lkdB3m6qy+nfNiVv0RY=
github.com/otiai10/copy v1.14.0 h1:dCI/t1iTdYGtkvCuBG2BgR6KZa83PTclw4U5n2wAllU=
github.com/otiai10/copy v1.14.0/go.mod h1:ECfuL02W+/FkTWZWgQqXPWZgW9oeKCSQ5qVfSc4qc4w=
github.com/otiai10/mint v1.5.1 h1:XaPLeE+9vGbuyEHem1JNk3bYc7KKqyI/na0/mLd/Kks=
Expand Down Expand Up @@ -552,8 +552,8 @@ github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs=
Expand Down
57 changes: 46 additions & 11 deletions internal/controllers/clusterextension_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import (
"helm.sh/helm/v3/pkg/postrender"
"helm.sh/helm/v3/pkg/release"
"helm.sh/helm/v3/pkg/storage/driver"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/equality"
apimeta "k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -79,6 +80,7 @@ import (
// ClusterExtensionReconciler reconciles a ClusterExtension object
type ClusterExtensionReconciler struct {
client.Client
client.Reader
BundleProvider BundleProvider
Unpacker rukpaksource.Unpacker
ActionClientGetter helmclient.ActionClientGetter
Expand All @@ -96,10 +98,6 @@ type InstalledBundleGetter interface {
GetInstalledBundle(ctx context.Context, ext *ocv1alpha1.ClusterExtension) (*ocv1alpha1.BundleMetadata, error)
}

const (
bundleConnectionAnnotation string = "bundle.connection.config/insecureSkipTLSVerify"
)

//+kubebuilder:rbac:groups=olm.operatorframework.io,resources=clusterextensions,verbs=get;list;watch
//+kubebuilder:rbac:groups=olm.operatorframework.io,resources=clusterextensions/status,verbs=update;patch
//+kubebuilder:rbac:groups=olm.operatorframework.io,resources=clusterextensions/finalizers,verbs=update
Expand Down Expand Up @@ -249,7 +247,7 @@ func (r *ClusterExtensionReconciler) reconcile(ctx context.Context, ext *ocv1alp
// Generate a BundleDeployment from the ClusterExtension to Unpack.
// Note: The BundleDeployment here is not a k8s API, its a simple Go struct which
// necessary embedded values.
bd := r.generateBundleDeploymentForUnpack(bundle.Image, ext)
bd := r.generateBundleDeploymentForUnpack(ctx, bundle.Image, ext)
unpackResult, err := r.Unpacker.Unpack(ctx, bd)
if err != nil {
setStatusUnpackFailed(ext, err.Error())
Expand Down Expand Up @@ -533,7 +531,11 @@ func SetDeprecationStatus(ext *ocv1alpha1.ClusterExtension, bundle *catalogmetad
}
}

func (r *ClusterExtensionReconciler) generateBundleDeploymentForUnpack(bundlePath string, ce *ocv1alpha1.ClusterExtension) *rukpakv1alpha2.BundleDeployment {
func (r *ClusterExtensionReconciler) generateBundleDeploymentForUnpack(ctx context.Context, bundlePath string, ce *ocv1alpha1.ClusterExtension) *rukpakv1alpha2.BundleDeployment {
certData, err := r.getCertificateData(ctx, ce)
if err != nil {
log.FromContext(ctx).WithName("operator-controller").WithValues("cluster-extension", ce.GetName()).Error(err, "unable to get TLS certificate")
}
return &rukpakv1alpha2.BundleDeployment{
TypeMeta: metav1.TypeMeta{
Kind: ce.Kind,
Expand All @@ -550,21 +552,54 @@ func (r *ClusterExtensionReconciler) generateBundleDeploymentForUnpack(bundlePat
Image: &rukpakv1alpha2.ImageSource{
Ref: bundlePath,
InsecureSkipTLSVerify: isInsecureSkipTLSVerifySet(ce),
CertificateData: certData,
},
},
},
}
}

func isInsecureSkipTLSVerifySet(ce *ocv1alpha1.ClusterExtension) bool {
if ce == nil {
if ce == nil || ce.Spec.RegistryTLS == nil {
return false
}
value, ok := ce.Annotations[bundleConnectionAnnotation]
if !ok {
return false
return ce.Spec.RegistryTLS.InsecureSkipTLSVerify
}

func (r *ClusterExtensionReconciler) getCertificateData(ctx context.Context, ce *ocv1alpha1.ClusterExtension) (string, error) {
if ce == nil || ce.Spec.RegistryTLS == nil || ce.Spec.RegistryTLS.CertificateSecretRef == nil {
return "", nil
tmshort marked this conversation as resolved.
Show resolved Hide resolved
}
secretName := getNamespacedName(*ce.Spec.RegistryTLS.CertificateSecretRef)
var secret = &corev1.Secret{}
if err := r.Reader.Get(ctx, secretName, secret); err != nil {
return "", fmt.Errorf("unable to get secret %v: %w", secretName, err)
}
tmshort marked this conversation as resolved.
Show resolved Hide resolved
if secret.Type != corev1.SecretTypeTLS {
return "", fmt.Errorf("invalid type in secret %v: %v", secretName, secret.Type)
}
var certs []string
// Get any 'ca.crt'
data, ok := secret.Data[corev1.ServiceAccountRootCAKey]
if ok && len(data) > 0 {
certs = append(certs, string(data))
}
// Get any 'tls.crt'
data, ok = secret.Data[corev1.TLSCertKey]
if ok && len(data) > 0 {
certs = append(certs, string(data))
}
if len(certs) == 0 {
return "", fmt.Errorf("no data found in secret: %v", secretName)
}
return strings.Join(certs, "\n"), nil
}

func getNamespacedName(name ocv1alpha1.ClusterExtensionSecretRef) types.NamespacedName {
if name.Namespace == "" {
return types.NamespacedName{Namespace: "default", Name: name.Name}
}
return value == "true"
return types.NamespacedName{Namespace: name.Namespace, Name: name.Name}
}

// SetupWithManager sets up the controller with the Manager.
Expand Down
16 changes: 13 additions & 3 deletions test/e2e/cluster_extension_install_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,18 @@ func testInit(t *testing.T) (*ocv1alpha1.ClusterExtension, *catalogd.ClusterCata
clusterExtension := &ocv1alpha1.ClusterExtension{
ObjectMeta: metav1.ObjectMeta{
Name: clusterExtensionName,
Annotations: map[string]string{
"bundle.connection.config/insecureSkipTLSVerify": "true",
},
},
}
return clusterExtension, extensionCatalog
}
func addCertToSpec(ce *ocv1alpha1.ClusterExtension) {
ce.Spec.RegistryTLS = &ocv1alpha1.ClusterExtensionTLS{
CertificateSecretRef: &ocv1alpha1.ClusterExtensionSecretRef{
Name: "operator-controller-e2e-registry",
Namespace: "operator-controller-e2e",
},
}
}

func testCleanup(t *testing.T, cat *catalogd.ClusterCatalog, clusterExtension *ocv1alpha1.ClusterExtension) {
require.NoError(t, c.Delete(context.Background(), cat))
Expand All @@ -78,6 +83,7 @@ func TestClusterExtensionInstallRegistry(t *testing.T) {
PackageName: "prometheus",
InstallNamespace: "default",
}
addCertToSpec(clusterExtension)
t.Log("It resolves the specified package with correct bundle path")
t.Log("By creating the ClusterExtension resource")
require.NoError(t, c.Create(context.Background(), clusterExtension))
Expand Down Expand Up @@ -135,6 +141,7 @@ func TestClusterExtensionInstallReResolvesWhenNewCatalog(t *testing.T) {
PackageName: pkgName,
InstallNamespace: "default",
}
addCertToSpec(clusterExtension)

t.Log("By deleting the catalog first")
require.NoError(t, c.Delete(context.Background(), extensionCatalog))
Expand Down Expand Up @@ -202,6 +209,7 @@ func TestClusterExtensionBlockInstallNonSuccessorVersion(t *testing.T) {
Version: "1.0.0",
InstallNamespace: "default",
}
addCertToSpec(clusterExtension)
require.NoError(t, c.Create(context.Background(), clusterExtension))
t.Log("By eventually reporting a successful installation")
require.EventuallyWithT(t, func(ct *assert.CollectT) {
Expand Down Expand Up @@ -248,6 +256,7 @@ func TestClusterExtensionForceInstallNonSuccessorVersion(t *testing.T) {
Version: "1.0.0",
InstallNamespace: "default",
}
addCertToSpec(clusterExtension)
require.NoError(t, c.Create(context.Background(), clusterExtension))
t.Log("By eventually reporting a successful resolution")
require.EventuallyWithT(t, func(ct *assert.CollectT) {
Expand Down Expand Up @@ -293,6 +302,7 @@ func TestClusterExtensionInstallSuccessorVersion(t *testing.T) {
Version: "1.0.0",
InstallNamespace: "default",
}
addCertToSpec(clusterExtension)
require.NoError(t, c.Create(context.Background(), clusterExtension))
t.Log("By eventually reporting a successful resolution")
require.EventuallyWithT(t, func(ct *assert.CollectT) {
Expand Down
Loading