github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/api/controller/firewaller/machine.go (about) 1 // Copyright 2014 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/errors" 10 "github.com/juju/names/v5" 11 12 apiwatcher "github.com/juju/juju/api/watcher" 13 "github.com/juju/juju/core/instance" 14 "github.com/juju/juju/core/life" 15 "github.com/juju/juju/core/network" 16 "github.com/juju/juju/core/watcher" 17 "github.com/juju/juju/rpc/params" 18 ) 19 20 // Machine represents a juju machine as seen by the firewaller worker. 21 type Machine struct { 22 st *Client 23 tag names.MachineTag 24 life life.Value 25 } 26 27 // Tag returns the machine tag. 28 func (m *Machine) Tag() names.MachineTag { 29 return m.tag 30 } 31 32 // WatchUnits starts a StringsWatcher to watch all units assigned to 33 // the machine. 34 func (m *Machine) WatchUnits() (watcher.StringsWatcher, error) { 35 var results params.StringsWatchResults 36 args := params.Entities{ 37 Entities: []params.Entity{{Tag: m.tag.String()}}, 38 } 39 err := m.st.facade.FacadeCall("WatchUnits", args, &results) 40 if err != nil { 41 return nil, err 42 } 43 if len(results.Results) != 1 { 44 return nil, fmt.Errorf("expected 1 result, got %d", len(results.Results)) 45 } 46 result := results.Results[0] 47 if result.Error != nil { 48 return nil, result.Error 49 } 50 w := apiwatcher.NewStringsWatcher(m.st.facade.RawAPICaller(), result) 51 return w, nil 52 } 53 54 // InstanceId returns the provider specific instance id for this 55 // machine, or a CodeNotProvisioned error, if not set. 56 func (m *Machine) InstanceId() (instance.Id, error) { 57 var results params.StringResults 58 args := params.Entities{ 59 Entities: []params.Entity{{Tag: m.tag.String()}}, 60 } 61 err := m.st.facade.FacadeCall("InstanceId", args, &results) 62 if err != nil { 63 return "", err 64 } 65 if len(results.Results) != 1 { 66 return "", fmt.Errorf("expected 1 result, got %d", len(results.Results)) 67 } 68 result := results.Results[0] 69 if result.Error != nil { 70 if params.IsCodeNotProvisioned(result.Error) { 71 return "", errors.NotProvisionedf("machine %v", m.tag.Id()) 72 } 73 return "", result.Error 74 } 75 return instance.Id(result.Result), nil 76 } 77 78 // Life returns the machine's life cycle value. 79 func (m *Machine) Life() life.Value { 80 return m.life 81 } 82 83 // IsManual returns true if the machine was manually provisioned. 84 func (m *Machine) IsManual() (bool, error) { 85 var results params.BoolResults 86 args := params.Entities{ 87 Entities: []params.Entity{{Tag: m.tag.String()}}, 88 } 89 err := m.st.facade.FacadeCall("AreManuallyProvisioned", args, &results) 90 if err != nil { 91 return false, err 92 } 93 if len(results.Results) != 1 { 94 return false, fmt.Errorf("expected 1 result, got %d", len(results.Results)) 95 } 96 result := results.Results[0] 97 if result.Error != nil { 98 return false, result.Error 99 } 100 return result.Result, nil 101 } 102 103 // OpenedMachinePortRanges queries the open port ranges for all units on this 104 // machine and returns back two maps where keys are unit names and values are 105 // open port range groupings by subnet CIDR and endpoint name. 106 func (m *Machine) OpenedMachinePortRanges() (byUnitAndCIDR map[names.UnitTag]network.GroupedPortRanges, byUnitAndEndpoint map[names.UnitTag]network.GroupedPortRanges, err error) { 107 var results params.OpenMachinePortRangesResults 108 args := params.Entities{ 109 Entities: []params.Entity{{Tag: m.tag.String()}}, 110 } 111 if err = m.st.facade.FacadeCall("OpenedMachinePortRanges", args, &results); err != nil { 112 return nil, nil, err 113 } 114 if len(results.Results) != 1 { 115 return nil, nil, fmt.Errorf("expected 1 result, got %d", len(results.Results)) 116 } 117 result := results.Results[0] 118 if result.Error != nil { 119 return nil, nil, result.Error 120 } 121 122 byUnitAndCIDR = make(map[names.UnitTag]network.GroupedPortRanges) 123 byUnitAndEndpoint = make(map[names.UnitTag]network.GroupedPortRanges) 124 for unitTagStr, unitPortRangeList := range result.UnitPortRanges { 125 unitTag, err := names.ParseUnitTag(unitTagStr) 126 if err != nil { 127 return nil, nil, errors.Trace(err) 128 } 129 130 byUnitAndCIDR[unitTag] = make(network.GroupedPortRanges) 131 byUnitAndEndpoint[unitTag] = make(network.GroupedPortRanges) 132 133 for _, unitPortRanges := range unitPortRangeList { 134 portList := make([]network.PortRange, len(unitPortRanges.PortRanges)) 135 for i, pr := range unitPortRanges.PortRanges { 136 portList[i] = pr.NetworkPortRange() 137 } 138 139 byUnitAndEndpoint[unitTag][unitPortRanges.Endpoint] = append(byUnitAndEndpoint[unitTag][unitPortRanges.Endpoint], portList...) 140 for _, cidr := range unitPortRanges.SubnetCIDRs { 141 byUnitAndCIDR[unitTag][cidr] = append(byUnitAndCIDR[unitTag][cidr], portList...) 142 } 143 } 144 } 145 return byUnitAndCIDR, byUnitAndEndpoint, nil 146 }