func (api *MachinerAPI) SetMachineAddresses(args params.SetMachinesAddresses) (params.ErrorResults, error) { results := params.ErrorResults{ Results: make([]params.ErrorResult, len(args.MachineAddresses)), } canModify, err := api.getCanModify() if err != nil { return results, err } for i, arg := range args.MachineAddresses { tag, err := names.ParseMachineTag(arg.Tag) if err != nil { results.Results[i].Error = common.ServerError(common.ErrPerm) continue } err = common.ErrPerm if canModify(tag) { var m *state.Machine m, err = api.getMachine(tag) if err == nil { addresses := params.NetworkAddresses(arg.Addresses) err = m.SetMachineAddresses(addresses...) } else if errors.IsNotFound(err) { err = common.ErrPerm } } results.Results[i].Error = common.ServerError(err) } return results, nil }
// SetProviderAddresses updates the list of known provider addresses // for each given entity. Only machine tags are accepted. func (a *InstancePollerAPI) SetProviderAddresses(args params.SetMachinesAddresses) (params.ErrorResults, error) { result := params.ErrorResults{ Results: make([]params.ErrorResult, len(args.MachineAddresses)), } canAccess, err := a.accessMachine() if err != nil { return result, err } for i, arg := range args.MachineAddresses { machine, err := a.getOneMachine(arg.Tag, canAccess) if err == nil { addrsToSet := params.NetworkAddresses(arg.Addresses) err = machine.SetProviderAddresses(addrsToSet...) } result.Results[i].Error = common.ServerError(err) } return result, nil }
// ProviderAddresses returns all addresses of the machine known to the // cloud provider. func (m *Machine) ProviderAddresses() ([]network.Address, error) { var results params.MachineAddressesResults args := params.Entities{Entities: []params.Entity{ {Tag: m.tag.String()}, }} err := m.facade.FacadeCall("ProviderAddresses", args, &results) if err != nil { return nil, errors.Trace(err) } if len(results.Results) != 1 { err := errors.Errorf("expected 1 result, got %d", len(results.Results)) return nil, err } result := results.Results[0] if result.Error != nil { return nil, result.Error } return params.NetworkAddresses(result.Addresses), nil }
func (c *Client) addOneMachine(p params.AddMachineParams) (*state.Machine, error) { if p.ParentId != "" && p.ContainerType == "" { return nil, fmt.Errorf("parent machine specified without container type") } if p.ContainerType != "" && p.Placement != nil { return nil, fmt.Errorf("container type and placement are mutually exclusive") } if p.Placement != nil { // Extract container type and parent from container placement directives. containerType, err := instance.ParseContainerType(p.Placement.Scope) if err == nil { p.ContainerType = containerType p.ParentId = p.Placement.Directive p.Placement = nil } } if p.ContainerType != "" || p.Placement != nil { // Guard against dubious client by making sure that // the following attributes can only be set when we're // not using placement. p.InstanceId = "" p.Nonce = "" p.HardwareCharacteristics = instance.HardwareCharacteristics{} p.Addrs = nil } if p.Series == "" { conf, err := c.api.state.EnvironConfig() if err != nil { return nil, err } p.Series = config.PreferredSeries(conf) } var placementDirective string if p.Placement != nil { env, err := c.api.state.Environment() if err != nil { return nil, err } // For 1.21 we should support both UUID and name, and with 1.22 // just support UUID if p.Placement.Scope != env.Name() && p.Placement.Scope != env.UUID() { return nil, fmt.Errorf("invalid environment name %q", p.Placement.Scope) } placementDirective = p.Placement.Directive } jobs, err := common.StateJobs(p.Jobs) if err != nil { return nil, err } template := state.MachineTemplate{ Series: p.Series, Constraints: p.Constraints, InstanceId: p.InstanceId, Jobs: jobs, Nonce: p.Nonce, HardwareCharacteristics: p.HardwareCharacteristics, Addresses: params.NetworkAddresses(p.Addrs), Placement: placementDirective, } if p.ContainerType == "" { return c.api.state.AddOneMachine(template) } if p.ParentId != "" { return c.api.state.AddMachineInsideMachine(template, p.ParentId, p.ContainerType) } return c.api.state.AddMachineInsideNewMachine(template, template, p.ContainerType) }
func (mm *MachineManagerAPI) addOneMachine(p params.AddMachineParams) (*state.Machine, error) { if p.ParentId != "" && p.ContainerType == "" { return nil, fmt.Errorf("parent machine specified without container type") } if p.ContainerType != "" && p.Placement != nil { return nil, fmt.Errorf("container type and placement are mutually exclusive") } if p.Placement != nil { // Extract container type and parent from container placement directives. containerType, err := instance.ParseContainerType(p.Placement.Scope) if err == nil { p.ContainerType = containerType p.ParentId = p.Placement.Directive p.Placement = nil } } if p.ContainerType != "" || p.Placement != nil { // Guard against dubious client by making sure that // the following attributes can only be set when we're // not using placement. p.InstanceId = "" p.Nonce = "" p.HardwareCharacteristics = instance.HardwareCharacteristics{} p.Addrs = nil } if p.Series == "" { conf, err := mm.st.ModelConfig() if err != nil { return nil, err } p.Series = config.PreferredSeries(conf) } var placementDirective string if p.Placement != nil { env, err := mm.st.Model() if err != nil { return nil, err } // For 1.21 we should support both UUID and name, and with 1.22 // just support UUID if p.Placement.Scope != env.Name() && p.Placement.Scope != env.UUID() { return nil, fmt.Errorf("invalid model name %q", p.Placement.Scope) } placementDirective = p.Placement.Directive } volumes := make([]state.MachineVolumeParams, 0, len(p.Disks)) for _, cons := range p.Disks { if cons.Count == 0 { return nil, errors.Errorf("invalid volume params: count not specified") } // Pool and Size are validated by AddMachineX. volumeParams := state.VolumeParams{ Pool: cons.Pool, Size: cons.Size, } volumeAttachmentParams := state.VolumeAttachmentParams{} for i := uint64(0); i < cons.Count; i++ { volumes = append(volumes, state.MachineVolumeParams{ volumeParams, volumeAttachmentParams, }) } } jobs, err := common.StateJobs(p.Jobs) if err != nil { return nil, err } template := state.MachineTemplate{ Series: p.Series, Constraints: p.Constraints, Volumes: volumes, InstanceId: p.InstanceId, Jobs: jobs, Nonce: p.Nonce, HardwareCharacteristics: p.HardwareCharacteristics, Addresses: params.NetworkAddresses(p.Addrs), Placement: placementDirective, } if p.ContainerType == "" { return mm.st.AddOneMachine(template) } if p.ParentId != "" { return mm.st.AddMachineInsideMachine(template, p.ParentId, p.ContainerType) } return mm.st.AddMachineInsideNewMachine(template, template, p.ContainerType) }