func (a *API) convertStateVolumeToParams(st state.Volume) (params.VolumeInstance, error) { volume := params.VolumeInstance{VolumeTag: st.VolumeTag().String()} if storage, err := st.StorageInstance(); err == nil { volume.StorageTag = storage.String() storageInstance, err := a.storage.StorageInstance(storage) if err != nil { err = errors.Annotatef(err, "getting storage instance %v for volume %v", storage, volume.VolumeTag) return params.VolumeInstance{}, err } owner := storageInstance.Owner() // only interested in Unit for now if unitTag, ok := owner.(names.UnitTag); ok { volume.UnitTag = unitTag.String() } } if info, err := st.Info(); err == nil { volume.HardwareId = info.HardwareId volume.Size = info.Size volume.Persistent = info.Persistent volume.VolumeId = info.VolumeId } status, err := st.Status() if err != nil { return params.VolumeInstance{}, errors.Trace(err) } volume.Status = common.EntityStatusFromState(status) return volume, nil }
func createStorageDetails(st storageAccess, si state.StorageInstance) (*params.StorageDetails, error) { // Get information from underlying volume or filesystem. var persistent bool var statusEntity status.StatusGetter if si.Kind() != state.StorageKindBlock { // TODO(axw) when we support persistent filesystems, // e.g. CephFS, we'll need to do set "persistent" // here too. filesystem, err := st.StorageInstanceFilesystem(si.StorageTag()) if err != nil { return nil, errors.Trace(err) } statusEntity = filesystem } else { volume, err := st.StorageInstanceVolume(si.StorageTag()) if err != nil { return nil, errors.Trace(err) } if info, err := volume.Info(); err == nil { persistent = info.Persistent } statusEntity = volume } status, err := statusEntity.Status() if err != nil { return nil, errors.Trace(err) } // Get unit storage attachments. var storageAttachmentDetails map[string]params.StorageAttachmentDetails storageAttachments, err := st.StorageAttachments(si.StorageTag()) if err != nil { return nil, errors.Trace(err) } if len(storageAttachments) > 0 { storageAttachmentDetails = make(map[string]params.StorageAttachmentDetails) for _, a := range storageAttachments { machineTag, location, err := storageAttachmentInfo(st, a) if err != nil { return nil, errors.Trace(err) } details := params.StorageAttachmentDetails{ a.StorageInstance().String(), a.Unit().String(), machineTag.String(), location, } storageAttachmentDetails[a.Unit().String()] = details } } return ¶ms.StorageDetails{ StorageTag: si.Tag().String(), OwnerTag: si.Owner().String(), Kind: params.StorageKind(si.Kind()), Status: common.EntityStatusFromState(status), Persistent: persistent, Attachments: storageAttachmentDetails, }, nil }
func createFilesystemDetails( st storageAccess, f state.Filesystem, attachments []state.FilesystemAttachment, ) (*params.FilesystemDetails, error) { details := ¶ms.FilesystemDetails{ FilesystemTag: f.FilesystemTag().String(), } if volumeTag, err := f.Volume(); err == nil { details.VolumeTag = volumeTag.String() } if info, err := f.Info(); err == nil { details.Info = storagecommon.FilesystemInfoFromState(info) } if len(attachments) > 0 { details.MachineAttachments = make(map[string]params.FilesystemAttachmentInfo, len(attachments)) for _, attachment := range attachments { stateInfo, err := attachment.Info() var info params.FilesystemAttachmentInfo if err == nil { info = storagecommon.FilesystemAttachmentInfoFromState(stateInfo) } details.MachineAttachments[attachment.Machine().String()] = info } } status, err := f.Status() if err != nil { return nil, errors.Trace(err) } details.Status = common.EntityStatusFromState(status) if storageTag, err := f.Storage(); err == nil { storageInstance, err := st.StorageInstance(storageTag) if err != nil { return nil, errors.Trace(err) } storageDetails, err := createStorageDetails(st, storageInstance) if err != nil { return nil, errors.Trace(err) } details.Storage = storageDetails } return details, nil }
func (m *ModelManagerAPI) getModelInfo(tag names.ModelTag) (params.ModelInfo, error) { st, err := m.state.ForModel(tag) if errors.IsNotFound(err) { return params.ModelInfo{}, common.ErrPerm } else if err != nil { return params.ModelInfo{}, errors.Trace(err) } defer st.Close() model, err := st.Model() if errors.IsNotFound(err) { return params.ModelInfo{}, common.ErrPerm } else if err != nil { return params.ModelInfo{}, errors.Trace(err) } cfg, err := model.Config() if err != nil { return params.ModelInfo{}, errors.Trace(err) } controllerCfg, err := st.ControllerConfig() if err != nil { return params.ModelInfo{}, errors.Trace(err) } users, err := model.Users() if err != nil { return params.ModelInfo{}, errors.Trace(err) } status, err := model.Status() if err != nil { return params.ModelInfo{}, errors.Trace(err) } owner := model.Owner() info := params.ModelInfo{ Name: cfg.Name(), UUID: cfg.UUID(), ControllerUUID: controllerCfg.ControllerUUID(), OwnerTag: owner.String(), Life: params.Life(model.Life().String()), Status: common.EntityStatusFromState(status), ProviderType: cfg.Type(), DefaultSeries: config.PreferredSeries(cfg), CloudTag: names.NewCloudTag(model.Cloud()).String(), CloudRegion: model.CloudRegion(), } if cloudCredentialTag, ok := model.CloudCredential(); ok { info.CloudCredentialTag = cloudCredentialTag.String() } authorizedOwner := m.authCheck(owner) == nil for _, user := range users { if !authorizedOwner && m.authCheck(user.UserTag) != nil { // The authenticated user is neither the owner // nor administrator, nor the model user, so // has no business knowing about the model user. continue } userInfo, err := common.ModelUserInfo(user, st) if err != nil { return params.ModelInfo{}, errors.Trace(err) } info.Users = append(info.Users, userInfo) } if len(info.Users) == 0 { // No users, which means the authenticated user doesn't // have access to the model. return params.ModelInfo{}, common.ErrPerm } canSeeMachines := authorizedOwner if !canSeeMachines { if canSeeMachines, err = m.hasWriteAccess(tag); err != nil { return params.ModelInfo{}, errors.Trace(err) } } if canSeeMachines { if info.Machines, err = common.ModelMachineInfo(st); err != nil { return params.ModelInfo{}, err } } return info, nil }
// ModelInfo returns information about the specified models. func (m *ModelManagerAPI) ModelInfo(args params.Entities) (params.ModelInfoResults, error) { results := params.ModelInfoResults{ Results: make([]params.ModelInfoResult, len(args.Entities)), } getModelInfo := func(arg params.Entity) (params.ModelInfo, error) { tag, err := names.ParseModelTag(arg.Tag) if err != nil { return params.ModelInfo{}, err } st, err := m.state.ForModel(tag) if errors.IsNotFound(err) { return params.ModelInfo{}, common.ErrPerm } else if err != nil { return params.ModelInfo{}, err } defer st.Close() model, err := st.Model() if errors.IsNotFound(err) { return params.ModelInfo{}, common.ErrPerm } else if err != nil { return params.ModelInfo{}, err } cfg, err := model.Config() if err != nil { return params.ModelInfo{}, err } users, err := model.Users() if err != nil { return params.ModelInfo{}, err } status, err := model.Status() if err != nil { return params.ModelInfo{}, err } owner := model.Owner() info := params.ModelInfo{ Name: cfg.Name(), UUID: cfg.UUID(), ControllerUUID: cfg.ControllerUUID(), OwnerTag: owner.String(), Life: params.Life(model.Life().String()), Status: common.EntityStatusFromState(status), ProviderType: cfg.Type(), DefaultSeries: config.PreferredSeries(cfg), } authorizedOwner := m.authCheck(owner) == nil for _, user := range users { if !authorizedOwner && m.authCheck(user.UserTag()) != nil { // The authenticated user is neither the owner // nor administrator, nor the model user, so // has no business knowing about the model user. continue } userInfo, err := common.ModelUserInfo(user) if err != nil { return params.ModelInfo{}, errors.Trace(err) } info.Users = append(info.Users, userInfo) } if len(info.Users) == 0 { // No users, which means the authenticated user doesn't // have access to the model. return params.ModelInfo{}, common.ErrPerm } return info, nil } for i, arg := range args.Entities { modelInfo, err := getModelInfo(arg) if err != nil { results.Results[i].Error = common.ServerError(err) continue } results.Results[i].Result = &modelInfo } return results, nil }