launchpad.net/~rogpeppe/juju-core/500-errgo-fix@v0.0.0-20140213181702-000000002356/worker/uniter/jujuc/context.go (about)

     1  // Copyright 2012, 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package jujuc
     5  
     6  import (
     7  	"strconv"
     8  	"strings"
     9  
    10  	"launchpad.net/errgo/errors"
    11  	"launchpad.net/juju-core/charm"
    12  	"launchpad.net/juju-core/state/api/params"
    13  )
    14  
    15  // Context is the interface that all hook helper commands
    16  // depend on to interact with the rest of the system.
    17  type Context interface {
    18  
    19  	// Unit returns the executing unit's name.
    20  	UnitName() string
    21  
    22  	// PublicAddress returns the executing unit's public address.
    23  	PublicAddress() (string, bool)
    24  
    25  	// PrivateAddress returns the executing unit's private address.
    26  	PrivateAddress() (string, bool)
    27  
    28  	// OpenPort marks the supplied port for opening when the executing unit's
    29  	// service is exposed.
    30  	OpenPort(protocol string, port int) error
    31  
    32  	// ClosePort ensures the supplied port is closed even when the executing
    33  	// unit's service is exposed (unless it is opened separately by a co-
    34  	// located unit).
    35  	ClosePort(protocol string, port int) error
    36  
    37  	// Config returns the current service configuration of the executing unit.
    38  	ConfigSettings() (charm.Settings, error)
    39  
    40  	// HookRelation returns the ContextRelation associated with the executing
    41  	// hook if it was found, and whether it was found.
    42  	HookRelation() (ContextRelation, bool)
    43  
    44  	// RemoteUnitName returns the name of the remote unit the hook execution
    45  	// is associated with if it was found, and whether it was found.
    46  	RemoteUnitName() (string, bool)
    47  
    48  	// Relation returns the relation with the supplied id if it was found, and
    49  	// whether it was found.
    50  	Relation(id int) (ContextRelation, bool)
    51  
    52  	// RelationIds returns the ids of all relations the executing unit is
    53  	// currently participating in.
    54  	RelationIds() []int
    55  
    56  	// OwnerTag returns the owner of the service the executing units belongs to
    57  	OwnerTag() string
    58  }
    59  
    60  // ContextRelation expresses the capabilities of a hook with respect to a relation.
    61  type ContextRelation interface {
    62  
    63  	// Id returns an integer which uniquely identifies the relation.
    64  	Id() int
    65  
    66  	// Name returns the name the locally executing charm assigned to this relation.
    67  	Name() string
    68  
    69  	// FakeId returns a string of the form "relation-name:123", which uniquely
    70  	// identifies the relation to the hook. In reality, the identification
    71  	// of the relation is the integer following the colon, but the composed
    72  	// name is useful to humans observing it.
    73  	FakeId() string
    74  
    75  	// Settings allows read/write access to the local unit's settings in
    76  	// this relation.
    77  	Settings() (Settings, error)
    78  
    79  	// UnitNames returns a list of the remote units in the relation.
    80  	UnitNames() []string
    81  
    82  	// ReadSettings returns the settings of any remote unit in the relation.
    83  	ReadSettings(unit string) (params.RelationSettings, error)
    84  }
    85  
    86  // Settings is implemented by types that manipulate unit settings.
    87  type Settings interface {
    88  	Map() params.RelationSettings
    89  	Set(string, string)
    90  	Delete(string)
    91  }
    92  
    93  // newRelationIdValue returns a gnuflag.Value for convenient parsing of relation
    94  // ids in ctx.
    95  func newRelationIdValue(ctx Context, result *int) *relationIdValue {
    96  	v := &relationIdValue{result: result, ctx: ctx}
    97  	id := -1
    98  	if r, found := ctx.HookRelation(); found {
    99  		id = r.Id()
   100  		v.value = r.FakeId()
   101  	}
   102  	*result = id
   103  	return v
   104  }
   105  
   106  // relationIdValue implements gnuflag.Value for use in relation commands.
   107  type relationIdValue struct {
   108  	result *int
   109  	ctx    Context
   110  	value  string
   111  }
   112  
   113  // String returns the current value.
   114  func (v *relationIdValue) String() string {
   115  	return v.value
   116  }
   117  
   118  // Set interprets value as a relation id, if possible, and returns an error
   119  // if it is not known to the system. The parsed relation id will be written
   120  // to v.result.
   121  func (v *relationIdValue) Set(value string) error {
   122  	trim := value
   123  	if idx := strings.LastIndex(trim, ":"); idx != -1 {
   124  		trim = trim[idx+1:]
   125  	}
   126  	id, err := strconv.Atoi(trim)
   127  	if err != nil {
   128  		return errors.Newf("invalid relation id")
   129  	}
   130  	if _, found := v.ctx.Relation(id); !found {
   131  		return errors.Newf("unknown relation id")
   132  	}
   133  	*v.result = id
   134  	v.value = value
   135  	return nil
   136  }