diff --git a/docs/user/environment-variables.md b/docs/user/environment-variables.md index b9ae79b0ed0..bedd18a0e28 100644 --- a/docs/user/environment-variables.md +++ b/docs/user/environment-variables.md @@ -38,6 +38,8 @@ The installer accepts a number of environment variable that allow the interactiv ## Platform-Specific +* `AWS_PROFILE`: + The AWS profile that corresponds to value in `${HOME}/.aws/credentials`. If not provided, the default is "default". * `OPENSHIFT_INSTALL_AWS_REGION`: The AWS region to be used for installation. * `OPENSHIFT_INSTALL_LIBVIRT_URI`: diff --git a/pkg/asset/manifests/content/tectonic/cloud-creds-secret.go b/pkg/asset/manifests/content/tectonic/cloud-creds-secret.go new file mode 100644 index 00000000000..c1259e4c30e --- /dev/null +++ b/pkg/asset/manifests/content/tectonic/cloud-creds-secret.go @@ -0,0 +1,28 @@ +package tectonic + +import ( + "text/template" +) + +var ( + // CloudCredsSecret is the constant to represent contents of corresponding yaml file + CloudCredsSecret = template.Must(template.New("cloud-creds-secret.yaml").Parse(` +--- +kind: Secret +apiVersion: v1 +metadata: + namespace: kube-system +{{- if .CloudCreds.AWS}} + name: aws-creds +{{- else if .CloudCreds.OpenStack}} + name: openstack-creds +{{- end}} +data: +{{- if .CloudCreds.AWS}} + aws_access_key_id: {{.CloudCreds.AWS.Base64encodeAccessKeyID}} + aws_secret_access_key: {{.CloudCreds.AWS.Base64encodeSecretAccessKey}} +{{- else if .CloudCreds.OpenStack}} + clouds.yaml: {{.CloudCreds.OpenStack.Base64encodeCloudCreds}} +{{- end}} +`)) +) diff --git a/pkg/asset/manifests/content/tectonic/role-cloud-creds-secret-reader.go b/pkg/asset/manifests/content/tectonic/role-cloud-creds-secret-reader.go new file mode 100644 index 00000000000..fd6b08eb703 --- /dev/null +++ b/pkg/asset/manifests/content/tectonic/role-cloud-creds-secret-reader.go @@ -0,0 +1,30 @@ +package tectonic + +import ( + "text/template" +) + +var ( + // RoleCloudCredsSecretReader is the variable to represent contents of corresponding file + RoleCloudCredsSecretReader = template.Must(template.New("role-cloud-creds-secret-reader.yaml").Parse(` +--- +kind: Role +apiVersion: rbac.authorization.k8s.io/v1beta1 +metadata: + namespace: kube-system +{{- if .CloudCreds.AWS}} + name: aws-creds-secret-reader +{{- else if .CloudCreds.OpenStack}} + name: openstack-creds-secret-reader +{{- end}} +rules: +- apiGroups: [""] + resources: ["secrets"] +{{- if .CloudCreds.AWS}} + resourceNames: ["aws-creds"] +{{- else if .CloudCreds.OpenStack}} + resourceNames: ["openstack-creds"] +{{- end}} + verbs: ["get"] +`)) +) diff --git a/pkg/asset/manifests/tectonic.go b/pkg/asset/manifests/tectonic.go index 4df2b40d87f..e689292dedf 100644 --- a/pkg/asset/manifests/tectonic.go +++ b/pkg/asset/manifests/tectonic.go @@ -1,12 +1,16 @@ package manifests import ( + "bufio" "encoding/base64" + "io/ioutil" + "os" "path/filepath" "github.com/ghodss/yaml" "github.com/pkg/errors" + "github.com/aws/aws-sdk-go/aws/credentials" "github.com/openshift/installer/pkg/asset" "github.com/openshift/installer/pkg/asset/installconfig" "github.com/openshift/installer/pkg/asset/machines" @@ -16,12 +20,17 @@ import ( const ( tectonicManifestDir = "tectonic" + // TODO: Verify this is expected os creds file + openStackCredsFile = "/etc/openstack/clouds.yaml" ) var ( tectonicConfigPath = filepath.Join(tectonicManifestDir, "00_cluster-config.yaml") _ asset.WritableAsset = (*Tectonic)(nil) + + // TODO: Verify which creds file to expect + //openStackCredsFile = os.Getenv("HOME") + "/.config/openstack" ) // Tectonic generates the dependent resource manifests for tectonic (as against bootkube) @@ -57,8 +66,37 @@ func (t *Tectonic) Generate(dependencies asset.Parents) error { master := &machines.Master{} addon := &kubeAddonOperator{} dependencies.Get(installConfig, clusterk8sio, worker, master, addon) + var cloudCreds cloudCredsSecretData + platform := "" + switch { + case installConfig.Config.Platform.AWS != nil: + platform = "aws" + p := credentials.SharedCredentialsProvider{} + creds, err := p.Retrieve() + if err != nil { + return err + } + cloudCreds = cloudCredsSecretData{ + AWS: &AwsCredsSecretData{ + Base64encodeAccessKeyID: base64.StdEncoding.EncodeToString([]byte(creds.AccessKeyID)), + Base64encodeSecretAccessKey: base64.StdEncoding.EncodeToString([]byte(creds.SecretAccessKey)), + }, + } + case installConfig.Config.Platform.OpenStack != nil: + platform = "openstack" + credsEncoded, err := credsFileEncode(openStackCredsFile) + if err != nil { + return err + } + cloudCreds = cloudCredsSecretData{ + OpenStack: &OpenStackCredsSecretData{ + Base64encodeCloudCreds: credsEncoded, + }, + } + } templateData := &tectonicTemplateData{ + CloudCreds: cloudCreds, KubeAddonOperatorImage: "quay.io/coreos/kube-addon-operator-dev:375423a332f2c12b79438fc6a6da6e448e28ec0f", PullSecret: base64.StdEncoding.EncodeToString([]byte(installConfig.Config.PullSecret)), } @@ -78,6 +116,18 @@ func (t *Tectonic) Generate(dependencies asset.Parents) error { "99_tectonic-system-02-pull.json": applyTemplateData(content.PullTectonicSystem, templateData), } + switch platform { + case "aws", "openstack": + conditionalAssetData := map[string][]byte{ + "99_cloud-creds-secret.yaml": applyTemplateData(content.CloudCredsSecret, templateData), + "99_role-cloud-creds-secret-reader.yaml": applyTemplateData(content.RoleCloudCredsSecretReader, templateData), + } + + for file, content := range conditionalAssetData { + assetData[file] = content + } + } + // addon goes to openshift system t.TectonicConfig = configMap("tectonic-system", "cluster-config-v1", genericData{ "addon-config": string(addon.Files()[0].Data), @@ -136,3 +186,14 @@ func (t *Tectonic) Load(f asset.FileFetcher) (bool, error) { t.FileList, t.TectonicConfig = fileList, tectonicConfig return true, nil } + +// credsFileEncode returns contents of a file as base64 encoded string +func credsFileEncode(credsFile string) (string, error) { + f, _ := os.Open(credsFile) + reader := bufio.NewReader(f) + credsData, err := ioutil.ReadAll(reader) + if err != nil { + return "", err + } + return base64.StdEncoding.EncodeToString(credsData), nil +} diff --git a/pkg/asset/manifests/template.go b/pkg/asset/manifests/template.go index 4eb5c07929e..13be4b49ede 100644 --- a/pkg/asset/manifests/template.go +++ b/pkg/asset/manifests/template.go @@ -1,5 +1,21 @@ package manifests +// AwsCredsSecretData holds encoded credentials and is used to generate cloud-creds secret +type AwsCredsSecretData struct { + Base64encodeAccessKeyID string + Base64encodeSecretAccessKey string +} + +// OpenStackCredsSecretData holds encoded credentials and is used to generate cloud-creds secret +type OpenStackCredsSecretData struct { + Base64encodeCloudCreds string +} + +type cloudCredsSecretData struct { + AWS *AwsCredsSecretData + OpenStack *OpenStackCredsSecretData +} + type bootkubeTemplateData struct { AggregatorCaCert string AggregatorCaKey string @@ -37,4 +53,5 @@ type bootkubeTemplateData struct { type tectonicTemplateData struct { KubeAddonOperatorImage string PullSecret string + CloudCreds cloudCredsSecretData }