~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/juju/juju/provider/manual/provider.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2013 Canonical Ltd.
 
2
// Licensed under the AGPLv3, see LICENCE file for details.
 
3
 
 
4
package manual
 
5
 
 
6
import (
 
7
        "fmt"
 
8
 
 
9
        "github.com/juju/errors"
 
10
 
 
11
        "github.com/juju/juju/cloud"
 
12
        "github.com/juju/juju/environs"
 
13
        "github.com/juju/juju/environs/config"
 
14
        "github.com/juju/juju/environs/manual"
 
15
)
 
16
 
 
17
type manualProvider struct {
 
18
        environProviderCredentials
 
19
}
 
20
 
 
21
// Verify that we conform to the interface.
 
22
var _ environs.EnvironProvider = (*manualProvider)(nil)
 
23
 
 
24
var initUbuntuUser = manual.InitUbuntuUser
 
25
 
 
26
func ensureBootstrapUbuntuUser(ctx environs.BootstrapContext, host string, cfg *environConfig) error {
 
27
        err := initUbuntuUser(host, cfg.bootstrapUser(), cfg.AuthorizedKeys(), ctx.GetStdin(), ctx.GetStdout())
 
28
        if err != nil {
 
29
                logger.Errorf("initializing ubuntu user: %v", err)
 
30
                return err
 
31
        }
 
32
        logger.Infof("initialized ubuntu user")
 
33
        return nil
 
34
}
 
35
 
 
36
// RestrictedConfigAttributes is specified in the EnvironProvider interface.
 
37
func (p manualProvider) RestrictedConfigAttributes() []string {
 
38
        return []string{"bootstrap-user"}
 
39
}
 
40
 
 
41
// DetectRegions is specified in the environs.CloudRegionDetector interface.
 
42
func (p manualProvider) DetectRegions() ([]cloud.Region, error) {
 
43
        return nil, errors.NotFoundf("regions")
 
44
}
 
45
 
 
46
// PrepareConfig is specified in the EnvironProvider interface.
 
47
func (p manualProvider) PrepareConfig(args environs.PrepareConfigParams) (*config.Config, error) {
 
48
        if args.Cloud.Endpoint == "" {
 
49
                return nil, errors.Errorf(
 
50
                        "missing address of host to bootstrap: " +
 
51
                                `please specify "juju bootstrap manual/<host>"`,
 
52
                )
 
53
        }
 
54
        envConfig, err := p.validate(args.Config, nil)
 
55
        if err != nil {
 
56
                return nil, err
 
57
        }
 
58
        return args.Config.Apply(envConfig.attrs)
 
59
}
 
60
 
 
61
func (p manualProvider) Open(args environs.OpenParams) (environs.Environ, error) {
 
62
        if err := validateCloudSpec(args.Cloud); err != nil {
 
63
                return nil, errors.Trace(err)
 
64
        }
 
65
        _, err := p.validate(args.Config, nil)
 
66
        if err != nil {
 
67
                return nil, err
 
68
        }
 
69
        // validate adds missing manual-specific config attributes
 
70
        // with their defaults in the result; we don't wnat that in
 
71
        // Open.
 
72
        envConfig := newModelConfig(args.Config, args.Config.UnknownAttrs())
 
73
        return p.open(args.Cloud.Endpoint, envConfig)
 
74
}
 
75
 
 
76
func validateCloudSpec(spec environs.CloudSpec) error {
 
77
        if spec.Endpoint == "" {
 
78
                return errors.Errorf(
 
79
                        "missing address of host to bootstrap: " +
 
80
                                `please specify "juju bootstrap manual/<host>"`,
 
81
                )
 
82
        }
 
83
        return nil
 
84
}
 
85
 
 
86
func (p manualProvider) open(host string, cfg *environConfig) (environs.Environ, error) {
 
87
        env := &manualEnviron{host: host, cfg: cfg}
 
88
        // Need to call SetConfig to initialise storage.
 
89
        if err := env.SetConfig(cfg.Config); err != nil {
 
90
                return nil, err
 
91
        }
 
92
        return env, nil
 
93
}
 
94
 
 
95
func checkImmutableString(cfg, old *environConfig, key string) error {
 
96
        if old.attrs[key] != cfg.attrs[key] {
 
97
                return fmt.Errorf("cannot change %s from %q to %q", key, old.attrs[key], cfg.attrs[key])
 
98
        }
 
99
        return nil
 
100
}
 
101
 
 
102
func (p manualProvider) validate(cfg, old *config.Config) (*environConfig, error) {
 
103
        // Check for valid changes for the base config values.
 
104
        if err := config.Validate(cfg, old); err != nil {
 
105
                return nil, err
 
106
        }
 
107
        validated, err := cfg.ValidateUnknownAttrs(configFields, configDefaults)
 
108
        if err != nil {
 
109
                return nil, err
 
110
        }
 
111
        envConfig := newModelConfig(cfg, validated)
 
112
        // Check various immutable attributes.
 
113
        if old != nil {
 
114
                oldEnvConfig, err := p.validate(old, nil)
 
115
                if err != nil {
 
116
                        return nil, err
 
117
                }
 
118
                for _, key := range [...]string{
 
119
                        "bootstrap-user",
 
120
                } {
 
121
                        if err = checkImmutableString(envConfig, oldEnvConfig, key); err != nil {
 
122
                                return nil, err
 
123
                        }
 
124
                }
 
125
        }
 
126
 
 
127
        // If the user hasn't already specified a value, set it to the
 
128
        // given value.
 
129
        defineIfNot := func(keyName string, value interface{}) {
 
130
                if _, defined := cfg.AllAttrs()[keyName]; !defined {
 
131
                        logger.Infof("%s was not defined. Defaulting to %v.", keyName, value)
 
132
                        envConfig.attrs[keyName] = value
 
133
                }
 
134
        }
 
135
 
 
136
        // If the user hasn't specified a value, refresh the
 
137
        // available updates, but don't upgrade.
 
138
        defineIfNot("enable-os-refresh-update", true)
 
139
        defineIfNot("enable-os-upgrade", false)
 
140
 
 
141
        return envConfig, nil
 
142
}
 
143
 
 
144
func (p manualProvider) Validate(cfg, old *config.Config) (valid *config.Config, err error) {
 
145
        envConfig, err := p.validate(cfg, old)
 
146
        if err != nil {
 
147
                return nil, err
 
148
        }
 
149
        return cfg.Apply(envConfig.attrs)
 
150
}
 
151
 
 
152
func (p manualProvider) SecretAttrs(cfg *config.Config) (map[string]string, error) {
 
153
        attrs := make(map[string]string)
 
154
        return attrs, nil
 
155
}