github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/apiserver/migrationtarget/migrationtarget.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package migrationtarget 5 6 import ( 7 "github.com/juju/errors" 8 "gopkg.in/juju/names.v2" 9 10 "github.com/juju/juju/apiserver/common" 11 "github.com/juju/juju/apiserver/facade" 12 "github.com/juju/juju/apiserver/params" 13 coremigration "github.com/juju/juju/core/migration" 14 "github.com/juju/juju/migration" 15 "github.com/juju/juju/permission" 16 "github.com/juju/juju/state" 17 ) 18 19 func init() { 20 common.RegisterStandardFacade("MigrationTarget", 1, NewAPI) 21 } 22 23 // API implements the API required for the model migration 24 // master worker when communicating with the target controller. 25 type API struct { 26 state *state.State 27 authorizer facade.Authorizer 28 resources facade.Resources 29 } 30 31 // NewAPI returns a new API. 32 func NewAPI( 33 st *state.State, 34 resources facade.Resources, 35 authorizer facade.Authorizer, 36 ) (*API, error) { 37 if err := checkAuth(authorizer, st); err != nil { 38 return nil, errors.Trace(err) 39 } 40 return &API{ 41 state: st, 42 authorizer: authorizer, 43 resources: resources, 44 }, nil 45 } 46 47 func checkAuth(authorizer facade.Authorizer, st *state.State) error { 48 if !authorizer.AuthClient() { 49 return errors.Trace(common.ErrPerm) 50 } 51 52 if isAdmin, err := authorizer.HasPermission(permission.SuperuserAccess, st.ControllerTag()); err != nil { 53 return errors.Trace(err) 54 } else if !isAdmin { 55 // The entire facade is only accessible to controller administrators. 56 return errors.Trace(common.ErrPerm) 57 } 58 return nil 59 } 60 61 // Prechecks ensure that the target controller is ready to accept a 62 // model migration. 63 func (api *API) Prechecks(model params.MigrationModelInfo) error { 64 ownerTag, err := names.ParseUserTag(model.OwnerTag) 65 if err != nil { 66 return errors.Trace(err) 67 } 68 return migration.TargetPrecheck( 69 migration.PrecheckShim(api.state), 70 coremigration.ModelInfo{ 71 UUID: model.UUID, 72 Name: model.Name, 73 Owner: ownerTag, 74 AgentVersion: model.AgentVersion, 75 }, 76 ) 77 } 78 79 // Import takes a serialized Juju model, deserializes it, and 80 // recreates it in the receiving controller. 81 func (api *API) Import(serialized params.SerializedModel) error { 82 _, st, err := migration.ImportModel(api.state, serialized.Bytes) 83 if err != nil { 84 return err 85 } 86 defer st.Close() 87 // TODO(mjs) - post import checks 88 // NOTE(fwereade) - checks here would be sensible, but we will 89 // also need to check after the binaries are imported too. 90 return err 91 } 92 93 func (api *API) getModel(args params.ModelArgs) (*state.Model, error) { 94 tag, err := names.ParseModelTag(args.ModelTag) 95 if err != nil { 96 return nil, errors.Trace(err) 97 } 98 model, err := api.state.GetModel(tag) 99 if err != nil { 100 return nil, errors.Trace(err) 101 } 102 if model.MigrationMode() != state.MigrationModeImporting { 103 return nil, errors.New("migration mode for the model is not importing") 104 } 105 return model, nil 106 } 107 108 // Abort removes the specified model from the database. It is an error to 109 // attempt to Abort a model that has a migration mode other than importing. 110 func (api *API) Abort(args params.ModelArgs) error { 111 model, err := api.getModel(args) 112 if err != nil { 113 return errors.Trace(err) 114 } 115 116 st, err := api.state.ForModel(model.ModelTag()) 117 if err != nil { 118 return errors.Trace(err) 119 } 120 defer st.Close() 121 122 return st.RemoveImportingModelDocs() 123 } 124 125 // Activate sets the migration mode of the model to "active". It is an error to 126 // attempt to Abort a model that has a migration mode other than importing. 127 func (api *API) Activate(args params.ModelArgs) error { 128 model, err := api.getModel(args) 129 if err != nil { 130 return errors.Trace(err) 131 } 132 133 // TODO(fwereade) - need to validate binaries here. 134 return model.SetMigrationMode(state.MigrationModeNone) 135 }