github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/controllerport/manifold.go (about) 1 // Copyright 2018 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package controllerport 5 6 import ( 7 "github.com/juju/errors" 8 "github.com/juju/pubsub" 9 "gopkg.in/juju/worker.v1" 10 "gopkg.in/juju/worker.v1/dependency" 11 12 "github.com/juju/juju/agent" 13 "github.com/juju/juju/controller" 14 "github.com/juju/juju/state" 15 workerstate "github.com/juju/juju/worker/state" 16 ) 17 18 // Logger defines the methods needed for the worker to log messages. 19 type Logger interface { 20 Debugf(string, ...interface{}) 21 Infof(string, ...interface{}) 22 Errorf(string, ...interface{}) 23 } 24 25 // ManifoldConfig holds the information necessary to determine the controller 26 // api port and keep it up to date. 27 type ManifoldConfig struct { 28 AgentName string 29 HubName string 30 StateName string 31 32 Logger Logger 33 UpdateControllerAPIPort func(int) error 34 35 GetControllerConfig func(*state.State) (controller.Config, error) 36 NewWorker func(Config) (worker.Worker, error) 37 } 38 39 // Validate validates the manifold configuration. 40 func (config ManifoldConfig) Validate() error { 41 if config.AgentName == "" { 42 return errors.NotValidf("empty AgentName") 43 } 44 if config.HubName == "" { 45 return errors.NotValidf("empty HubName") 46 } 47 if config.StateName == "" { 48 return errors.NotValidf("empty StateName") 49 } 50 if config.Logger == nil { 51 return errors.NotValidf("nil Logger") 52 } 53 if config.UpdateControllerAPIPort == nil { 54 return errors.NotValidf("nil UpdateControllerAPIPort") 55 } 56 if config.GetControllerConfig == nil { 57 return errors.NotValidf("nil GetControllerConfig") 58 } 59 if config.NewWorker == nil { 60 return errors.NotValidf("nil NewWorker") 61 } 62 return nil 63 } 64 65 // Manifold returns a dependency.Manifold that will run an HTTP server 66 // worker. The manifold outputs an *apiserverhttp.Mux, for other workers 67 // to register handlers against. 68 func Manifold(config ManifoldConfig) dependency.Manifold { 69 return dependency.Manifold{ 70 Inputs: []string{ 71 config.AgentName, 72 config.HubName, 73 config.StateName, 74 }, 75 Start: config.start, 76 } 77 } 78 79 // start is a method on ManifoldConfig because it's more readable than a closure. 80 func (config ManifoldConfig) start(context dependency.Context) (worker.Worker, error) { 81 if err := config.Validate(); err != nil { 82 return nil, errors.Trace(err) 83 } 84 85 var agent agent.Agent 86 if err := context.Get(config.AgentName, &agent); err != nil { 87 return nil, errors.Trace(err) 88 } 89 90 var hub *pubsub.StructuredHub 91 if err := context.Get(config.HubName, &hub); err != nil { 92 return nil, errors.Trace(err) 93 } 94 95 var stTracker workerstate.StateTracker 96 if err := context.Get(config.StateName, &stTracker); err != nil { 97 return nil, errors.Trace(err) 98 } 99 statePool, err := stTracker.Use() 100 if err != nil { 101 return nil, errors.Trace(err) 102 } 103 defer stTracker.Done() 104 105 systemState := statePool.SystemState() 106 controllerConfig, err := config.GetControllerConfig(systemState) 107 if err != nil { 108 return nil, errors.Annotate(err, "unable to get controller config") 109 } 110 controllerAPIPort := controllerConfig.ControllerAPIPort() 111 112 w, err := config.NewWorker(Config{ 113 AgentConfig: agent.CurrentConfig(), 114 Hub: hub, 115 Logger: config.Logger, 116 ControllerAPIPort: controllerAPIPort, 117 UpdateControllerAPIPort: config.UpdateControllerAPIPort, 118 }) 119 if err != nil { 120 return nil, errors.Trace(err) 121 } 122 return w, nil 123 } 124 125 // GetControllerConfig gets the controller config from the given state 126 // - it's a shim so we can test the manifold without a state suite. 127 func GetControllerConfig(st *state.State) (controller.Config, error) { 128 return st.ControllerConfig() 129 }