github.com/docker/compose-on-kubernetes@v0.5.0/cmd/installer/main.go (about) 1 package main 2 3 import ( 4 "context" 5 "errors" 6 "flag" 7 "fmt" 8 "io/ioutil" 9 "os" 10 11 "github.com/docker/compose-on-kubernetes/api/constants" 12 "github.com/docker/compose-on-kubernetes/install" 13 customflags "github.com/docker/compose-on-kubernetes/internal/flags" 14 homedir "github.com/mitchellh/go-homedir" 15 log "github.com/sirupsen/logrus" 16 corev1types "k8s.io/api/core/v1" 17 _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" // For Google Kubernetes Engine authentication 18 "k8s.io/client-go/rest" 19 "k8s.io/client-go/tools/clientcmd" 20 ) 21 22 func main() { 23 if err := do(); err != nil { 24 fmt.Fprintf(os.Stderr, "Installation failed: %s", err) 25 os.Exit(1) 26 } 27 } 28 29 func do() error { 30 installerConfig, err := parseOptions() 31 if err != nil { 32 return err 33 } 34 if installerConfig.uninstall { 35 err := install.Uninstall(installerConfig.restConfig, installerConfig.options.Namespace, false) 36 if err != nil { 37 return err 38 } 39 return install.WaitForUninstallCompletion(context.Background(), installerConfig.restConfig, installerConfig.options.Namespace, false) 40 } 41 return install.Safe(context.Background(), installerConfig.restConfig, installerConfig.options) 42 } 43 44 type installerConfig struct { 45 uninstall bool 46 options install.SafeOptions 47 restConfig *rest.Config 48 } 49 50 func parseOptions() (installerConfig, error) { 51 var flags additionalFlags 52 var options install.SafeOptions 53 parseFlags(&flags, &options) 54 loggerLevel, err := log.ParseLevel(flags.logLevel) 55 if err != nil { 56 return installerConfig{}, err 57 } 58 log.SetLevel(loggerLevel) 59 60 pp, err := parsePullPolicy(flags.pullPolicy) 61 if err != nil { 62 return installerConfig{}, err 63 } 64 options.OptionsCommon.PullPolicy = pp 65 66 options.Etcd.ClientTLSBundle, err = flags.etcdBundle.load() 67 if err != nil { 68 return installerConfig{}, err 69 } 70 options.Network.CustomTLSBundle, err = flags.tlsBundle.load() 71 if err != nil { 72 return installerConfig{}, err 73 } 74 configFile, err := homedir.Expand(flags.kubeconfig) 75 if err != nil { 76 return installerConfig{}, err 77 } 78 config, err := clientcmd.BuildConfigFromFlags("", configFile) 79 if err != nil { 80 return installerConfig{}, err 81 } 82 if flags.skipLivenessProbes { 83 options.HealthzCheckPort = 0 84 } 85 if flags.apiServerReplicas != 1 { 86 replicas := int32(flags.apiServerReplicas) 87 options.APIServerReplicas = &replicas 88 } 89 return installerConfig{ 90 options: options, 91 restConfig: config, 92 uninstall: flags.uninstall, 93 }, nil 94 } 95 96 func parsePullPolicy(pullPolicy string) (corev1types.PullPolicy, error) { 97 switch pp := corev1types.PullPolicy(pullPolicy); pp { 98 case corev1types.PullAlways, corev1types.PullNever, corev1types.PullIfNotPresent: 99 return pp, nil 100 default: 101 return "", fmt.Errorf("invalid pull policy: %q", pullPolicy) 102 } 103 } 104 105 type additionalFlags struct { 106 etcdBundle certBundleSource 107 tlsBundle certBundleSource 108 logLevel string 109 pullPolicy string 110 kubeconfig string 111 uninstall bool 112 skipLivenessProbes bool 113 apiServerReplicas int 114 } 115 116 func parseFlags(customFlags *additionalFlags, options *install.SafeOptions) { 117 flag.BoolVar(&options.Network.ShouldUseHost, "network-host", false, "Use network host") 118 flag.StringVar(&options.OptionsCommon.Namespace, "namespace", "docker", "Namespace in which to deploy") 119 flag.DurationVar(&options.OptionsCommon.ReconciliationInterval, "reconciliation-interval", constants.DefaultFullSyncInterval, "Interval of reconciliation loop") 120 flag.StringVar(&options.OptionsCommon.Tag, "tag", "latest", "Image tag") 121 pullPolicyDescription := fmt.Sprintf("Image pull policy (%q|%q|%q)", corev1types.PullAlways, corev1types.PullNever, corev1types.PullIfNotPresent) 122 flag.StringVar(&customFlags.pullPolicy, "pull-policy", string(corev1types.PullAlways), pullPolicyDescription) 123 flag.StringVar(&options.Etcd.Servers, "etcd-servers", "", "etcd server addresses") 124 flag.BoolVar(&customFlags.skipLivenessProbes, "skip-liveness-probes", false, "Disable liveness probe on Controller and API server deployments. Use this when HTTPS liveness probe fails.") 125 flag.IntVar(&options.HealthzCheckPort, "healthz-check-port", 8080, "Defines the port used by healthz check server for api-server and controller (0 to disable it)") 126 127 flag.StringVar(&customFlags.etcdBundle.ca, "etcd-ca-file", "", "CA of etcd TLS certificate") 128 flag.StringVar(&customFlags.etcdBundle.cert, "etcd-cert-file", "", "TLS client certificate for accessing etcd") 129 flag.StringVar(&customFlags.etcdBundle.key, "etcd-key-file", "", "TLS client private key for accessing etcd") 130 131 flag.StringVar(&customFlags.tlsBundle.ca, "tls-ca-file", "", "CA used to generate the TLS certificate") 132 flag.StringVar(&customFlags.tlsBundle.cert, "tls-cert-file", "", "Server TLS certificate (must be valid for name compose-api.<namespace>.svc)") 133 flag.StringVar(&customFlags.tlsBundle.key, "tls-key-file", "", "Server TLS private key") 134 flag.BoolVar(&customFlags.uninstall, "uninstall", false, "Uninstall") 135 flag.StringVar(&customFlags.logLevel, "log-level", "info", `Set the log level ("debug"|"info"|"warn"|"error"|"fatal")`) 136 flag.IntVar(&customFlags.apiServerReplicas, "apiserver-replicas", 1, "Number of replicas for the API Server") 137 kubeconfigFlag := customflags.EnvString("kubeconfig", "~/.kube/config", "KUBECONFIG", "Path to a kubeconfig file (set to \"\" to use incluster config)") 138 flag.Parse() 139 customFlags.kubeconfig = kubeconfigFlag.String() 140 } 141 142 type certBundleSource struct { 143 ca, cert, key string 144 } 145 146 func (s certBundleSource) empty() bool { 147 return s.ca == "" && s.cert == "" && s.key == "" 148 } 149 150 func (s certBundleSource) load() (*install.TLSBundle, error) { 151 if s.empty() { 152 return nil, nil 153 } 154 if s.ca == "" || s.cert == "" || s.key == "" { 155 return nil, errors.New("ca-file, cert-file and key-file must be set altogether or not at all") 156 } 157 caBytes, err := ioutil.ReadFile(s.ca) 158 if err != nil { 159 return nil, err 160 } 161 certBytes, err := ioutil.ReadFile(s.cert) 162 if err != nil { 163 return nil, err 164 } 165 keyBytes, err := ioutil.ReadFile(s.key) 166 if err != nil { 167 return nil, err 168 } 169 bundle, err := install.NewTLSBundle(caBytes, certBytes, keyBytes) 170 if err != nil { 171 return nil, err 172 } 173 return bundle, nil 174 }