github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/apiserver/rsyslog/rsyslog.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package rsyslog
     5  
     6  import (
     7  	"github.com/juju/juju/apiserver/common"
     8  	"github.com/juju/juju/apiserver/params"
     9  	"github.com/juju/juju/cert"
    10  	"github.com/juju/juju/state"
    11  	"github.com/juju/juju/state/watcher"
    12  )
    13  
    14  func init() {
    15  	common.RegisterStandardFacade("Rsyslog", 0, NewRsyslogAPI)
    16  }
    17  
    18  // RsyslogAPI implements the API used by the rsyslog worker.
    19  type RsyslogAPI struct {
    20  	*common.EnvironWatcher
    21  
    22  	st             *state.State
    23  	resources      *common.Resources
    24  	authorizer     common.Authorizer
    25  	StateAddresser *common.StateAddresser
    26  	canModify      bool
    27  }
    28  
    29  // NewRsyslogAPI creates a new instance of the Rsyslog API.
    30  func NewRsyslogAPI(st *state.State, resources *common.Resources, authorizer common.Authorizer) (*RsyslogAPI, error) {
    31  	if !authorizer.AuthMachineAgent() && !authorizer.AuthUnitAgent() {
    32  		return nil, common.ErrPerm
    33  	}
    34  	return &RsyslogAPI{
    35  		EnvironWatcher: common.NewEnvironWatcher(st, resources, authorizer),
    36  		st:             st,
    37  		authorizer:     authorizer,
    38  		resources:      resources,
    39  		canModify:      authorizer.AuthEnvironManager(),
    40  		StateAddresser: common.NewStateAddresser(st),
    41  	}, nil
    42  }
    43  
    44  // SetRsyslogCert sets the rsyslog CACert.
    45  func (api *RsyslogAPI) SetRsyslogCert(args params.SetRsyslogCertParams) (params.ErrorResult, error) {
    46  	var result params.ErrorResult
    47  	if !api.canModify {
    48  		result.Error = common.ServerError(common.ErrBadCreds)
    49  		return result, nil
    50  	}
    51  	if _, err := cert.ParseCert(string(args.CACert)); err != nil {
    52  		result.Error = common.ServerError(err)
    53  		return result, nil
    54  	}
    55  
    56  	attrs := map[string]interface{}{
    57  		"rsyslog-ca-cert": string(args.CACert),
    58  		"rsyslog-ca-key":  string(args.CAKey),
    59  	}
    60  	if err := api.st.UpdateEnvironConfig(attrs, nil, nil); err != nil {
    61  		result.Error = common.ServerError(err)
    62  	}
    63  	return result, nil
    64  }
    65  
    66  // GetRsyslogConfig returns a RsyslogConfigResult.
    67  func (api *RsyslogAPI) GetRsyslogConfig(args params.Entities) (params.RsyslogConfigResults, error) {
    68  	result := params.RsyslogConfigResults{
    69  		Results: make([]params.RsyslogConfigResult, len(args.Entities)),
    70  	}
    71  	cfg, err := api.st.EnvironConfig()
    72  	if err != nil {
    73  		return result, err
    74  	}
    75  	for i := range args.Entities {
    76  		rsyslogCfg, err := newRsyslogConfig(cfg, api)
    77  		if err == nil {
    78  			result.Results[i] = params.RsyslogConfigResult{
    79  				CACert:    rsyslogCfg.CACert,
    80  				CAKey:     rsyslogCfg.CAKey,
    81  				Port:      rsyslogCfg.Port,
    82  				HostPorts: params.FromNetworkHostPorts(rsyslogCfg.HostPorts),
    83  			}
    84  		} else {
    85  			result.Results[i].Error = common.ServerError(err)
    86  		}
    87  	}
    88  	return result, nil
    89  }
    90  
    91  // WatchForRsyslogChanges starts a watcher to track if there are changes
    92  // that require we update the rsyslog.d configurations for a machine and/or unit.
    93  func (api *RsyslogAPI) WatchForRsyslogChanges(args params.Entities) (params.NotifyWatchResults, error) {
    94  	result := params.NotifyWatchResults{
    95  		Results: make([]params.NotifyWatchResult, len(args.Entities)),
    96  	}
    97  	for i := range args.Entities {
    98  		err := common.ErrPerm
    99  		if api.authorizer.AuthMachineAgent() || api.authorizer.AuthUnitAgent() {
   100  			watch := api.st.WatchAPIHostPorts()
   101  			// Consume the initial event. Technically, API
   102  			// calls to Watch 'transmit' the initial event
   103  			// in the Watch response. But NotifyWatchers
   104  			// have no state to transmit.
   105  			if _, ok := <-watch.Changes(); ok {
   106  				result.Results[i].NotifyWatcherId = api.resources.Register(watch)
   107  				err = nil
   108  			} else {
   109  				err = watcher.EnsureErr(watch)
   110  			}
   111  		}
   112  		result.Results[i].Error = common.ServerError(err)
   113  	}
   114  	return result, nil
   115  
   116  }