cli/io/config.go (183 lines of code) (raw):

/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package io import ( "encoding/json" "os" "path/filepath" "bytes" "encoding/base64" "errors" "github.com/apache/brooklyn-client/cli/error_handler" ) // Deprecated: support old style of .brooklyn_cli format for version <= 0.11.0 const authKey = "auth" const credentialsKey = "credentials" const usernameKey = "username" const passwordKey = "password" const targetKey = "target" const skipSslChecksKey = "skipSslChecks" const authTypeKey = "authType" type Config struct { FilePath string Map map[string]interface{} } func GetConfig() (config *Config) { // check to see if $BRCLI_HOME/.brooklyn_cli or $HOME/.brooklyn_cli exists // Then parse it to get user credentials config = new(Config) if os.Getenv("BRCLI_HOME") != "" { config.FilePath = filepath.Join(os.Getenv("BRCLI_HOME"), ".brooklyn_cli") } else { config.FilePath = filepath.Join(os.Getenv("HOME"), ".brooklyn_cli") } if _, err := os.Stat(config.FilePath); os.IsNotExist(err) { config.Map = make(map[string]interface{}) config.Write() } config.read() return } func (config *Config) Delete() (err error) { if _, err := os.Stat(config.FilePath); err == nil { err = os.Remove(config.FilePath) } return err } func (config *Config) Write() { // Create file as read/write by user (but does not change perms of existing file) fileToWrite, err := os.OpenFile(config.FilePath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600) defer fileToWrite.Close() if err != nil { error_handler.ErrorExit(err) } marshalledMap, err := json.Marshal(config.Map) if err != nil { error_handler.ErrorExit(err) } var formatted bytes.Buffer if err = json.Indent(&formatted, marshalledMap, "", " "); err != nil { error_handler.ErrorExit(err) } fileToWrite.Write(formatted.Bytes()) } func (config *Config) read() { fileToRead, err := os.Open(config.FilePath) if err != nil { error_handler.ErrorExit(err) } defer fileToRead.Close() dec := json.NewDecoder(fileToRead) dec.Decode(&config.Map) } // getCredentials reads credentials from .brooklyn_cli data formatted for versions > 0.11.0 // Note that the password is base64 encoded to avoid json formatting problems //{ // "credentials": { // "http://geoffs-macbook-pro.local:8081": "Z2VvZmY6cGFzc3dvcmQ=", // "http://localhost:8081": "Z2VvZmY6cGFzc3dvcmQ=" // }, // "skipSslChecks": false, // "target": "http://geoffs-macbook-pro.local:8081" //} func (config *Config) getCredentials(target string) (credentials string, err error) { credentialsMap, found := config.Map[credentialsKey].(map[string]interface{}) if !found { err = errors.New("No credentials found in configuration") return } credentials, found = credentialsMap[target].(string) if !found { err = errors.New("No credentials found in configuration for " + target) return } return credentials, err } // Deprecated: // getCredentialsOldStyle provides backward support for .brooklyn_cli format for version <= 0.11.0: // { // "auth": { // "http://geoffs-macbook-pro.local:8081": { // "password": "password", // "username": "geoff" // } // }, // "skipSslChecks": false, // "target": "http://geoffs-macbook-pro.local:8081" //} func (config *Config) getCredentialsOldStyle(target string) (username string, password string, err error) { auth, found := config.Map[authKey].(map[string]interface{}) if !found { err = errors.New("No credentials for " + target) return } creds, found := auth[target].(map[string]interface{}) if !found { err = errors.New("No credentials found for " + target) return } if username, found = creds[usernameKey].(string); !found { err = errors.New("No credentials for " + username) return } if password, found = creds[passwordKey].(string); !found { err = errors.New("No credentials for " + username) return } return username, password, err } func (config *Config) initialize() { if config.Map == nil { config.Map = make(map[string]interface{}) } if _, found := config.Map[credentialsKey]; !found { config.Map[credentialsKey] = make(map[string]interface{}) } if _, found := config.Map[authTypeKey]; !found { config.Map[authTypeKey] = make(map[string]interface{}) } } func (config *Config) setCredential(target string, credentials string) { credentialsMap := config.Map[credentialsKey].(map[string]interface{}) credentialsMap[target] = credentials } func (config *Config) SetNetworkCredentials(target string, credentials string) { config.initialize() config.adaptLegacyCredentialFormat() config.setCredential(target, credentials) config.Map[targetKey] = target // Overwrite old style format from version <= 0.11.0 delete(config.Map, authKey) } func (config *Config) adaptLegacyCredentialFormat() { auth, found := config.Map[authKey].(map[string]interface{}) if !found { return } for url, credMap := range auth { creds := credMap.(map[string]interface{}) var username, password string username, found := creds[usernameKey].(string) if found { password, found = creds[passwordKey].(string) } if found { credentials := base64.StdEncoding.EncodeToString([]byte(username + ":" + password)) config.setCredential(url, credentials) } } } func (config *Config) GetNetworkCredentialsForTarget(target string) (credentials string, err error) { if credentials, err = config.getCredentials(target); err != nil { var username, password string username, password, err = config.getCredentialsOldStyle(target) if err == nil { credentials = base64.StdEncoding.EncodeToString([]byte(username + ":" + password)) } } return } func (config *Config) GetNetworkCredentials() (target string, credentials string, err error) { target, found := config.Map[targetKey].(string) if found { credentials, err = config.GetNetworkCredentialsForTarget(target) } else { err = errors.New("Not logged in") } return target, credentials, err } func (config *Config) GetSkipSslChecks() bool { if config.Map == nil { config.Map = make(map[string]interface{}) } skipSslChecks, _ := config.Map[skipSslChecksKey].(bool) return skipSslChecks } func (config *Config) SetSkipSslChecks(skipSslChecks bool) { config.Map[skipSslChecksKey] = skipSslChecks } func (config *Config) GetAuthType(target string) (authType string, err error) { authTypeMap, found := config.Map[authTypeKey].(map[string]interface{}) if found { authType, found = authTypeMap[target].(string) } // default behaviour if !found { authType = "Basic" } return authType, err } func (config *Config) SetAuthType(target string, authType string) { authTypeMap := config.Map[authTypeKey].(map[string]interface{}) authTypeMap[target] = authType }