forked from juju/juju
-
Notifications
You must be signed in to change notification settings - Fork 0
/
reload.go
143 lines (125 loc) · 4.44 KB
/
reload.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
140
141
142
143
// Copyright 2020 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.
package spaces
import (
"github.com/juju/errors"
"github.com/juju/names/v4"
apiservererrors "github.com/DavinZhang/juju/apiserver/errors"
"github.com/DavinZhang/juju/apiserver/facade"
"github.com/DavinZhang/juju/core/permission"
"github.com/DavinZhang/juju/environs"
"github.com/DavinZhang/juju/environs/context"
"github.com/DavinZhang/juju/environs/space"
"github.com/DavinZhang/juju/state"
"github.com/DavinZhang/juju/state/stateenvirons"
)
// ReloadSpacesState contains all the methods required to execute the API.
type ReloadSpacesState interface {
space.ReloadSpacesState
}
// ReloadSpacesEnviron contains the methods for requesting environ data.
type ReloadSpacesEnviron interface {
environs.EnvironConfigGetter
// GetEnviron returns the environs.Environ ("provider") associated
// with the model.
GetEnviron(environs.EnvironConfigGetter, environs.NewEnvironFunc) (environs.Environ, error)
}
// EnvironSpaces defines methods for handling spaces within a environ setting.
type EnvironSpaces interface {
// ReloadSpaces loads spaces and subnets from provider specified by environ
// into state.
// Currently it's an append-only operation, no spaces/subnets are deleted.
ReloadSpaces(context.ProviderCallContext, ReloadSpacesState, environs.BootstrapEnviron) error
}
// ReloadSpacesAPI provides the reload spaces API facade for version.
type ReloadSpacesAPI struct {
state ReloadSpacesState
environs ReloadSpacesEnviron
spaces EnvironSpaces
context context.ProviderCallContext
authorize ReloadSpacesAuthorizer
}
// NewReloadSpacesAPI creates a new ReloadSpacesAPI.
func NewReloadSpacesAPI(state ReloadSpacesState,
environs ReloadSpacesEnviron,
spaces EnvironSpaces,
context context.ProviderCallContext,
authorizer ReloadSpacesAuthorizer,
) *ReloadSpacesAPI {
return &ReloadSpacesAPI{
state: state,
environs: environs,
spaces: spaces,
context: context,
authorize: authorizer,
}
}
// ReloadSpaces refreshes spaces from the substrate.
func (api *ReloadSpacesAPI) ReloadSpaces() error {
if err := api.authorize(); err != nil {
return errors.Trace(err)
}
env, err := api.environs.GetEnviron(api.environs, environs.New)
if err != nil {
return errors.Trace(err)
}
return errors.Trace(api.spaces.ReloadSpaces(api.context, api.state, env))
}
// ReloadSpacesAuthorizer represents a way to authorize reload spaces.
type ReloadSpacesAuthorizer func() error
// AuthorizerState contains the methods used from state to authorize API
// requests.
type AuthorizerState interface {
// ModelTag returns the tag of this model.
ModelTag() names.ModelTag
}
// DefaultReloadSpacesAuthorizer creates a new ReloadSpacesAuthorizer for
// handling reload spaces.
func DefaultReloadSpacesAuthorizer(auth facade.Authorizer,
check BlockChecker,
state AuthorizerState,
) ReloadSpacesAuthorizer {
return func() error {
canWrite, err := auth.HasPermission(permission.WriteAccess, state.ModelTag())
if err != nil && !errors.IsNotFound(err) {
return errors.Trace(err)
}
if !canWrite {
return apiservererrors.ServerError(apiservererrors.ErrPerm)
}
if err := check.ChangeAllowed(); err != nil {
return errors.Trace(err)
}
return nil
}
}
// ReloadSpacesEnvirons returns a reload spaces environs type.
type ReloadSpacesEnvirons struct {
stateenvirons.EnvironConfigGetter
}
// GetEnviron returns the environs.Environ ("provider") associated
// with the model.
func (ReloadSpacesEnvirons) GetEnviron(st environs.EnvironConfigGetter, fn environs.NewEnvironFunc) (environs.Environ, error) {
return environs.GetEnviron(st, fn)
}
// DefaultReloadSpacesEnvirons creates a new ReloadSpacesEnviron from state.
func DefaultReloadSpacesEnvirons(st *state.State) (ReloadSpacesEnvirons, error) {
m, err := st.Model()
if err != nil {
return ReloadSpacesEnvirons{}, errors.Trace(err)
}
return ReloadSpacesEnvirons{
stateenvirons.EnvironConfigGetter{
Model: m,
},
}, nil
}
// EnvironSpacesAdapter allows the calling of ReloadSpaces from a type level,
// instead of a package level construct.
type EnvironSpacesAdapter struct{}
// ReloadSpaces loads spaces and subnets from provider specified by environ
// into state.
// Currently it's an append-only operation, no spaces/subnets are deleted.
func (EnvironSpacesAdapter) ReloadSpaces(ctx context.ProviderCallContext, st ReloadSpacesState, env environs.BootstrapEnviron) error {
return space.ReloadSpaces(ctx, st, env)
}