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