Skip to content

Commit

Permalink
Use existing Docker credentials for pushing images (kyma-project#511)
Browse files Browse the repository at this point in the history
  • Loading branch information
Suleyman Akbas authored Jul 21, 2020
1 parent befddd4 commit ce35f37
Show file tree
Hide file tree
Showing 30 changed files with 235 additions and 158 deletions.
6 changes: 1 addition & 5 deletions cmd/kyma/install/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,7 @@ The standard installation uses the minimal configuration. The system performs th
cobraCmd.Flags().StringArrayVarP(&o.OverrideConfigs, "override", "o", nil, "Path to a YAML file with parameters to override.")
cobraCmd.Flags().StringVarP(&o.ComponentsConfig, "components", "c", "", "Path to a YAML file with component list to override.")
cobraCmd.Flags().IntVar(&o.FallbackLevel, "fallbackLevel", 5, `If "source=latest-published", defines the number of commits from master branch taken into account if artifacts for newer commits do not exist yet`)
cobraCmd.Flags().StringVarP(&o.DockerUsername, "docker-username", "", "", "Docker username to push the custom image. Used only for installation from local sources to a remote cluster.")
cobraCmd.Flags().StringVarP(&o.DockerPassword, "docker-password", "", "", "Docker password to push the custom image. Used only for installation from local sources to a remote cluster.")
cobraCmd.Flags().StringVarP(&o.CustomImage, "custom-image", "", "", "Full image name including the registry and the tag. Used only for installation from local sources to a remote cluster.")
cobraCmd.Flags().StringVarP(&o.CustomImage, "custom-image", "", "", "Full image name including the registry and the tag. Required for installation from local sources to a remote cluster.")
return cobraCmd
}

Expand Down Expand Up @@ -162,8 +160,6 @@ func (cmd *command) configureInstallation(clusterConfig installation.ClusterInfo
Timeout: cmd.opts.Timeout,
KubeconfigPath: cmd.opts.KubeconfigPath,
CustomImage: cmd.opts.CustomImage,
DockerUsername: cmd.opts.DockerUsername,
DockerPassword: cmd.opts.DockerPassword,
Domain: cmd.opts.Domain,
TLSCert: cmd.opts.TLSCert,
TLSKey: cmd.opts.TLSKey,
Expand Down
2 changes: 0 additions & 2 deletions cmd/kyma/install/opts.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ type Options struct {
Source string
FallbackLevel int
CustomImage string
DockerUsername string
DockerPassword string
}

//NewOptions creates options with default values
Expand Down
2 changes: 1 addition & 1 deletion docs/gen-docs/kyma.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@ For more information, see: https://github.com/kyma-project/cli
* [kyma upgrade](kyma_upgrade.md) - Upgrades Kyma to match the CLI version.
* [kyma version](kyma_version.md) - Displays the version of Kyma CLI and the connected Kyma cluster.

###### Auto generated by spf13/cobra on 15-Jul-2020
###### Auto generated by spf13/cobra on 21-Jul-2020
2 changes: 1 addition & 1 deletion docs/gen-docs/kyma_completion.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ kyma completion bash|zsh [flags]

* [kyma](kyma.md) - Controls a Kyma cluster.

###### Auto generated by spf13/cobra on 15-Jul-2020
###### Auto generated by spf13/cobra on 21-Jul-2020
2 changes: 1 addition & 1 deletion docs/gen-docs/kyma_console.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ kyma console [flags]

* [kyma](kyma.md) - Controls a Kyma cluster.

###### Auto generated by spf13/cobra on 15-Jul-2020
###### Auto generated by spf13/cobra on 21-Jul-2020
40 changes: 19 additions & 21 deletions docs/gen-docs/kyma_install.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,26 +45,24 @@ kyma install [flags]
### Options

```
-c, --components string Path to a YAML file with component list to override.
--custom-image string Full image name including the registry and the tag. Used only for installation from local sources to a remote cluster.
--docker-password string Docker password to push the custom image. Used only for installation from local sources to a remote cluster.
--docker-username string Docker username to push the custom image. Used only for installation from local sources to a remote cluster.
-d, --domain string Domain used for installation. (default "kyma.local")
--fallbackLevel int If "source=latest-published", defines the number of commits from master branch taken into account if artifacts for newer commits do not exist yet (default 5)
-n, --noWait Flag that determines if the command should wait for Kyma installation to complete.
-o, --override stringArray Path to a YAML file with parameters to override.
-p, --password string Predefined cluster password.
-s, --source string Installation source.
- To use the specific release, write "kyma install --source=1.3.0".
- To use the latest master, write "kyma install --source=latest".
- To use the latest published master, which is the latest commit with released images, write "kyma install --source=latest-published".
- To use a commit, write "kyma install --source=34edf09a".
- To use the local sources, write "kyma install --source=local".
- To use a custom installer image, write kyma "install --source=user/my-kyma-installer:v1.4.0".
--src-path string Absolute path to local sources.
--timeout duration Time-out after which CLI stops watching the installation progress. (default 1h0m0s)
--tlsCert string TLS certificate for the domain used for installation. The certificate must be a base64-encoded value.
--tlsKey string TLS key for the domain used for installation. The key must be a base64-encoded value.
-c, --components string Path to a YAML file with component list to override.
--custom-image string Full image name including the registry and the tag. Required for installation from local sources to a remote cluster.
-d, --domain string Domain used for installation. (default "kyma.local")
--fallbackLevel int If "source=latest-published", defines the number of commits from master branch taken into account if artifacts for newer commits do not exist yet (default 5)
-n, --noWait Flag that determines if the command should wait for Kyma installation to complete.
-o, --override stringArray Path to a YAML file with parameters to override.
-p, --password string Predefined cluster password.
-s, --source string Installation source.
- To use the specific release, write "kyma install --source=1.3.0".
- To use the latest master, write "kyma install --source=latest".
- To use the latest published master, which is the latest commit with released images, write "kyma install --source=latest-published".
- To use a commit, write "kyma install --source=34edf09a".
- To use the local sources, write "kyma install --source=local".
- To use a custom installer image, write kyma "install --source=user/my-kyma-installer:v1.4.0".
--src-path string Absolute path to local sources.
--timeout duration Time-out after which CLI stops watching the installation progress. (default 1h0m0s)
--tlsCert string TLS certificate for the domain used for installation. The certificate must be a base64-encoded value.
--tlsKey string TLS key for the domain used for installation. The key must be a base64-encoded value.
```

### Options inherited from parent commands
Expand All @@ -81,4 +79,4 @@ kyma install [flags]

* [kyma](kyma.md) - Controls a Kyma cluster.

###### Auto generated by spf13/cobra on 15-Jul-2020
###### Auto generated by spf13/cobra on 21-Jul-2020
2 changes: 1 addition & 1 deletion docs/gen-docs/kyma_provision.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ Provisions a cluster for Kyma installation.
* [kyma provision gke](kyma_provision_gke.md) - Provisions a Google Kubernetes Engine (GKE) cluster on Google Cloud Platform (GCP).
* [kyma provision minikube](kyma_provision_minikube.md) - Provisions Minikube.

###### Auto generated by spf13/cobra on 15-Jul-2020
###### Auto generated by spf13/cobra on 21-Jul-2020
2 changes: 1 addition & 1 deletion docs/gen-docs/kyma_provision_aks.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,4 @@ kyma provision aks [flags]

* [kyma provision](kyma_provision.md) - Provisions a cluster for Kyma installation.

###### Auto generated by spf13/cobra on 15-Jul-2020
###### Auto generated by spf13/cobra on 21-Jul-2020
2 changes: 1 addition & 1 deletion docs/gen-docs/kyma_provision_gardener.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ Provisions a cluster using Gardener on GCP, Azure, or AWS.
* [kyma provision gardener az](kyma_provision_gardener_az.md) - Provisions a Kubernetes cluster using Gardener on Azure.
* [kyma provision gardener gcp](kyma_provision_gardener_gcp.md) - Provisions a Kubernetes cluster using Gardener on Google Cloud Platform (GCP).

###### Auto generated by spf13/cobra on 15-Jul-2020
###### Auto generated by spf13/cobra on 21-Jul-2020
2 changes: 1 addition & 1 deletion docs/gen-docs/kyma_provision_gardener_aws.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,4 @@ kyma provision gardener aws [flags]

* [kyma provision gardener](kyma_provision_gardener.md) - Provisions a cluster using Gardener on GCP, Azure, or AWS.

###### Auto generated by spf13/cobra on 15-Jul-2020
###### Auto generated by spf13/cobra on 21-Jul-2020
2 changes: 1 addition & 1 deletion docs/gen-docs/kyma_provision_gardener_az.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,4 @@ kyma provision gardener az [flags]

* [kyma provision gardener](kyma_provision_gardener.md) - Provisions a cluster using Gardener on GCP, Azure, or AWS.

###### Auto generated by spf13/cobra on 15-Jul-2020
###### Auto generated by spf13/cobra on 21-Jul-2020
2 changes: 1 addition & 1 deletion docs/gen-docs/kyma_provision_gardener_gcp.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,4 @@ kyma provision gardener gcp [flags]

* [kyma provision gardener](kyma_provision_gardener.md) - Provisions a cluster using Gardener on GCP, Azure, or AWS.

###### Auto generated by spf13/cobra on 15-Jul-2020
###### Auto generated by spf13/cobra on 21-Jul-2020
2 changes: 1 addition & 1 deletion docs/gen-docs/kyma_provision_gke.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,4 @@ kyma provision gke [flags]

* [kyma provision](kyma_provision.md) - Provisions a cluster for Kyma installation.

###### Auto generated by spf13/cobra on 15-Jul-2020
###### Auto generated by spf13/cobra on 21-Jul-2020
2 changes: 1 addition & 1 deletion docs/gen-docs/kyma_provision_minikube.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,4 @@ kyma provision minikube [flags]

* [kyma provision](kyma_provision.md) - Provisions a cluster for Kyma installation.

###### Auto generated by spf13/cobra on 15-Jul-2020
###### Auto generated by spf13/cobra on 21-Jul-2020
2 changes: 1 addition & 1 deletion docs/gen-docs/kyma_test.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ Use this command to run tests on a provisioned Kyma cluster.
* [kyma test run](kyma_test_run.md) - Runs tests on a Kyma cluster.
* [kyma test status](kyma_test_status.md) - Shows the status of a test suite and related test executions.

###### Auto generated by spf13/cobra on 15-Jul-2020
###### Auto generated by spf13/cobra on 21-Jul-2020
2 changes: 1 addition & 1 deletion docs/gen-docs/kyma_test_definitions.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ kyma test definitions [flags]

* [kyma test](kyma_test.md) - Runs tests on a provisioned Kyma cluster.

###### Auto generated by spf13/cobra on 15-Jul-2020
###### Auto generated by spf13/cobra on 21-Jul-2020
2 changes: 1 addition & 1 deletion docs/gen-docs/kyma_test_delete.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ kyma test delete <test-suite-1> <test-suite-2> ... <test-suite-N> [flags]

* [kyma test](kyma_test.md) - Runs tests on a provisioned Kyma cluster.

###### Auto generated by spf13/cobra on 15-Jul-2020
###### Auto generated by spf13/cobra on 21-Jul-2020
2 changes: 1 addition & 1 deletion docs/gen-docs/kyma_test_list.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ kyma test list [flags]

* [kyma test](kyma_test.md) - Runs tests on a provisioned Kyma cluster.

###### Auto generated by spf13/cobra on 15-Jul-2020
###### Auto generated by spf13/cobra on 21-Jul-2020
2 changes: 1 addition & 1 deletion docs/gen-docs/kyma_test_logs.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,4 @@ kyma test logs <test-suite-1> <test-suite-2> ... <test-suite-N> [flags]

* [kyma test](kyma_test.md) - Runs tests on a provisioned Kyma cluster.

###### Auto generated by spf13/cobra on 15-Jul-2020
###### Auto generated by spf13/cobra on 21-Jul-2020
2 changes: 1 addition & 1 deletion docs/gen-docs/kyma_test_run.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,4 @@ kyma test run <test-definition-1> <test-definition-2> ... <test-definition-N> [f

* [kyma test](kyma_test.md) - Runs tests on a provisioned Kyma cluster.

###### Auto generated by spf13/cobra on 15-Jul-2020
###### Auto generated by spf13/cobra on 21-Jul-2020
2 changes: 1 addition & 1 deletion docs/gen-docs/kyma_test_status.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,4 @@ kyma test status <test-suite-1> <test-suite-2> ... <test-suite-N> [flags]

* [kyma test](kyma_test.md) - Runs tests on a provisioned Kyma cluster.

###### Auto generated by spf13/cobra on 15-Jul-2020
###### Auto generated by spf13/cobra on 21-Jul-2020
2 changes: 1 addition & 1 deletion docs/gen-docs/kyma_upgrade.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ kyma upgrade [flags]

* [kyma](kyma.md) - Controls a Kyma cluster.

###### Auto generated by spf13/cobra on 15-Jul-2020
###### Auto generated by spf13/cobra on 21-Jul-2020
2 changes: 1 addition & 1 deletion docs/gen-docs/kyma_version.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ kyma version [flags]

* [kyma](kyma.md) - Controls a Kyma cluster.

###### Auto generated by spf13/cobra on 15-Jul-2020
###### Auto generated by spf13/cobra on 21-Jul-2020
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ require (
github.com/containerd/containerd v1.3.0 // indirect
github.com/containerd/continuity v0.0.0-20200228182428-0f16d7a0959c // indirect
github.com/daviddengcn/go-colortext v0.0.0-20180409174941-186a3d44e920
github.com/docker/cli v0.0.0-20190925022749-754388324470
github.com/docker/distribution v2.7.1+incompatible // indirect
github.com/docker/docker v1.4.2-0.20191101170500-ac7306503d23
github.com/docker/docker-credential-helpers v0.6.3 // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/fatih/color v1.7.0
github.com/gogo/protobuf v1.3.1 // indirect
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,15 @@ github.com/dimchansky/utfbom v1.0.0 h1:fGC2kkf4qOoKqZ4q7iIh+Vef4ubC1c38UDsEyZynZ
github.com/dimchansky/utfbom v1.0.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
github.com/dnaeon/go-vcr v0.0.0-20180920040454-5637cf3d8a31 h1:Dzuw9GtbmllUqEcoHfScT9YpKFUssSiZ5PgZkIGf/YQ=
github.com/dnaeon/go-vcr v0.0.0-20180920040454-5637cf3d8a31/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
github.com/docker/cli v0.0.0-20190925022749-754388324470 h1:KrSeY2qJPl1blFLllwCMBIgwilomqEte/nb8dPhqY2o=
github.com/docker/cli v0.0.0-20190925022749-754388324470/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v1.4.2-0.20191101170500-ac7306503d23 h1:oqgGT9O61YAYvI41EBsLePOr+LE6roB0xY4gpkZuFSE=
github.com/docker/docker v1.4.2-0.20191101170500-ac7306503d23/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.6.3 h1:zI2p9+1NQYdnG6sMU26EX4aVGlqbInSQxQXLvzJ4RPQ=
github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
Expand Down
163 changes: 163 additions & 0 deletions pkg/installation/docker.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
package installation

import (
"bufio"
"context"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"os"
"path"
"strings"
"time"

dockerConfig "github.com/docker/cli/cli/config"
configTypes "github.com/docker/cli/cli/config/types"
"github.com/docker/docker/api/types"
docker "github.com/docker/docker/client"
"github.com/docker/docker/pkg/archive"
"github.com/kyma-project/cli/internal/minikube"
)

const (
defaultRegistry = "index.docker.io"
)

// DockerErrorMessage is used to parse error messages coming from Docker
type DockerErrorMessage struct {
Error string
}

func (i *Installation) buildKymaInstaller(imageName string) error {
var dc *docker.Client
var err error
if i.Options.IsLocal {
dc, err = minikube.DockerClient(i.Options.Verbose, i.Options.LocalCluster.Profile, i.Options.Timeout)
} else {
dc, err = docker.NewClientWithOpts(docker.FromEnv)
}
if err != nil {
return err
}

reader, err := archive.TarWithOptions(i.Options.LocalSrcPath, &archive.TarOptions{})
if err != nil {
return err
}

ctx, cancel := context.WithTimeout(context.Background(), time.Duration(300)*time.Second)
defer cancel()

dc.NegotiateAPIVersion(ctx)

args := make(map[string]*string)
_, err = dc.ImageBuild(
ctx,
reader,
types.ImageBuildOptions{
Tags: []string{strings.TrimSpace(string(imageName))},
SuppressOutput: true,
Remove: true,
Dockerfile: path.Join("tools", "kyma-installer", "kyma.Dockerfile"),
BuildArgs: args,
},
)
if err != nil {
return err
}

return nil
}

func (i *Installation) pushKymaInstaller() error {
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(300)*time.Second)
defer cancel()

dc, err := docker.NewClientWithOpts(docker.FromEnv)
if err != nil {
return err
}

dc.NegotiateAPIVersion(ctx)

domain, _ := splitDockerDomain(i.Options.CustomImage)
auth, err := resolve(domain)
if err != nil {
return err
}

encodedJSON, err := json.Marshal(auth)
if err != nil {
return err
}
authStr := base64.URLEncoding.EncodeToString(encodedJSON)

pusher, err := dc.ImagePush(ctx, i.Options.CustomImage, types.ImagePushOptions{RegistryAuth: authStr})
if err != nil {
return err
}

defer pusher.Close()

var errorMessage DockerErrorMessage
buffIOReader := bufio.NewReader(pusher)

for {
streamBytes, err := buffIOReader.ReadBytes('\n')
if err == io.EOF {
break
}
err = json.Unmarshal(streamBytes, &errorMessage)
if err != nil {
return err
}
if errorMessage.Error != "" {
if strings.Contains(errorMessage.Error, "unauthorized") || strings.Contains(errorMessage.Error, "requested access to the resource is denied") {
return fmt.Errorf("failed to push Docker image: %s\nPlease run `docker login`", errorMessage.Error)
}
return fmt.Errorf("failed to push Docker image: %s", errorMessage.Error)
}
}

return nil
}

func splitDockerDomain(name string) (domain, remainder string) {
i := strings.IndexRune(name, '/')
if i == -1 || (!strings.ContainsAny(name[:i], ".:") && name[:i] != "localhost") {
domain, remainder = defaultRegistry, name
} else {
domain, remainder = name[:i], name[i+1:]
}
return
}

// resolve finds the Docker credentials to push an image.
func resolve(registry string) (*configTypes.AuthConfig, error) {
cf, err := dockerConfig.Load(os.Getenv("DOCKER_CONFIG"))
if err != nil {
return nil, err
}

if registry == defaultRegistry {
registry = "https://" + defaultRegistry + "/v1/"
}

cfg, err := cf.GetAuthConfig(registry)
if err != nil {
return nil, err
}

empty := configTypes.AuthConfig{}
if cfg == empty {
return &empty, nil
}
return &configTypes.AuthConfig{
Username: cfg.Username,
Password: cfg.Password,
Auth: cfg.Auth,
IdentityToken: cfg.IdentityToken,
RegistryToken: cfg.RegistryToken,
}, nil
}
Loading

0 comments on commit ce35f37

Please sign in to comment.