github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/firewaller/manifold.go (about)

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