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 }