launchpad.net/~rogpeppe/juju-core/500-errgo-fix@v0.0.0-20140213181702-000000002356/state/api/firewaller/unit.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package firewaller 5 6 import ( 7 "fmt" 8 9 "launchpad.net/errgo/errors" 10 "launchpad.net/juju-core/instance" 11 "launchpad.net/juju-core/names" 12 "launchpad.net/juju-core/state/api/base" 13 "launchpad.net/juju-core/state/api/params" 14 "launchpad.net/juju-core/state/api/watcher" 15 ) 16 17 // Unit represents a juju unit as seen by a firewaller worker. 18 type Unit struct { 19 st *State 20 tag string 21 life params.Life 22 } 23 24 // Name returns the name of the unit. 25 func (u *Unit) Name() string { 26 _, unitName, err := names.ParseTag(u.tag, names.UnitTagKind) 27 if err != nil { 28 panic(fmt.Sprintf("%q is not a valid unit tag", u.tag)) 29 } 30 return unitName 31 } 32 33 // Life returns the unit's life cycle value. 34 func (u *Unit) Life() params.Life { 35 return u.life 36 } 37 38 // Refresh updates the cached local copy of the unit's data. 39 func (u *Unit) Refresh() error { 40 life, err := u.st.life(u.tag) 41 if err != nil { 42 return base.WrapError(err) 43 } 44 u.life = life 45 return nil 46 } 47 48 // Watch returns a watcher for observing changes to the unit. 49 func (u *Unit) Watch() (watcher.NotifyWatcher, error) { 50 var results params.NotifyWatchResults 51 args := params.Entities{ 52 Entities: []params.Entity{{Tag: u.tag}}, 53 } 54 err := u.st.caller.Call("Firewaller", "", "Watch", args, &results) 55 if err != nil { 56 return nil, base.WrapError(err) 57 } 58 if len(results.Results) != 1 { 59 return nil, errors.Newf("expected one result, got %d", len(results.Results)) 60 } 61 result := results.Results[0] 62 if result.Error != nil { 63 return nil, result.Error 64 } 65 w := watcher.NewNotifyWatcher(u.st.caller, result) 66 return w, nil 67 } 68 69 // Service returns the service. 70 func (u *Unit) Service() (*Service, error) { 71 serviceTag := names.ServiceTag(names.UnitService(u.Name())) 72 service := &Service{ 73 st: u.st, 74 tag: serviceTag, 75 } 76 // Call Refresh() immediately to get the up-to-date 77 // life and other needed locally cached fields. 78 err := service.Refresh() 79 if err != nil { 80 return nil, base.WrapError(err) 81 } 82 return service, nil 83 } 84 85 // OpenedPorts returns the list of opened ports for this unit. 86 // 87 // NOTE: This differs from state.Unit.OpenedPorts() by returning 88 // an error as well, because it needs to make an API call. 89 func (u *Unit) OpenedPorts() ([]instance.Port, error) { 90 var results params.PortsResults 91 args := params.Entities{ 92 Entities: []params.Entity{{Tag: u.tag}}, 93 } 94 err := u.st.caller.Call("Firewaller", "", "OpenedPorts", args, &results) 95 if err != nil { 96 return nil, base.WrapError(err) 97 } 98 if len(results.Results) != 1 { 99 return nil, errors.Newf("expected one result, got %d", len(results.Results)) 100 } 101 result := results.Results[0] 102 if result.Error != nil { 103 return nil, result.Error 104 } 105 return result.Ports, nil 106 } 107 108 // AssignedMachine returns the tag of this unit's assigned machine (if 109 // any), or a CodeNotAssigned error. 110 func (u *Unit) AssignedMachine() (string, error) { 111 var results params.StringResults 112 args := params.Entities{ 113 Entities: []params.Entity{{Tag: u.tag}}, 114 } 115 err := u.st.caller.Call("Firewaller", "", "GetAssignedMachine", args, &results) 116 if err != nil { 117 return "", base.WrapError(err) 118 } 119 if len(results.Results) != 1 { 120 return "", errors.Newf("expected one result, got %d", len(results.Results)) 121 } 122 result := results.Results[0] 123 if result.Error != nil { 124 return "", result.Error 125 } 126 return result.Result, nil 127 }