-
Notifications
You must be signed in to change notification settings - Fork 9
/
existing.go
102 lines (81 loc) · 3.89 KB
/
existing.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// Copyright 2022 Namespace Labs Inc; All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
package prepare
import (
"context"
"fmt"
"strings"
"github.com/google/go-containerregistry/pkg/name"
"github.com/spf13/cobra"
"namespacelabs.dev/foundation/internal/build/registry"
"namespacelabs.dev/foundation/internal/console"
"namespacelabs.dev/foundation/internal/fnerrors"
"namespacelabs.dev/foundation/internal/prepare"
"namespacelabs.dev/foundation/internal/runtime/kubernetes/client"
"namespacelabs.dev/foundation/std/cfg"
)
func newExistingCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "existing",
Short: "Prepares a Namespace enviroment with an existing Kubernetes cluster.",
}
contextName := cmd.Flags().String("context", "", "The name of the kubernetes context to use.")
registryAddr := cmd.Flags().String("registry", "", "Which registry to use for deployed images.")
kubeConfig := cmd.Flags().String("kube_config", "~/.kube/config", "Which kubernetes configuration to use.")
insecure := cmd.Flags().Bool("insecure", false, "Set to true if the image registry is not accessible via TLS.")
useDockerCredentials := cmd.Flags().Bool("use_docker_creds", false, "If set to true, uses Docker's credentials when accessing the registry.")
singleRepository := cmd.Flags().Bool("use_single_repository", false, "If set to true, collapse all images onto a single repository under the configured registry (rather than a repository per image).")
cmd.RunE = runPrepare(func(ctx context.Context, env cfg.Context) ([]prepare.Stage, error) {
if *contextName == "" {
return nil, fnerrors.New("--context is required; it's the name of an existing kubernetes context")
}
if *registryAddr == "" {
return nil, fnerrors.New("--registry is required; it's the url of an existing image registry")
}
repo, err := name.NewRepository(*registryAddr)
if err != nil {
return nil, fnerrors.New("invalid registry definition: %w", err)
}
// Docker Hub validation.
if repo.Registry.Name() == name.DefaultRegistry {
warn := console.Warnings(ctx)
fmt.Fprintf(warn, `
Docker Hub detected as the target registry.
When using Docker Hub, we collapse all image pushes to a single repository,
as Docker Hub doesn't support multi segment repositories.
Also, the configured repository must be public, as we don't forward
your docker credentials to the cluster.
`)
if !*singleRepository {
return nil, fnerrors.New("--use_single_repository is required when the target registry is Docker Hub")
}
if !*useDockerCredentials {
return nil, fnerrors.New("--use_docker_creds is required when the target registry is Docker Hub")
}
parts := strings.Split(repo.RepositoryStr(), "/")
if len(parts) != 2 || parts[0] == "library" {
return nil, fnerrors.New("when using Docker Hub, you must specify the target registry explicitly. E.g. --registry docker.io/username/namespace-images")
}
}
cfg, err := client.LoadExistingConfiguration(*kubeConfig, *contextName)
if err != nil {
return nil, fnerrors.New("failed to load existing configuration: %w", err)
}
if _, err := cfg.ClientConfig(); err != nil {
return nil, fnerrors.New("failed to load existing configuration from %q: %w (you can change which kubeconfig is used via --kube_config)", *kubeConfig, err)
}
insecureLabel := ""
if *insecure {
insecureLabel = fmt.Sprintf(" insecure=%v", *insecure)
}
fmt.Fprintf(console.Stdout(ctx), "Setting up existing cluster configured at context %q (registry %q%s)...\n", *contextName, *registryAddr, insecureLabel)
return []prepare.Stage{prepare.PrepareExistingK8s(env, *kubeConfig, *contextName, ®istry.Registry{
Url: *registryAddr,
Insecure: *insecure,
UseDockerAuth: *useDockerCredentials,
SingleRepository: *singleRepository,
})}, nil
})
return cmd
}