github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/uniter/runner/jujuc/network-get_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package jujuc_test 5 6 import ( 7 "fmt" 8 "strings" 9 10 "github.com/juju/cmd" 11 "github.com/juju/cmd/cmdtesting" 12 "github.com/juju/testing" 13 jc "github.com/juju/testing/checkers" 14 gc "gopkg.in/check.v1" 15 16 "github.com/juju/juju/apiserver/params" 17 "github.com/juju/juju/worker/uniter/runner/jujuc" 18 ) 19 20 type NetworkGetSuite struct { 21 ContextSuite 22 } 23 24 var _ = gc.Suite(&NetworkGetSuite{}) 25 26 func (s *NetworkGetSuite) SetUpSuite(c *gc.C) { 27 s.ContextSuite.SetUpSuite(c) 28 lookupHost := func(host string) (addrs []string, err error) { 29 return []string{"10.3.3.3"}, nil 30 } 31 testing.PatchValue(&jujuc.LookupHost, lookupHost) 32 } 33 34 func (s *NetworkGetSuite) createCommand(c *gc.C) cmd.Command { 35 hctx := s.GetHookContext(c, -1, "") 36 37 presetBindings := make(map[string]params.NetworkInfoResult) 38 presetBindings["known-relation"] = params.NetworkInfoResult{ 39 Info: []params.NetworkInfo{ 40 {MACAddress: "00:11:22:33:44:00", 41 InterfaceName: "eth0", 42 Addresses: []params.InterfaceAddress{ 43 { 44 Address: "10.10.0.23", 45 CIDR: "10.10.0.0/24", 46 }, 47 { 48 Address: "192.168.1.111", 49 CIDR: "192.168.1.0/24", 50 }, 51 }, 52 }, 53 {MACAddress: "00:11:22:33:44:11", 54 InterfaceName: "eth1", 55 Addresses: []params.InterfaceAddress{ 56 { 57 Address: "10.10.1.23", 58 CIDR: "10.10.1.0/24", 59 }, 60 { 61 Address: "192.168.2.111", 62 CIDR: "192.168.2.0/24", 63 }, 64 }, 65 }, 66 }, 67 } 68 presetBindings["known-extra"] = params.NetworkInfoResult{ 69 Info: []params.NetworkInfo{ 70 {MACAddress: "00:11:22:33:44:22", 71 InterfaceName: "eth2", 72 Addresses: []params.InterfaceAddress{ 73 { 74 Address: "10.20.1.42", 75 CIDR: "10.20.1.42/24", 76 }, 77 { 78 Address: "fc00::1", 79 CIDR: "fc00::/64", 80 }, 81 }, 82 }, 83 }, 84 } 85 presetBindings["valid-no-config"] = params.NetworkInfoResult{} 86 // Simulate known but unspecified bindings. 87 presetBindings["known-unbound"] = params.NetworkInfoResult{ 88 Info: []params.NetworkInfo{ 89 {MACAddress: "00:11:22:33:44:33", 90 InterfaceName: "eth3", 91 Addresses: []params.InterfaceAddress{ 92 { 93 Address: "10.33.1.8", 94 CIDR: "10.33.1.8/24", 95 }, 96 }, 97 }, 98 }, 99 } 100 // Simulate info with egress and ingress data. 101 presetBindings["ingress-egress"] = params.NetworkInfoResult{ 102 Info: []params.NetworkInfo{ 103 {MACAddress: "00:11:22:33:44:33", 104 InterfaceName: "eth3", 105 Addresses: []params.InterfaceAddress{ 106 { 107 Address: "10.33.1.8", 108 CIDR: "10.33.1.8/24", 109 }, 110 }, 111 }, 112 }, 113 IngressAddresses: []string{"100.1.2.3", "100.4.3.2"}, 114 EgressSubnets: []string{"192.168.1.0/8", "10.0.0.0/8"}, 115 } 116 117 // This should not happen. A hostname should never populate the address 118 // field. However, until the code is updated to prevent addresses from 119 // being populated by Hostnames (e.g. Change the Address field type from 120 // `string` to `net.IP` which will ensure all code paths exclude string 121 // population) we will have this check in place to ensure that hostnames 122 // are resolved to IPs and that hostnames populate a distinct field. 123 // `network-get --primary-address` and the like should only ever return 124 // IPs. 125 presetBindings["resolvable-hostname"] = params.NetworkInfoResult{ 126 Info: []params.NetworkInfo{ 127 {MACAddress: "00:11:22:33:44:33", 128 InterfaceName: "eth3", 129 Addresses: []params.InterfaceAddress{ 130 { 131 Address: "resolvable-hostname", 132 CIDR: "10.33.1.8/24", 133 }, 134 }, 135 }, 136 }, 137 IngressAddresses: []string{"resolvable-hostname"}, 138 } 139 140 hctx.info.NetworkInterface.NetworkInfoResults = presetBindings 141 142 com, err := jujuc.NewCommand(hctx, cmdString("network-get")) 143 c.Assert(err, jc.ErrorIsNil) 144 return jujuc.NewJujucCommandWrappedForTest(com) 145 } 146 147 func (s *NetworkGetSuite) TestNetworkGet(c *gc.C) { 148 for i, t := range []struct { 149 summary string 150 args []string 151 code int 152 out string 153 checkctx func(*gc.C, *cmd.Context) 154 }{{ 155 summary: "no arguments", 156 code: 2, 157 out: `no arguments specified`, 158 }, { 159 summary: "empty binding name specified", 160 code: 2, 161 args: []string{""}, 162 out: `no binding name specified`, 163 }, { 164 summary: "unknown binding given, no extra args given", 165 code: 1, 166 args: []string{"unknown"}, 167 out: `no network config found for binding "unknown"`, 168 }, { 169 summary: "unknown binding given, with additional args", 170 args: []string{"unknown", "--ingress-address"}, 171 code: 1, 172 out: `no network config found for binding "unknown"`, 173 }, { 174 summary: "API server returns no config for this binding, with --ingress-address", 175 args: []string{"valid-no-config", "--ingress-address"}, 176 code: 1, 177 out: `no network config found for binding "valid-no-config"`, 178 }, { 179 summary: "API server returns no config for this binding, no address args", 180 args: []string{"valid-no-config"}, 181 code: 1, 182 out: `no network config found for binding "valid-no-config"`, 183 }, { 184 summary: "explicitly bound, extra-binding name given with single flag arg", 185 args: []string{"known-extra", "--ingress-address"}, 186 out: "10.20.1.42", 187 }, { 188 summary: "explicitly bound, extra-binding name given with multiple flag args", 189 args: []string{"known-extra", "--ingress-address", "--bind-address"}, 190 out: ` 191 bind-address: 10.20.1.42 192 ingress-address: 10.20.1.42`[1:], 193 }, { 194 summary: "explicitly bound, extra-binding name given without extra args", 195 args: []string{"known-extra"}, 196 out: ` 197 bind-addresses: 198 - macaddress: "00:11:22:33:44:22" 199 interfacename: eth2 200 addresses: 201 - hostname: "" 202 address: 10.20.1.42 203 cidr: 10.20.1.42/24 204 - hostname: "" 205 address: fc00::1 206 cidr: fc00::/64`[1:], 207 }, { 208 summary: "explicitly bound relation name given with single flag arg", 209 args: []string{"known-relation", "--ingress-address"}, 210 out: "10.10.0.23", 211 }, { 212 summary: "explicitly bound relation name given without extra args", 213 args: []string{"known-relation"}, 214 out: ` 215 bind-addresses: 216 - macaddress: "00:11:22:33:44:00" 217 interfacename: eth0 218 addresses: 219 - hostname: "" 220 address: 10.10.0.23 221 cidr: 10.10.0.0/24 222 - hostname: "" 223 address: 192.168.1.111 224 cidr: 192.168.1.0/24 225 - macaddress: "00:11:22:33:44:11" 226 interfacename: eth1 227 addresses: 228 - hostname: "" 229 address: 10.10.1.23 230 cidr: 10.10.1.0/24 231 - hostname: "" 232 address: 192.168.2.111 233 cidr: 192.168.2.0/24`[1:], 234 }, { 235 summary: "no user requested binding falls back to binding address, with ingress-address arg", 236 args: []string{"known-unbound", "--ingress-address"}, 237 out: "10.33.1.8", 238 }, { 239 summary: "no user requested binding falls back to primary address, without address args", 240 args: []string{"known-unbound"}, 241 out: ` 242 bind-addresses: 243 - macaddress: "00:11:22:33:44:33" 244 interfacename: eth3 245 addresses: 246 - hostname: "" 247 address: 10.33.1.8 248 cidr: 10.33.1.8/24`[1:], 249 }, { 250 summary: "explicit ingress and egress information", 251 args: []string{"ingress-egress", "--ingress-address", "--bind-address", "--egress-subnets"}, 252 out: ` 253 bind-address: 10.33.1.8 254 egress-subnets: 255 - 192.168.1.0/8 256 - 10.0.0.0/8 257 ingress-address: 100.1.2.3`[1:], 258 }, { 259 summary: "explicit ingress and egress information, no extra args", 260 args: []string{"ingress-egress"}, 261 out: ` 262 bind-addresses: 263 - macaddress: "00:11:22:33:44:33" 264 interfacename: eth3 265 addresses: 266 - hostname: "" 267 address: 10.33.1.8 268 cidr: 10.33.1.8/24 269 egress-subnets: 270 - 192.168.1.0/8 271 - 10.0.0.0/8 272 ingress-addresses: 273 - 100.1.2.3 274 - 100.4.3.2`[1:], 275 }, { 276 summary: "a resolvable hostname as address, no args", 277 args: []string{"resolvable-hostname"}, 278 out: ` 279 bind-addresses: 280 - macaddress: "00:11:22:33:44:33" 281 interfacename: eth3 282 addresses: 283 - hostname: resolvable-hostname 284 address: 10.3.3.3 285 cidr: 10.33.1.8/24 286 ingress-addresses: 287 - 10.3.3.3`[1:], 288 }} { 289 c.Logf("test %d: %s", i, t.summary) 290 com := s.createCommand(c) 291 ctx := cmdtesting.Context(c) 292 code := cmd.Main(com, ctx, t.args) 293 c.Check(code, gc.Equals, t.code) 294 if code == 0 { 295 c.Check(bufferString(ctx.Stderr), gc.Equals, "") 296 expect := t.out 297 if expect != "" { 298 expect = expect + "\n" 299 } 300 c.Check(bufferString(ctx.Stdout), gc.Equals, expect) 301 } else { 302 c.Check(bufferString(ctx.Stdout), gc.Equals, "") 303 expect := fmt.Sprintf(`(.|\n)*ERROR %s\n`, t.out) 304 c.Check(bufferString(ctx.Stderr), gc.Matches, expect) 305 } 306 } 307 } 308 309 func (s *NetworkGetSuite) TestHelp(c *gc.C) { 310 311 helpLine := `Usage: network-get [options] <binding-name> [--ingress-address] [--bind-address] [--egress-subnets]` 312 313 com := s.createCommand(c) 314 ctx := cmdtesting.Context(c) 315 code := cmd.Main(com, ctx, []string{"--help"}) 316 c.Check(code, gc.Equals, 0) 317 318 c.Check(strings.Split(bufferString(ctx.Stdout), "\n")[0], gc.Equals, helpLine) 319 c.Check(bufferString(ctx.Stderr), gc.Equals, "") 320 }