launchpad.net/~rogpeppe/juju-core/500-errgo-fix@v0.0.0-20140213181702-000000002356/state/api/firewaller/service.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/names" 11 "launchpad.net/juju-core/state/api/base" 12 "launchpad.net/juju-core/state/api/params" 13 "launchpad.net/juju-core/state/api/watcher" 14 ) 15 16 // Service represents the state of a service. 17 type Service struct { 18 st *State 19 tag string 20 life params.Life 21 } 22 23 // Name returns the service name. 24 func (s *Service) Name() string { 25 _, serviceName, err := names.ParseTag(s.tag, names.ServiceTagKind) 26 if err != nil { 27 panic(fmt.Sprintf("%q is not a valid service tag", s.tag)) 28 } 29 return serviceName 30 } 31 32 // Watch returns a watcher for observing changes to a service. 33 func (s *Service) Watch() (watcher.NotifyWatcher, error) { 34 var results params.NotifyWatchResults 35 args := params.Entities{ 36 Entities: []params.Entity{{Tag: s.tag}}, 37 } 38 err := s.st.caller.Call("Firewaller", "", "Watch", args, &results) 39 if err != nil { 40 return nil, base.WrapError(err) 41 } 42 if len(results.Results) != 1 { 43 return nil, errors.Newf("expected one result, got %d", len(results.Results)) 44 } 45 result := results.Results[0] 46 if result.Error != nil { 47 return nil, result.Error 48 } 49 w := watcher.NewNotifyWatcher(s.st.caller, result) 50 return w, nil 51 } 52 53 // Life returns the service's current life state. 54 func (s *Service) Life() params.Life { 55 return s.life 56 } 57 58 // Refresh refreshes the contents of the Service from the underlying 59 // state. 60 func (s *Service) Refresh() error { 61 life, err := s.st.life(s.tag) 62 if err != nil { 63 return base.WrapError(err) 64 } 65 s.life = life 66 return nil 67 } 68 69 // IsExposed returns whether this service is exposed. The explicitly 70 // open ports (with open-port) for exposed services may be accessed 71 // from machines outside of the local deployment network. 72 // 73 // NOTE: This differs from state.Service.IsExposed() by returning 74 // an error as well, because it needs to make an API call. 75 func (s *Service) IsExposed() (bool, error) { 76 var results params.BoolResults 77 args := params.Entities{ 78 Entities: []params.Entity{{Tag: s.tag}}, 79 } 80 err := s.st.caller.Call("Firewaller", "", "GetExposed", args, &results) 81 if err != nil { 82 return false, base.WrapError(err) 83 } 84 if len(results.Results) != 1 { 85 return false, errors.Newf("expected one result, got %d", len(results.Results)) 86 } 87 result := results.Results[0] 88 if result.Error != nil { 89 return false, result.Error 90 } 91 return result.Result, nil 92 }