Beispiel #1
0
func unitMatchSubnet(u *state.Unit, patterns []string) (bool, bool, error) {
	pub, pubErr := u.PublicAddress()
	if pubErr != nil && !network.IsNoAddress(pubErr) {
		return true, false, errors.Trace(pubErr)
	}
	priv, privErr := u.PrivateAddress()
	if privErr != nil && !network.IsNoAddress(privErr) {
		return true, false, errors.Trace(privErr)
	}
	if pubErr != nil && privErr != nil {
		return true, false, nil
	}
	return matchSubnet(patterns, pub.Value, priv.Value)
}
Beispiel #2
0
// PrivateAddress returns the private address for each given unit, if set.
func (u *UniterAPIV3) PrivateAddress(args params.Entities) (params.StringResults, error) {
	result := params.StringResults{
		Results: make([]params.StringResult, len(args.Entities)),
	}
	canAccess, err := u.accessUnit()
	if err != nil {
		return params.StringResults{}, err
	}
	for i, entity := range args.Entities {
		tag, err := names.ParseUnitTag(entity.Tag)
		if err != nil {
			result.Results[i].Error = common.ServerError(common.ErrPerm)
			continue
		}
		err = common.ErrPerm
		if canAccess(tag) {
			var unit *state.Unit
			unit, err = u.getUnit(tag)
			if err == nil {
				var address network.Address
				address, err = unit.PrivateAddress()
				if err == nil {
					result.Results[i].Result = address.Value
				} else if network.IsNoAddress(err) {
					err = common.NoAddressSetError(tag, "private")
				}
			}
		}
		result.Results[i].Error = common.ServerError(err)
	}
	return result, nil
}
Beispiel #3
0
// runMachineUpdate connects via ssh to the machine and runs the update script.
func runMachineUpdate(machine *state.Machine, sshArg string) error {
	addr, err := machine.PublicAddress()
	if err != nil {
		if network.IsNoAddress(err) {
			return errors.Annotatef(err, "no appropriate public address found")
		}
		return errors.Trace(err)
	}
	return runViaSSH(addr.Value, sshArg)
}
Beispiel #4
0
func (s *NetworkSuite) TestNoAddressError(c *gc.C) {
	err := network.NoAddressf("boom")
	c.Assert(err, gc.ErrorMatches, "boom no address")
	c.Assert(network.IsNoAddress(err), jc.IsTrue)
	c.Assert(network.IsNoAddress(errors.New("address found")), jc.IsFalse)
}
Beispiel #5
0
func (u *UniterAPIV3) getOneNetworkConfig(canAccess common.AuthFunc, unitTagArg, bindingName string) ([]params.NetworkConfig, error) {
	unitTag, err := names.ParseUnitTag(unitTagArg)
	if err != nil {
		return nil, errors.Trace(err)
	}

	if bindingName == "" {
		return nil, errors.Errorf("binding name cannot be empty")
	}

	if !canAccess(unitTag) {
		return nil, common.ErrPerm
	}

	unit, err := u.getUnit(unitTag)
	if err != nil {
		return nil, errors.Trace(err)
	}

	service, err := unit.Service()
	if err != nil {
		return nil, errors.Trace(err)
	}

	bindings, err := service.EndpointBindings()
	if err != nil {
		return nil, errors.Trace(err)
	}
	boundSpace, known := bindings[bindingName]
	if !known {
		return nil, errors.Errorf("binding name %q not defined by the unit's charm", bindingName)
	}

	machineID, err := unit.AssignedMachineId()
	if err != nil {
		return nil, errors.Trace(err)
	}

	machine, err := u.st.Machine(machineID)
	if err != nil {
		return nil, errors.Trace(err)
	}

	var results []params.NetworkConfig
	if boundSpace == "" {
		logger.Debugf(
			"endpoint %q not explicitly bound to a space, using preferred private address for machine %q",
			bindingName, machineID,
		)

		privateAddress, err := machine.PrivateAddress()
		if err != nil && !network.IsNoAddress(err) {
			return nil, errors.Annotatef(err, "getting machine %q preferred private address", machineID)
		}

		results = append(results, params.NetworkConfig{
			Address: privateAddress.Value,
		})
		return results, nil
	} else {
		logger.Debugf("endpoint %q is explicitly bound to space %q", bindingName, boundSpace)
	}

	// TODO(dimitern): Use NetworkInterfaces() instead later, this is just for
	// the PoC to enable minimal network-get implementation returning just the
	// primary address.
	//
	// LKK Card: https://canonical.leankit.com/Boards/View/101652562/119258804
	addresses, err := machine.AllAddresses()
	if err != nil {
		return nil, errors.Annotate(err, "cannot get devices addresses")
	}
	logger.Infof(
		"geting network config for machine %q with addresses %+v, hosting unit %q of service %q, with bindings %+v",
		machineID, addresses, unit.Name(), service.Name(), bindings,
	)

	for _, addr := range addresses {
		subnet, err := addr.Subnet()
		if err != nil {
			return nil, errors.Annotatef(err, "cannot get subnet for address %q", addr)
		}
		if subnet == nil {
			logger.Debugf("skipping %s: not linked to a known subnet", addr)
			continue
		}
		if space := subnet.SpaceName(); space != boundSpace {
			logger.Debugf("skipping %s: want bound to space %q, got space %q", addr, boundSpace, space)
			continue
		}
		logger.Debugf("endpoint %q bound to space %q has address %q", bindingName, boundSpace, addr)

		// TODO(dimitern): Fill in the rest later (see linked LKK card above).
		results = append(results, params.NetworkConfig{
			Address: addr.Value(),
		})
	}

	return results, nil
}