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