Пример #1
0
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
}
Пример #2
0
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 &params.StorageDetails{
		StorageTag:  si.Tag().String(),
		OwnerTag:    si.Owner().String(),
		Kind:        params.StorageKind(si.Kind()),
		Status:      common.EntityStatusFromState(status),
		Persistent:  persistent,
		Attachments: storageAttachmentDetails,
	}, nil
}
Пример #3
0
func createFilesystemDetails(
	st storageAccess, f state.Filesystem, attachments []state.FilesystemAttachment,
) (*params.FilesystemDetails, error) {

	details := &params.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
}
Пример #4
0
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
}
Пример #5
0
// 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
}