forked from juju/juju
/
manifold.go
139 lines (124 loc) · 4.08 KB
/
manifold.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// Copyright 2015 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.
package firewaller
import (
"github.com/juju/errors"
"gopkg.in/juju/worker.v1"
"gopkg.in/juju/worker.v1/dependency"
"github.com/juju/juju/agent"
"github.com/juju/juju/api"
"github.com/juju/juju/api/base"
"github.com/juju/juju/api/remoterelations"
"github.com/juju/juju/environs"
"github.com/juju/juju/environs/config"
"github.com/juju/juju/worker/apicaller"
"github.com/juju/juju/worker/common"
)
// ManifoldConfig describes the resources used by the firewaller worker.
type ManifoldConfig struct {
AgentName string
APICallerName string
EnvironName string
NewControllerConnection apicaller.NewExternalControllerConnectionFunc
NewRemoteRelationsFacade func(base.APICaller) (*remoterelations.Client, error)
NewFirewallerFacade func(base.APICaller) (FirewallerAPI, error)
NewFirewallerWorker func(Config) (worker.Worker, error)
NewCredentialValidatorFacade func(base.APICaller) (common.CredentialAPI, error)
}
// Manifold returns a Manifold that encapsulates the firewaller worker.
func Manifold(cfg ManifoldConfig) dependency.Manifold {
return dependency.Manifold{
Inputs: []string{
cfg.AgentName,
cfg.APICallerName,
cfg.EnvironName,
},
Start: cfg.start,
}
}
// Validate is called by start to check for bad configuration.
func (cfg ManifoldConfig) Validate() error {
if cfg.AgentName == "" {
return errors.NotValidf("empty AgentName")
}
if cfg.APICallerName == "" {
return errors.NotValidf("empty APICallerName")
}
if cfg.EnvironName == "" {
return errors.NotValidf("empty EnvironName")
}
if cfg.NewControllerConnection == nil {
return errors.NotValidf("nil NewControllerConnection")
}
if cfg.NewRemoteRelationsFacade == nil {
return errors.NotValidf("nil NewRemoteRelationsFacade")
}
if cfg.NewFirewallerFacade == nil {
return errors.NotValidf("nil NewFirewallerFacade")
}
if cfg.NewFirewallerWorker == nil {
return errors.NotValidf("nil NewFirewallerWorker")
}
if cfg.NewCredentialValidatorFacade == nil {
return errors.NotValidf("nil NewCredentialValidatorFacade")
}
return nil
}
// start is a StartFunc for a Worker manifold.
func (cfg ManifoldConfig) start(context dependency.Context) (worker.Worker, error) {
if err := cfg.Validate(); err != nil {
return nil, errors.Trace(err)
}
var agent agent.Agent
if err := context.Get(cfg.AgentName, &agent); err != nil {
return nil, errors.Trace(err)
}
var apiConn api.Connection
if err := context.Get(cfg.APICallerName, &apiConn); err != nil {
return nil, errors.Trace(err)
}
var environ environs.Environ
if err := context.Get(cfg.EnvironName, &environ); err != nil {
return nil, errors.Trace(err)
}
// Check if the env supports global firewalling. If the
// configured mode is instance, we can ignore fwEnv being a
// nil value, as it won't be used.
fwEnv, fwEnvOK := environ.(environs.Firewaller)
mode := environ.Config().FirewallMode()
if mode == config.FwNone {
logger.Infof("stopping firewaller (not required)")
return nil, dependency.ErrUninstall
} else if mode == config.FwGlobal {
if !fwEnvOK {
logger.Infof("Firewall global mode set on provider with no support. stopping firewaller")
return nil, dependency.ErrUninstall
}
}
firewallerAPI, err := cfg.NewFirewallerFacade(apiConn)
if err != nil {
return nil, errors.Trace(err)
}
remoteRelationsAPI, err := cfg.NewRemoteRelationsFacade(apiConn)
if err != nil {
return nil, errors.Trace(err)
}
credentialAPI, err := cfg.NewCredentialValidatorFacade(apiConn)
if err != nil {
return nil, errors.Trace(err)
}
w, err := cfg.NewFirewallerWorker(Config{
ModelUUID: agent.CurrentConfig().Model().Id(),
RemoteRelationsApi: remoteRelationsAPI,
FirewallerAPI: firewallerAPI,
EnvironFirewaller: fwEnv,
EnvironInstances: environ,
Mode: mode,
NewCrossModelFacadeFunc: crossmodelFirewallerFacadeFunc(cfg.NewControllerConnection),
CredentialAPI: credentialAPI,
})
if err != nil {
return nil, errors.Trace(err)
}
return w, nil
}