123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- package cloudinit
- import (
- "io/ioutil"
- "strings"
- log "github.com/Sirupsen/logrus"
- "google.golang.org/cloud/compute/metadata"
- "gopkg.in/yaml.v2"
- )
- type GceCloudConfig struct {
- FileName string
- UserData string
- NonUserDataSSHKeys []string
- }
- const (
- gceCloudConfigFile = "/var/lib/rancher/conf/gce_cloudinit_config.yml"
- )
- func NewGceCloudConfig() *GceCloudConfig {
- userData, err := metadata.InstanceAttributeValue("user-data")
- if err != nil {
- log.Errorf("Could not retrieve user-data: %s", err)
- }
- projectSSHKeys, err := metadata.ProjectAttributeValue("sshKeys")
- if err != nil {
- log.Errorf("Could not retrieve project SSH Keys: %s", err)
- }
- instanceSSHKeys, err := metadata.InstanceAttributeValue("sshKeys")
- if err != nil {
- log.Errorf("Could not retrieve instance SSH Keys: %s", err)
- }
- nonUserDataSSHKeysRaw := projectSSHKeys + "\n" + instanceSSHKeys
- nonUserDataSSHKeys := gceSshKeyFormatter(nonUserDataSSHKeysRaw)
- gceCC := &GceCloudConfig{
- FileName: gceCloudConfigFile,
- UserData: userData,
- NonUserDataSSHKeys: nonUserDataSSHKeys,
- }
- return gceCC
- }
- func GetAndCreateGceDataSourceFilename() (string, error) {
- gceCC := NewGceCloudConfig()
- err := gceCC.saveToFile(gceCC.FileName)
- if err != nil {
- log.Errorf("Error: %s", err)
- return "", err
- }
- return gceCC.FileName, nil
- }
- func (cc *GceCloudConfig) saveToFile(filename string) error {
- //Get Merged UserData sshkeys
- data, err := cc.getMergedUserData()
- if err != nil {
- log.Errorf("Could not process userdata: %s", err)
- return err
- }
- //write file
- writeFile(filename, data)
- return nil
- }
- func (cc *GceCloudConfig) getMergedUserData() ([]byte, error) {
- var returnUserData []byte
- userdata := make(map[string]interface{})
- if cc.UserData != "" {
- log.Infof("Found UserData Config")
- err := yaml.Unmarshal([]byte(cc.UserData), &userdata)
- if err != nil {
- log.Errorf("Could not unmarshal data: %s", err)
- return nil, err
- }
- }
- var auth_keys []string
- if _, exists := userdata["ssh_authorized_keys"]; exists {
- udSshKeys := userdata["ssh_authorized_keys"].([]interface{})
- log.Infof("userdata %s", udSshKeys)
- for _, value := range udSshKeys {
- auth_keys = append(auth_keys, value.(string))
- }
- }
- if cc.NonUserDataSSHKeys != nil {
- for _, value := range cc.NonUserDataSSHKeys {
- auth_keys = append(auth_keys, value)
- }
- }
- userdata["ssh_authorized_keys"] = auth_keys
- yamlUserData, err := yaml.Marshal(&userdata)
- if err != nil {
- log.Errorf("Could not Marshal userdata: %s", err)
- return nil, err
- } else {
- returnUserData = append([]byte("#cloud-config\n"), yamlUserData...)
- }
- return returnUserData, nil
- }
- func writeFile(filename string, data []byte) error {
- if err := ioutil.WriteFile(filename, data, 400); err != nil {
- log.Errorf("Could not write file %v", err)
- return err
- }
- return nil
- }
- func gceSshKeyFormatter(rawKeys string) []string {
- keySlice := strings.Split(rawKeys, "\n")
- var cloudFormatedKeys []string
- if len(keySlice) > 0 {
- for i := range keySlice {
- keyString := keySlice[i]
- sIdx := strings.Index(keyString, ":")
- if sIdx != -1 {
- key := strings.TrimSpace(keyString[sIdx+1:])
- keyA := strings.Split(key, " ")
- key = strings.Join(keyA, " ")
- if key != "" {
- cloudFormatedKeys = append(cloudFormatedKeys, key)
- }
- }
- }
- }
- return cloudFormatedKeys
- }
|