// getSecretKeyLoginResponsePayload returns the information required by the // client to login to the controller securely. func (h *registerUserHandler) getSecretKeyLoginResponsePayload( st *state.State, userTag names.UserTag, ) (*params.SecretKeyLoginResponsePayload, error) { if !st.IsController() { return nil, errors.New("state is not for a controller") } payload := params.SecretKeyLoginResponsePayload{ CACert: st.CACert(), ControllerUUID: st.ControllerUUID(), } return &payload, nil }
// EnableHASingle applies a single ControllersServersSpec specification to the current environment. // Exported so it can be called by the legacy client API in the client package. func EnableHASingle(st *state.State, spec params.ControllersSpec) (params.ControllersChanges, error) { if !st.IsController() { return params.ControllersChanges{}, errors.New("unsupported with hosted models") } // Check if changes are allowed and the command may proceed. blockChecker := common.NewBlockChecker(st) if err := blockChecker.ChangeAllowed(); err != nil { return params.ControllersChanges{}, errors.Trace(err) } // Validate the environment tag if present. if spec.ModelTag != "" { tag, err := names.ParseModelTag(spec.ModelTag) if err != nil { return params.ControllersChanges{}, errors.Errorf("invalid model tag: %v", err) } if _, err := st.FindEntity(tag); err != nil { return params.ControllersChanges{}, err } } series := spec.Series if series == "" { ssi, err := st.ControllerInfo() if err != nil { return params.ControllersChanges{}, err } // We should always have at least one voting machine // If we *really* wanted we could just pick whatever series is // in the majority, but really, if we always copy the value of // the first one, then they'll stay in sync. if len(ssi.VotingMachineIds) == 0 { // Better than a panic()? return params.ControllersChanges{}, fmt.Errorf("internal error, failed to find any voting machines") } templateMachine, err := st.Machine(ssi.VotingMachineIds[0]) if err != nil { return params.ControllersChanges{}, err } series = templateMachine.Series() } changes, err := st.EnableHA(spec.NumControllers, spec.Constraints, series, spec.Placement) if err != nil { return params.ControllersChanges{}, err } return controllersChanges(changes), nil }
// getSecretKeyLoginResponsePayload returns the information required by the // client to login to the controller securely. func (h *registerUserHandler) getSecretKeyLoginResponsePayload( st *state.State, userTag names.UserTag, ) (*params.SecretKeyLoginResponsePayload, error) { if !st.IsController() { return nil, errors.New("state is not for a controller") } mac, err := h.createLocalLoginMacaroon(userTag) if err != nil { return nil, errors.Trace(err) } payload := params.SecretKeyLoginResponsePayload{ CACert: st.CACert(), ControllerUUID: st.ModelUUID(), Macaroon: mac, } return &payload, nil }
// NewAPI creates a new instance of the Backups API facade. func NewAPI(st *state.State, resources *common.Resources, authorizer common.Authorizer) (*API, error) { if !authorizer.AuthClient() { return nil, errors.Trace(common.ErrPerm) } // For now, backup operations are only permitted on the controller environment. if !st.IsController() { return nil, errors.New("backups are not supported for hosted models") } // Get the backup paths. dataDir, err := extractResourceValue(resources, "dataDir") if err != nil { return nil, errors.Trace(err) } logsDir, err := extractResourceValue(resources, "logDir") if err != nil { return nil, errors.Trace(err) } paths := backups.Paths{ DataDir: dataDir, LogsDir: logsDir, } // Build the API. machineID, err := extractResourceValue(resources, "machineID") if err != nil { return nil, errors.Trace(err) } b := API{ st: st, paths: &paths, machineID: machineID, } return &b, nil }
// EnableHASingle applies a single ControllersServersSpec specification to the current environment. // Exported so it can be called by the legacy client API in the client package. func EnableHASingle(st *state.State, spec params.ControllersSpec) (params.ControllersChanges, error) { if !st.IsController() { return params.ControllersChanges{}, errors.New("unsupported with hosted models") } // Check if changes are allowed and the command may proceed. blockChecker := common.NewBlockChecker(st) if err := blockChecker.ChangeAllowed(); err != nil { return params.ControllersChanges{}, errors.Trace(err) } // Validate the environment tag if present. if spec.ModelTag != "" { tag, err := names.ParseModelTag(spec.ModelTag) if err != nil { return params.ControllersChanges{}, errors.Errorf("invalid model tag: %v", err) } if _, err := st.FindEntity(tag); err != nil { return params.ControllersChanges{}, err } } series := spec.Series if series == "" { ssi, err := st.ControllerInfo() if err != nil { return params.ControllersChanges{}, err } // We should always have at least one voting machine // If we *really* wanted we could just pick whatever series is // in the majority, but really, if we always copy the value of // the first one, then they'll stay in sync. if len(ssi.VotingMachineIds) == 0 { // Better than a panic()? return params.ControllersChanges{}, errors.Errorf("internal error, failed to find any voting machines") } templateMachine, err := st.Machine(ssi.VotingMachineIds[0]) if err != nil { return params.ControllersChanges{}, err } series = templateMachine.Series() } if constraints.IsEmpty(&spec.Constraints) { // No constraints specified, so we'll use the constraints off // a running controller. controllerInfo, err := st.ControllerInfo() if err != nil { return params.ControllersChanges{}, err } // We'll sort the controller ids to find the smallest. // This will typically give the initial bootstrap machine. var controllerIds []int for _, id := range controllerInfo.MachineIds { idNum, err := strconv.Atoi(id) if err != nil { logger.Warningf("ignoring non numeric controller id %v", id) continue } controllerIds = append(controllerIds, idNum) } if len(controllerIds) == 0 { errors.Errorf("internal error, failed to find any controllers") } sort.Ints(controllerIds) // Load the controller machine and get its constraints. controllerId := controllerIds[0] controller, err := st.Machine(strconv.Itoa(controllerId)) if err != nil { return params.ControllersChanges{}, errors.Annotatef(err, "reading controller id %v", controllerId) } spec.Constraints, err = controller.Constraints() if err != nil { return params.ControllersChanges{}, errors.Annotatef(err, "reading constraints for controller id %v", controllerId) } } changes, err := st.EnableHA(spec.NumControllers, spec.Constraints, series, spec.Placement) if err != nil { return params.ControllersChanges{}, err } return controllersChanges(changes), nil }