diff --git a/apiserver/params/network.go b/apiserver/params/network.go index 2bf8e19ed3..ef395036a9 100644 --- a/apiserver/params/network.go +++ b/apiserver/params/network.go @@ -120,6 +120,10 @@ type NetworkConfig struct { // inside an "iface" section of a interfaces(5) config file, e.g. // "up", "down", "mtu", etc. ExtraConfig map[string]string `json:"ExtraConfig,omitempty"` + + // RoutableSubnets contains an optional list of CIDRs that the network + // is able to route to. + RoutableSubnets []string `json:"RoutableSubnets,omitempty"` } // Port encapsulates a protocol and port number. It is used in API diff --git a/apiserver/provisioner/provisioner.go b/apiserver/provisioner/provisioner.go index 3737edc185..80f6b2c0f3 100644 --- a/apiserver/provisioner/provisioner.go +++ b/apiserver/provisioner/provisioner.go @@ -886,6 +886,15 @@ func (p *ProvisionerAPI) PrepareContainerInterfaceInfo(args params.Entities) (pa if err != nil { return result, errors.Annotate(err, "cannot allocate addresses") } + allSubnets, err := environ.Subnets(instId, []network.Id{}) + if err != nil { + return result, errors.Annotate(err, "cannot allocate addresses") + } + allSubnetCIDRs := []string{} + for _, cidr := range allSubnets { + allSubnetCIDRs = append(allSubnetCIDRs, cidr.CIDR) + } + // Loop over the passed container tags. for i, entity := range args.Entities { tag, err := names.ParseMachineTag(entity.Tag) @@ -949,8 +958,9 @@ func (p *ProvisionerAPI) PrepareContainerInterfaceInfo(args params.Entities) (pa ConfigType: string(network.ConfigStatic), Address: addr.Value(), // container's gateway is the host's primary NIC's IP. - GatewayAddress: interfaceInfo.Address.Value, - ExtraConfig: interfaceInfo.ExtraConfig, + GatewayAddress: interfaceInfo.Address.Value, + ExtraConfig: interfaceInfo.ExtraConfig, + RoutableSubnets: allSubnetCIDRs, }}, } } diff --git a/apiserver/server_test.go b/apiserver/server_test.go index a17379fac5..7093123309 100644 --- a/apiserver/server_test.go +++ b/apiserver/server_test.go @@ -90,7 +90,7 @@ func (s *serverSuite) TestStop(c *gc.C) { // The client has not necessarily seen the server shutdown yet, // so there are two possible errors. if err != rpc.ErrShutdown && err != io.ErrUnexpectedEOF { - c.Fatalf("unexpected error from request: %#T, expected rpc.ErrShutdown or io.ErrUnexpectedEOF", err) + c.Fatalf("unexpected error from request: %#v, expected rpc.ErrShutdown or io.ErrUnexpectedEOF", err) } // Check it can be stopped twice. diff --git a/provider/ec2/environ.go b/provider/ec2/environ.go index 97ce1639ac..e4a8b879ab 100644 --- a/provider/ec2/environ.go +++ b/provider/ec2/environ.go @@ -864,11 +864,6 @@ func (e *environ) NetworkInterfaces(instId instance.Id) ([]network.InterfaceInfo // by the provider for the specified instance. subnetIds must not be // empty. Implements NetworkingEnviron.Subnets. func (e *environ) Subnets(_ instance.Id, subnetIds []network.Id) ([]network.SubnetInfo, error) { - // At some point in the future an empty netIds may mean "fetch all subnets" - // but until that functionality is needed it's an error. - if len(subnetIds) == 0 { - return nil, errors.Errorf("subnetIds must not be empty") - } ec2Inst := e.ec2() // We can't filter by instance id here, unfortunately. resp, err := ec2Inst.Subnets(nil, nil) @@ -880,11 +875,12 @@ func (e *environ) Subnets(_ instance.Id, subnetIds []network.Id) ([]network.Subn for _, subId := range subnetIds { subIdSet[string(subId)] = false } + allSubnets := len(subnetIds) == 0 var results []network.SubnetInfo for _, subnet := range resp.Subnets { _, ok := subIdSet[subnet.Id] - if !ok { + if !allSubnets && !ok { logger.Tracef("subnet %q not in %v, skipping", subnet.Id, subnetIds) continue }