Fix #1771: use registry creds for pull and push
diff --git a/docs/modules/ROOT/nav.adoc b/docs/modules/ROOT/nav.adoc
index ef1ff50..73aaaca 100644
--- a/docs/modules/ROOT/nav.adoc
+++ b/docs/modules/ROOT/nav.adoc
@@ -1,10 +1,12 @@
* xref:installation/installation.adoc[Installation]
** xref:installation/minikube.adoc[Minikube]
** xref:installation/minishift.adoc[Minishift]
+** xref:installation/digitalocean.adoc[DigitalOcean Kubernetes Cluster]
** xref:installation/gke.adoc[Google Kubernetes Engine (GKE)]
** xref:installation/openshift.adoc[OpenShift]
** xref:installation/iks.adoc[IBM Kubernetes Service (IKS)]
** xref:installation/registry/registry.adoc[Configuring Registry]
+*** xref:installation/registry/digitalocean.adoc[DigitalOcean]
*** xref:installation/registry/dockerhub.adoc[Docker Hub]
*** xref:installation/registry/github.adoc[Github Packages]
*** xref:installation/registry/gcr.adoc[Gcr.io]
diff --git a/docs/modules/ROOT/pages/installation/digitalocean.adoc b/docs/modules/ROOT/pages/installation/digitalocean.adoc
new file mode 100644
index 0000000..42bad62
--- /dev/null
+++ b/docs/modules/ROOT/pages/installation/digitalocean.adoc
@@ -0,0 +1,8 @@
+[[installation-on-digitalocean]]
+= Installing Camel K on DigitalOcean
+
+This guide assumes you've already created a Kubernetes Engine cluster on https://digitalocean.com.
+
+To install Camel K on a DigitalOcean Kubernetes cluster, just to xref:installation/registry/digitalocean.adoc[configure the DigitalOcen container registry] during installation.
+
+After doing that, you'll be ready to play with Camel K. Enjoy!
diff --git a/docs/modules/ROOT/pages/installation/registry/digitalocean.adoc b/docs/modules/ROOT/pages/installation/registry/digitalocean.adoc
new file mode 100644
index 0000000..58b2e04
--- /dev/null
+++ b/docs/modules/ROOT/pages/installation/registry/digitalocean.adoc
@@ -0,0 +1,17 @@
+[[configuring-registry-digitalocean]]
+= Configuring a DigitalOcean Container Registry
+
+You can host your container images on the Digital Ocean container registry in case your cluster doesn't provide a xref:installation/registry/registry.adoc[default registry].
+
+After logging in into the DigitalOcean web console on https://www.digitalocean.com/, access the *registry page* to do the following actions:
+
+- Take note of the registry address and organization: you should find something like `registry.digitalocean.com/<your-org-id>`
+- Download the "Docker Credentials" for the registry for **"Read & Write"**: this will save a file named `docker-config.json` in your machine
+
+[source,bash]
+----
+# make sure you set the right organization parameter
+kamel install --registry registry.digitalocean.com --organization your-org-id --registry-auth-file docker-config.json
+----
+
+Have fun with Camel K!
diff --git a/docs/modules/ROOT/pages/installation/registry/gcr.adoc b/docs/modules/ROOT/pages/installation/registry/gcr.adoc
index 3f1e3b6..5c6f289 100644
--- a/docs/modules/ROOT/pages/installation/registry/gcr.adoc
+++ b/docs/modules/ROOT/pages/installation/registry/gcr.adoc
@@ -29,7 +29,7 @@
You should now execute the following command to install cluster resources and the operator (in the current namespace):
```
-kamel install --registry gcr.io --organization <<your-project-id>> --registry-secret kaniko-secret
+kamel install --build-publish-strategy=Kaniko --registry gcr.io --organization <<your-project-id>> --registry-secret kaniko-secret
```
Use the project id of your project on GKE. Usually this can be obtained from the connection string.
diff --git a/pkg/builder/spectrum/publisher.go b/pkg/builder/spectrum/publisher.go
index fbae10e..a50fd4e 100644
--- a/pkg/builder/spectrum/publisher.go
+++ b/pkg/builder/spectrum/publisher.go
@@ -79,6 +79,7 @@
options := spectrum.Options{
PullInsecure: pullInsecure,
PushInsecure: pl.Status.Build.Registry.Insecure,
+ PullConfigDir: registryConfigDir,
PushConfigDir: registryConfigDir,
Base: ctx.BaseImage,
Target: target,
diff --git a/pkg/cmd/install.go b/pkg/cmd/install.go
index 403b5d8..9a112aa 100644
--- a/pkg/cmd/install.go
+++ b/pkg/cmd/install.go
@@ -84,6 +84,7 @@
cmd.Flags().String("registry", "", "A Docker registry that can be used to publish images")
cmd.Flags().String("registry-secret", "", "A secret used to push/pull images to the Docker registry")
cmd.Flags().Bool("registry-insecure", false, "Configure to configure registry access in insecure mode or not")
+ cmd.Flags().String("registry-auth-file", "", "A docker registry configuration file containing authorization tokens for pushing and pulling images")
cmd.Flags().String("registry-auth-server", "", "The docker registry authentication server")
cmd.Flags().String("registry-auth-username", "", "The docker registry authentication username")
cmd.Flags().String("registry-auth-password", "", "The docker registry authentication password")
@@ -171,9 +172,11 @@
TraitProfile string `mapstructure:"trait-profile"`
HTTPProxySecret string `mapstructure:"http-proxy-secret"`
- registry v1.IntegrationPlatformRegistrySpec
- registryAuth registry.Auth
- olmOptions olm.Options
+ registry v1.IntegrationPlatformRegistrySpec
+ registryAuth registry.Auth
+ RegistryAuthFile string `mapstructure:"registry-auth-file"`
+
+ olmOptions olm.Options
}
// nolint: gocyclo
@@ -280,6 +283,11 @@
if err != nil {
return err
}
+ } else if o.RegistryAuthFile != "" {
+ generatedSecretName, err = install.RegistrySecretFromFileOrCollect(o.Context, c, namespace, o.RegistryAuthFile, collection, o.Force)
+ if err != nil {
+ return err
+ }
}
platform, err := install.PlatformOrCollect(o.Context, c, o.ClusterType, namespace, o.registry, collection)
@@ -507,11 +515,25 @@
}
}
- if o.registry.Secret != "" && o.registryAuth.IsSet() {
+ if o.registry.Secret != "" && (o.registryAuth.IsSet() || o.RegistryAuthFile != "") {
err := fmt.Errorf("incompatible options combinations: you cannot set both registry-secret and registry-auth-[*] settings")
result = multierr.Append(result, err)
}
+ if o.registryAuth.IsSet() && o.RegistryAuthFile != "" {
+ err := fmt.Errorf("incompatible options combinations: you cannot set registry-auth-file with other registry-auth-[*] settings")
+ result = multierr.Append(result, err)
+ }
+
+ if o.RegistryAuthFile != "" {
+ nfo, err := os.Stat(o.RegistryAuthFile)
+ if err != nil {
+ result = multierr.Append(result, err)
+ } else if nfo.IsDir() {
+ result = multierr.Append(result, errors.Wrapf(err, "registry file cannot be a directory: %s", o.RegistryAuthFile))
+ }
+ }
+
if o.BuildStrategy != "" {
found := false
for _, s := range v1.IntegrationPlatformBuildStrategies {
diff --git a/pkg/install/secret.go b/pkg/install/secret.go
index 70a7536..9fe4fc5 100644
--- a/pkg/install/secret.go
+++ b/pkg/install/secret.go
@@ -19,6 +19,7 @@
import (
"context"
+ "io/ioutil"
"github.com/apache/camel-k/pkg/client"
"github.com/apache/camel-k/pkg/util/kubernetes"
@@ -36,6 +37,21 @@
return "", err
}
+ return registrySecretFromDataOrCollect(ctx, c, namespace, secretData, collection, force)
+}
+
+// RegistrySecretFromFileOrCollect generates a secret from a docker-config.json file and creates it on the cluster (or appends it to the collection)
+func RegistrySecretFromFileOrCollect(ctx context.Context, c client.Client, namespace string, file string, collection *kubernetes.Collection, force bool) (string, error) {
+ secretData, err := ioutil.ReadFile(file)
+ if err != nil {
+ return "", err
+ }
+
+ return registrySecretFromDataOrCollect(ctx, c, namespace, secretData, collection, force)
+}
+
+// registrySecretFromDataOrCollect generates a secret from a docker config file content file and creates it on the cluster (or appends it to the collection)
+func registrySecretFromDataOrCollect(ctx context.Context, c client.Client, namespace string, secretData []byte, collection *kubernetes.Collection, force bool) (string, error) {
registrySecret := v1.Secret{
TypeMeta: metav1.TypeMeta{
Kind: "Secret",
diff --git a/pkg/platform/defaults.go b/pkg/platform/defaults.go
index c072152..5e83379 100644
--- a/pkg/platform/defaults.go
+++ b/pkg/platform/defaults.go
@@ -70,15 +70,18 @@
if p.Status.Cluster == v1.IntegrationPlatformClusterOpenShift {
p.Status.Build.PublishStrategy = v1.IntegrationPlatformBuildPublishStrategyS2I
} else {
- p.Status.Build.PublishStrategy = v1.IntegrationPlatformBuildPublishStrategyBuildah
+ p.Status.Build.PublishStrategy = v1.IntegrationPlatformBuildPublishStrategySpectrum
}
}
if p.Status.Build.BuildStrategy == "" {
// If the operator is global, a global build strategy should be used
if IsCurrentOperatorGlobal() {
- // The only global strategy we have for now
- p.Status.Build.BuildStrategy = v1.IntegrationPlatformBuildStrategyPod
+ if p.Status.Build.PublishStrategy == v1.IntegrationPlatformBuildPublishStrategySpectrum {
+ p.Status.Build.BuildStrategy = v1.IntegrationPlatformBuildStrategyRoutine
+ } else {
+ p.Status.Build.BuildStrategy = v1.IntegrationPlatformBuildStrategyPod
+ }
} else {
if p.Status.Build.PublishStrategy == v1.IntegrationPlatformBuildPublishStrategyS2I ||
p.Status.Build.PublishStrategy == v1.IntegrationPlatformBuildPublishStrategySpectrum {