github.com/cloudbase/juju-core@v0.0.0-20140504232958-a7271ac7912f/state/apiserver/common/environwatcher.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package common
     5  
     6  import (
     7  	"launchpad.net/juju-core/environs"
     8  	"launchpad.net/juju-core/state"
     9  	"launchpad.net/juju-core/state/api/params"
    10  	"launchpad.net/juju-core/state/watcher"
    11  )
    12  
    13  // EnvironWatcher implements two common methods for use by various
    14  // facades - WatchForEnvironConfigChanges and EnvironConfig.
    15  type EnvironWatcher struct {
    16  	st                state.EnvironAccessor
    17  	resources         *Resources
    18  	getCanWatch       GetAuthFunc
    19  	getCanReadSecrets GetAuthFunc
    20  }
    21  
    22  // NewEnvironWatcher returns a new EnvironWatcher. Active watchers
    23  // will be stored in the provided Resources. The two GetAuthFunc
    24  // callbacks will be used on each invocation of the methods to
    25  // determine current permissions.
    26  // Right now, environment tags are not used, so both created AuthFuncs
    27  // are called with "" for tag, which means "the current environment".
    28  func NewEnvironWatcher(st state.EnvironAccessor, resources *Resources, getCanWatch, getCanReadSecrets GetAuthFunc) *EnvironWatcher {
    29  	return &EnvironWatcher{
    30  		st:                st,
    31  		resources:         resources,
    32  		getCanWatch:       getCanWatch,
    33  		getCanReadSecrets: getCanReadSecrets,
    34  	}
    35  }
    36  
    37  // WatchForEnvironConfigChanges returns a NotifyWatcher that observes
    38  // changes to the environment configuration.
    39  func (e *EnvironWatcher) WatchForEnvironConfigChanges() (params.NotifyWatchResult, error) {
    40  	result := params.NotifyWatchResult{}
    41  
    42  	canWatch, err := e.getCanWatch()
    43  	if err != nil {
    44  		return result, err
    45  	}
    46  	// TODO(dimitern) If we have multiple environments in state, use a
    47  	// tag argument here and as a method argument.
    48  	if !canWatch("") {
    49  		result.Error = ServerError(ErrPerm)
    50  		return result, ErrPerm
    51  	}
    52  
    53  	watch := e.st.WatchForEnvironConfigChanges()
    54  	// Consume the initial event. Technically, API
    55  	// calls to Watch 'transmit' the initial event
    56  	// in the Watch response. But NotifyWatchers
    57  	// have no state to transmit.
    58  	if _, ok := <-watch.Changes(); ok {
    59  		result.NotifyWatcherId = e.resources.Register(watch)
    60  	} else {
    61  		return result, watcher.MustErr(watch)
    62  	}
    63  	return result, nil
    64  }
    65  
    66  // EnvironConfig returns the current environment's configuration.
    67  func (e *EnvironWatcher) EnvironConfig() (params.EnvironConfigResult, error) {
    68  	result := params.EnvironConfigResult{}
    69  
    70  	canReadSecrets, err := e.getCanReadSecrets()
    71  	if err != nil {
    72  		return result, err
    73  	}
    74  
    75  	config, err := e.st.EnvironConfig()
    76  	if err != nil {
    77  		return result, err
    78  	}
    79  	allAttrs := config.AllAttrs()
    80  
    81  	// TODO(dimitern) If we have multiple environments in state, use a
    82  	// tag argument here and as a method argument.
    83  	if !canReadSecrets("") {
    84  		// Mask out any secrets in the environment configuration
    85  		// with values of the same type, so it'll pass validation.
    86  		//
    87  		// TODO(dimitern) 201309-26 bug #1231384
    88  		// Delete the code below and mark the bug as fixed,
    89  		// once it's live tested on MAAS and 1.16 compatibility
    90  		// is dropped.
    91  		env, err := environs.New(config)
    92  		if err != nil {
    93  			return result, err
    94  		}
    95  		secretAttrs, err := env.Provider().SecretAttrs(config)
    96  		for k := range secretAttrs {
    97  			allAttrs[k] = "not available"
    98  		}
    99  	}
   100  	result.Config = allAttrs
   101  	return result, nil
   102  }