1
// Copyright 2016 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
9
"github.com/juju/juju/apiserver/common"
10
"github.com/juju/juju/apiserver/facade"
11
"github.com/juju/juju/apiserver/params"
12
"github.com/juju/juju/environs/config"
13
"github.com/juju/juju/network"
14
"github.com/juju/juju/state"
15
"github.com/juju/juju/state/watcher"
16
"github.com/juju/utils/proxy"
17
"github.com/juju/utils/set"
18
"gopkg.in/juju/names.v2"
21
// Backend defines the state methods this facade needs, so they can be
22
// mocked for testing.
23
type Backend interface {
24
ModelConfig() (*config.Config, error)
25
APIHostPorts() ([][]network.HostPort, error)
26
WatchAPIHostPorts() state.NotifyWatcher
27
WatchForModelConfigChanges() state.NotifyWatcher
30
type ProxyUpdaterAPI struct {
32
resources facade.Resources
33
authorizer facade.Authorizer
36
// NewAPIWithBacking creates a new server-side API facade with the given Backing.
37
func NewAPIWithBacking(st Backend, resources facade.Resources, authorizer facade.Authorizer) (*ProxyUpdaterAPI, error) {
38
if !(authorizer.AuthMachineAgent() || authorizer.AuthUnitAgent()) {
39
return &ProxyUpdaterAPI{}, common.ErrPerm
41
return &ProxyUpdaterAPI{
44
authorizer: authorizer,
48
func (api *ProxyUpdaterAPI) oneWatch() params.NotifyWatchResult {
49
var result params.NotifyWatchResult
51
watch := common.NewMultiNotifyWatcher(
52
api.backend.WatchForModelConfigChanges(),
53
api.backend.WatchAPIHostPorts())
55
if _, ok := <-watch.Changes(); ok {
56
result = params.NotifyWatchResult{
57
NotifyWatcherId: api.resources.Register(watch),
60
result.Error = common.ServerError(watcher.EnsureErr(watch))
65
// WatchForProxyConfigAndAPIHostPortChanges watches for cleanups to be perfomed in state
66
func (api *ProxyUpdaterAPI) WatchForProxyConfigAndAPIHostPortChanges(args params.Entities) params.NotifyWatchResults {
67
results := params.NotifyWatchResults{
68
Results: make([]params.NotifyWatchResult, len(args.Entities)),
70
errors, _ := api.authEntities(args)
72
for i := range args.Entities {
73
if errors.Results[i].Error == nil {
74
results.Results[i] = api.oneWatch()
76
results.Results[i].Error = errors.Results[i].Error
83
func proxyUtilsSettingsToProxySettingsParam(settings proxy.Settings) params.ProxyConfig {
84
return params.ProxyConfig{
86
HTTPS: settings.Https,
88
NoProxy: settings.NoProxy,
92
func (api *ProxyUpdaterAPI) authEntities(args params.Entities) (params.ErrorResults, bool) {
93
result := params.ErrorResults{
94
Results: make([]params.ErrorResult, len(args.Entities)),
99
for i, entity := range args.Entities {
100
tag, err := names.ParseTag(entity.Tag)
102
result.Results[i].Error = common.ServerError(common.ErrPerm)
106
if !api.authorizer.AuthOwner(tag) {
107
result.Results[i].Error = common.ServerError(err)
115
func (api *ProxyUpdaterAPI) proxyConfig() params.ProxyConfigResult {
116
var result params.ProxyConfigResult
117
env, err := api.backend.ModelConfig()
119
result.Error = common.ServerError(err)
123
apiHostPorts, err := api.backend.APIHostPorts()
125
result.Error = common.ServerError(err)
129
result.ProxySettings = proxyUtilsSettingsToProxySettingsParam(env.ProxySettings())
130
result.APTProxySettings = proxyUtilsSettingsToProxySettingsParam(env.AptProxySettings())
133
if result.ProxySettings.NoProxy != "" {
134
noProxy = strings.Split(result.ProxySettings.NoProxy, ",")
137
noProxySet := set.NewStrings(noProxy...)
138
for _, host := range apiHostPorts {
139
for _, hp := range host {
140
noProxySet.Add(hp.Address.Value)
143
result.ProxySettings.NoProxy = strings.Join(noProxySet.SortedValues(), ",")
148
// ProxyConfig returns the proxy settings for the current environment
149
func (api *ProxyUpdaterAPI) ProxyConfig(args params.Entities) params.ProxyConfigResults {
150
var result params.ProxyConfigResult
151
errors, ok := api.authEntities(args)
154
result = api.proxyConfig()
157
results := params.ProxyConfigResults{
158
Results: make([]params.ProxyConfigResult, len(args.Entities)),
160
for i := range args.Entities {
161
if errors.Results[i].Error == nil {
162
results.Results[i] = result
164
results.Results[i].Error = errors.Results[i].Error