1
// Copyright 2016 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
13
"github.com/juju/errors"
14
"github.com/juju/utils"
16
"github.com/juju/juju/cloud"
20
credAttrMAASOAuth = "maas-oauth"
23
type environProviderCredentials struct{}
25
// CredentialSchemas is part of the environs.ProviderCredentials interface.
26
func (environProviderCredentials) CredentialSchemas() map[cloud.AuthType]cloud.CredentialSchema {
27
return map[cloud.AuthType]cloud.CredentialSchema{
28
cloud.OAuth1AuthType: {{
29
credAttrMAASOAuth, cloud.CredentialAttr{
30
Description: "OAuth/API-key credentials for MAAS",
37
// DetectCredentials is part of the environs.ProviderCredentials interface.
38
func (environProviderCredentials) DetectCredentials() (*cloud.CloudCredential, error) {
39
// MAAS stores credentials in a json file: ~/.maasrc
40
// {"Server": "http://<ip>/MAAS", "OAuth": "<key>"}
41
maasrc := filepath.Join(utils.Home(), ".maasrc")
42
fileBytes, err := ioutil.ReadFile(maasrc)
44
return nil, errors.Trace(err)
47
details := make(map[string]interface{})
48
err = json.Unmarshal(fileBytes, &details)
50
return nil, errors.Trace(err)
52
oauthKey := details["OAuth"]
54
return nil, errors.New("MAAS credentials require a value for OAuth token")
56
cred := cloud.NewCredential(cloud.OAuth1AuthType, map[string]string{
57
credAttrMAASOAuth: fmt.Sprintf("%v", oauthKey),
59
server, ok := details["Server"]
60
if server == "" || !ok {
61
server = "unspecified server"
63
cred.Label = fmt.Sprintf("MAAS credential for %s", server)
65
return &cloud.CloudCredential{
66
AuthCredentials: map[string]cloud.Credential{
72
func parseOAuthToken(cred cloud.Credential) (string, error) {
73
oauth := cred.Attributes()[credAttrMAASOAuth]
74
if strings.Count(oauth, ":") != 2 {
75
return "", errMalformedMaasOAuth
80
var errMalformedMaasOAuth = errors.New("malformed maas-oauth (3 items separated by colons)")