// SampleCloudSpec returns an environs.CloudSpec that can be used to
// open a dummy Environ.
545052
func SampleCloudSpec() environs.CloudSpec {
	cred := cloud.NewCredential(cloud.UserPassAuthType, map[string]string{"username": "dummy", "password": "secret"})
	return environs.CloudSpec{
		Type:             "dummy",
		Name:             "dummy",
		Endpoint:         "dummy-endpoint",
		IdentityEndpoint: "dummy-identity-endpoint",
		Region:           "dummy-region",
		StorageEndpoint:  "dummy-storage-endpoint",
		Credential:       &cred,
	}
}
465977
func (p *environProvider) PrepareConfig(args environs.PrepareConfigParams) (*config.Config, error) {
	if err := p.validateCloudSpec(args.Cloud); err != nil {
		return nil, errors.Annotate(err, "validating cloud spec")
	}
	// Set the default filesystem-storage source.
	attrs := make(map[string]interface{})
	if _, ok := args.Config.StorageDefaultFilesystemSource(); !ok {
		attrs[config.StorageDefaultFilesystemSourceKey] = lxdStorageProviderType
	}
	if len(attrs) == 0 {
		return args.Config, nil
	}
	cfg, err := args.Config.Apply(attrs)
	return cfg, errors.Trace(err)
}
298823
func findInstanceSpec(
	controller bool,
	allImageMetadata []*imagemetadata.ImageMetadata,
	instanceTypes []instances.InstanceType,
	ic *instances.InstanceConstraint,
) (*instances.InstanceSpec, error) {
	logger.Debugf("received %d image(s)", len(allImageMetadata))
	if !controller {
		ic.Constraints = withDefaultNonControllerConstraints(ic.Constraints)
	}
	suitableImages := filterImages(allImageMetadata, ic)
	logger.Debugf("found %d suitable image(s)", len(suitableImages))
	images := instances.ImageMetadataToImages(suitableImages)
	return instances.FindInstanceSpec(images, ic, instanceTypes)
}
632794
func NewCloudSpec(
	resources facade.Resources,
	getCloudSpec func(names.ModelTag) (environs.CloudSpec, error),
	watchCloudSpec func(tag names.ModelTag) (state.NotifyWatcher, error),
	getAuthFunc common.GetAuthFunc,
) CloudSpecAPI {
	return cloudSpecAPI{resources, getCloudSpec, watchCloudSpec, getAuthFunc}
}
1017240
func (c *CloudService) CloudService() (*CloudService, error) {
	doc, err := c.cloudServiceDoc()
	if err != nil {
		return nil, errors.Trace(err)
	}
	if doc == nil {
		return nil, errors.NotFoundf("cloud service %v", c.Id())
	}
	c.doc = *doc
	return c, nil
}
1126951
func (g EnvironConfigGetter) CloudSpec() (environs.CloudSpec, error) {
	cloudName := g.Model.Cloud()
	regionName := g.Model.CloudRegion()
	credentialTag, _ := g.Model.CloudCredential()
	return CloudSpec(g.State, cloudName, regionName, credentialTag)
}
474207
func NewMockCloud(ctrl *gomock.Controller) *MockCloud {
	mock := &MockCloud{ctrl: ctrl}
	mock.recorder = &MockCloudMockRecorder{mock}
	return mock
}
829529
func (kc *kubeClient) GetEnvironment(envName string) (*app.SimpleEnvironment, error) {
	envNS, err := kc.getDeployableEnvironmentNamespace(envName)
	if err != nil {
		return nil, err
	}

	envStats, err := kc.getResourceQuota(envNS)
	if err != nil {
		return nil, err
	}

	env := &app.SimpleEnvironment{
		Type: "environment",
		Attributes: &app.SimpleEnvironmentAttributes{
			Name:  &envName,
			Quota: envStats,
		},
	}
	return env, nil
}
819868
func (g EnvironConfigGetter) CloudAPIVersion(spec environs.CloudSpec) (string, error) {
	// Only CAAS models have an API version we care about right now.
	if g.Model.Type() == state.ModelTypeIAAS {
		return "", nil
	}
	cfg, err := g.ModelConfig()
	if err != nil {
		return "", errors.Trace(err)
	}
	ctrlCfg, err := g.ControllerConfig()
	if err != nil {
		return "", errors.Trace(err)
	}
	newBroker := g.NewContainerBroker
	if newBroker == nil {
		newBroker = caas.New
	}
	broker, err := newBroker(environs.OpenParams{
		ControllerUUID: ctrlCfg.ControllerUUID(),
		Cloud:          spec,
		Config:         cfg,
	})
	if err != nil {
		return "", errors.Trace(err)
	}
	return broker.APIVersion()
}
795379
func (pm *VolumePluginMgr) FindRecyclablePluginBySpec(spec *Spec) (RecyclableVolumePlugin, error) {
	volumePlugin, err := pm.FindPluginBySpec(spec)
	if err != nil {
		return nil, err
	}
	if recyclableVolumePlugin, ok := volumePlugin.(RecyclableVolumePlugin); ok {
		return recyclableVolumePlugin, nil
	}
	return nil, fmt.Errorf("no recyclable volume plugin matched")
}
1026593
func findInstanceSpec(
	ctx context.ProviderCallContext,
	client compute.VirtualMachineImagesClient,
	instanceTypesMap map[string]instances.InstanceType,
	constraint *instances.InstanceConstraint,
	imageStream string,
) (*instances.InstanceSpec, error) {

	if !constraintHasArch(constraint, arch.AMD64) {
		// Azure only supports AMD64.
		return nil, errors.NotFoundf("%s in arch constraints", arch.AMD64)
	}

	image, err := imageutils.SeriesImage(ctx, constraint.Series, imageStream, constraint.Region, client)
	if err != nil {
		return nil, errors.Trace(err)
	}
	images := []instances.Image{*image}

	instanceTypes := make([]instances.InstanceType, 0, len(instanceTypesMap))
	for _, instanceType := range instanceTypesMap {
		instanceTypes = append(instanceTypes, instanceType)
	}
	constraint.Constraints = defaultToBaselineSpec(constraint.Constraints)
	return instances.FindInstanceSpec(images, constraint, instanceTypes)
}
652085
func (env *environ) StartInstance(ctx context.ProviderCallContext, args environs.StartInstanceParams) (*environs.StartInstanceResult, error) {
	// Start a new instance.

	spec, err := buildInstanceSpec(env, args)
	if err != nil {
		return nil, common.ZoneIndependentError(err)
	}

	if err := env.finishInstanceConfig(args, spec); err != nil {
		return nil, common.ZoneIndependentError(err)
	}

	// Validate availability zone.
	volumeAttachmentsZone, err := volumeAttachmentsZone(args.VolumeAttachments)
	if err != nil {
		return nil, common.ZoneIndependentError(err)
	}
	if err := validateAvailabilityZoneConsistency(args.AvailabilityZone, volumeAttachmentsZone); err != nil {
		return nil, errors.Trace(err)
	}

	raw, err := newRawInstance(env, ctx, args, spec)
	if err != nil {
		return nil, errors.Trace(err)
	}
	logger.Infof("started instance %q in zone %q", raw.ID, raw.ZoneName)
	inst := newInstance(raw, env)

	// Build the result.
	hwc := getHardwareCharacteristics(env, spec, inst)
	result := environs.StartInstanceResult{
		Instance: inst,
		Hardware: hwc,
	}
	return &result, nil
}
191878
func (u *UniterAPI) CloudSpec() (params.CloudSpecResult, error) {
	canAccess, err := u.accessCloudSpec()
	if err != nil {
		return params.CloudSpecResult{}, err
	}
	if !canAccess() {
		return params.CloudSpecResult{Error: common.ServerError(common.ErrPerm)}, nil
	}

	return u.cloudSpec.GetCloudSpec(u.m.Tag().(names.ModelTag)), nil
}
160858
func (e *environ) StartInstance(ctx context.ProviderCallContext, args environs.StartInstanceParams) (_ *environs.StartInstanceResult, resultErr error) {
	var inst *ec2Instance
	callback := args.StatusCallback
	defer func() {
		if resultErr == nil || inst == nil {
			return
		}
		if err := e.StopInstances(ctx, inst.Id()); err != nil {
			callback(status.Error, fmt.Sprintf("error stopping failed instance: %v", err), nil)
			logger.Errorf("error stopping failed instance: %v", err)
		}
	}()

	callback(status.Allocating, "Verifying availability zone", nil)

	annotateWrapError := func(received error, annotation string) error {
		if received == nil {
			return nil
		}
		// If there is a problem with authentication/authorisation,
		// we want a correctly typed error.
		annotatedErr := errors.Annotate(
			maybeConvertCredentialError(received, ctx),
			annotation)
		if common.IsCredentialNotValid(annotatedErr) {
			return annotatedErr
		}
		return common.ZoneIndependentError(annotatedErr)
	}

	wrapError := func(received error) error {
		return annotateWrapError(received, "")
	}

	// Verify the provided availability zone to start the instance in.  It's
	// provided via StartInstanceParams Constraints or AvailabilityZone.
	// The availability zone of existing volumes that are to be
	// attached to the machine must all match, and must be the same
	// as specified zone (if any).
	availabilityZone, placementSubnetID, err := e.deriveAvailabilityZoneAndSubnetID(ctx, args)
	if err != nil {
		// An IsNotValid error is returned if the zone is invalid;
		// this is a zone-specific error.
		zoneSpecific := errors.IsNotValid(err)
		if !zoneSpecific {
			return nil, wrapError(err)
		}
		return nil, err
	}

	arches := args.Tools.Arches()

	instanceTypes, err := e.supportedInstanceTypes(ctx)
	if err != nil {
		return nil, wrapError(err)
	}

	spec, err := findInstanceSpec(
		args.InstanceConfig.Controller != nil,
		args.ImageMetadata,
		instanceTypes,
		&instances.InstanceConstraint{
			Region:      e.cloud.Region,
			Series:      args.InstanceConfig.Series,
			Arches:      arches,
			Constraints: args.Constraints,
			Storage:     []string{ssdStorage, ebsStorage},
		},
	)
	if err != nil {
		return nil, wrapError(err)
	}
	tools, err := args.Tools.Match(tools.Filter{Arch: spec.Image.Arch})
	if err != nil {
		return nil, common.ZoneIndependentError(
			errors.Errorf("chosen architecture %v not present in %v", spec.Image.Arch, arches),
		)
	}

	if spec.InstanceType.Deprecated {
		logger.Infof("deprecated instance type specified: %s", spec.InstanceType.Name)
	}

	if err := args.InstanceConfig.SetTools(tools); err != nil {
		return nil, common.ZoneIndependentError(err)
	}
	if err := instancecfg.FinishInstanceConfig(args.InstanceConfig, e.Config()); err != nil {
		return nil, common.ZoneIndependentError(err)
	}

	callback(status.Allocating, "Making user data", nil)
	userData, err := providerinit.ComposeUserData(args.InstanceConfig, nil, AmazonRenderer{})
	if err != nil {
		return nil, common.ZoneIndependentError(
			errors.Annotate(err, "cannot make user data"),
		)
	}
	logger.Debugf("ec2 user data; %d bytes", len(userData))
	apiPorts := make([]int, 0, 2)
	if args.InstanceConfig.Controller != nil {
		apiPorts = append(apiPorts, args.InstanceConfig.Controller.Config.APIPort())
		if args.InstanceConfig.Controller.Config.AutocertDNSName() != "" {
			// Open port 80 as well as it handles Let's Encrypt HTTP challenge.
			apiPorts = append(apiPorts, 80)
		}
	} else {
		apiPorts = append(apiPorts, args.InstanceConfig.APIInfo.Ports()[0])
	}
	callback(status.Allocating, "Setting up groups", nil)
	groups, err := e.setUpGroups(ctx, args.ControllerUUID, args.InstanceConfig.MachineId, apiPorts)
	if err != nil {
		return nil, annotateWrapError(err, "cannot set up groups")
	}

	blockDeviceMappings := getBlockDeviceMappings(
		args.Constraints,
		args.InstanceConfig.Series,
		args.InstanceConfig.Controller != nil,
	)
	rootDiskSize := uint64(blockDeviceMappings[0].VolumeSize) * 1024

	// If --constraints spaces=foo was passed, the provisioner will populate
	// args.SubnetsToZones map. In AWS a subnet can span only one zone, so here
	// we build the reverse map zonesToSubnets, which we will use to below in
	// the RunInstance loop to provide an explicit subnet ID, rather than just
	// AZ. This ensures instances in the same group (units of an application or all
	// instances when adding a machine manually) will still be evenly
	// distributed across AZs, but only within subnets of the space constraint.
	//
	// TODO(dimitern): This should be done in a provider-independent way.
	if spaces := args.Constraints.IncludeSpaces(); len(spaces) > 1 {
		logger.Infof("ignoring all but the first positive space from constraints: %v", spaces)
	}

	var instResp *ec2.RunInstancesResp
	commonRunArgs := &ec2.RunInstances{
		MinCount:            1,
		MaxCount:            1,
		UserData:            userData,
		InstanceType:        spec.InstanceType.Name,
		SecurityGroups:      groups,
		BlockDeviceMappings: blockDeviceMappings,
		ImageId:             spec.Image.Id,
	}

	runArgs := commonRunArgs
	runArgs.AvailZone = availabilityZone

	haveVPCID := isVPCIDSet(e.ecfg().vpcID())
	var subnetIDsForZone []string
	var subnetErr error
	if haveVPCID {
		var allowedSubnetIDs []string
		if placementSubnetID != "" {
			allowedSubnetIDs = []string{placementSubnetID}
		} else {
			for subnetID := range args.SubnetsToZones {
				allowedSubnetIDs = append(allowedSubnetIDs, string(subnetID))
			}
		}
		subnetIDsForZone, subnetErr = getVPCSubnetIDsForAvailabilityZone(e.ec2, ctx, e.ecfg().vpcID(), availabilityZone, allowedSubnetIDs)
	} else if args.Constraints.HasSpaces() {
		subnetIDsForZone, subnetErr = findSubnetIDsForAvailabilityZone(availabilityZone, args.SubnetsToZones)
		if subnetErr == nil && placementSubnetID != "" {
			asSet := set.NewStrings(subnetIDsForZone...)
			if asSet.Contains(placementSubnetID) {
				subnetIDsForZone = []string{placementSubnetID}
			} else {
				subnetIDsForZone = nil
				subnetErr = errors.NotFoundf("subnets %q in AZ %q", placementSubnetID, availabilityZone)
			}
		}
	}

	switch {
	case subnetErr != nil && errors.IsNotFound(subnetErr):
		return nil, errors.Trace(subnetErr)
	case subnetErr != nil:
		return nil, errors.Annotatef(maybeConvertCredentialError(subnetErr, ctx), "getting subnets for zone %q", availabilityZone)
	case len(subnetIDsForZone) > 1:
		// With multiple equally suitable subnets, picking one at random
		// will allow for better instance spread within the same zone, and
		// still work correctly if we happen to pick a constrained subnet
		// (we'll just treat this the same way we treat constrained zones
		// and retry).
		runArgs.SubnetId = subnetIDsForZone[rand.Intn(len(subnetIDsForZone))]
		logger.Debugf("selected random subnet %q from all matching in zone %q", runArgs.SubnetId, availabilityZone)
	case len(subnetIDsForZone) == 1:
		runArgs.SubnetId = subnetIDsForZone[0]
		logger.Debugf("selected subnet %q in zone %q", runArgs.SubnetId, availabilityZone)
	}

	callback(status.Allocating, fmt.Sprintf("Trying to start instance in availability zone %q", availabilityZone), nil)
	instResp, err = runInstances(e.ec2, ctx, runArgs, callback)
	if err != nil {
		if !isZoneOrSubnetConstrainedError(err) {
			err = annotateWrapError(err, "cannot run instances")
		}
		return nil, err
	}
	if len(instResp.Instances) != 1 {
		return nil, errors.Errorf("expected 1 started instance, got %d", len(instResp.Instances))
	}

	inst = &ec2Instance{
		e:        e,
		Instance: &instResp.Instances[0],
	}
	instAZ := inst.Instance.AvailZone
	if haveVPCID {
		instVPC := e.ecfg().vpcID()
		instSubnet := inst.Instance.SubnetId
		logger.Infof("started instance %q in AZ %q, subnet %q, VPC %q", inst.Id(), instAZ, instSubnet, instVPC)
	} else {
		logger.Infof("started instance %q in AZ %q", inst.Id(), instAZ)
	}

	// Tag instance, for accounting and identification.
	instanceName := resourceName(
		names.NewMachineTag(args.InstanceConfig.MachineId), e.Config().Name(),
	)
	args.InstanceConfig.Tags[tagName] = instanceName
	if err := tagResources(e.ec2, ctx, args.InstanceConfig.Tags, string(inst.Id())); err != nil {
		return nil, annotateWrapError(err, "tagging instance")
	}

	// Tag the machine's root EBS volume, if it has one.
	if inst.Instance.RootDeviceType == "ebs" {
		cfg := e.Config()
		tags := tags.ResourceTags(
			names.NewModelTag(cfg.UUID()),
			names.NewControllerTag(args.ControllerUUID),
			cfg,
		)
		tags[tagName] = instanceName + "-root"
		if err := tagRootDisk(e.ec2, ctx, tags, inst.Instance); err != nil {
			return nil, annotateWrapError(err, "tagging root disk")
		}
	}

	hc := instance.HardwareCharacteristics{
		Arch:     &spec.Image.Arch,
		Mem:      &spec.InstanceType.Mem,
		CpuCores: &spec.InstanceType.CpuCores,
		CpuPower: spec.InstanceType.CpuPower,
		RootDisk: &rootDiskSize,
		// Tags currently not supported by EC2
		AvailabilityZone: &inst.Instance.AvailZone,
	}
	return &environs.StartInstanceResult{
		Instance: inst,
		Hardware: &hc,
	}, nil
}
1271171
func (metadata *IndexMetadata) hasCloud(cloud CloudSpec) bool {
	for _, metadataCloud := range metadata.Clouds {
		if metadataCloud.equals(&cloud) {
			return true
		}
	}
	return len(metadata.Clouds) == 0
}
193433
func (p environProvider) Open(args environs.OpenParams) (environs.Environ, error) {
	logger.Infof("opening model %q", args.Config.Name())

	e := new(environ)
	e.cloud = args.Cloud
	e.name = args.Config.Name()

	// The endpoints in public-clouds.yaml from 2.0-rc2
	// and before were wrong, so we use whatever is defined
	// in goamz/aws if available.
	if isBrokenCloud(e.cloud) {
		if region, ok := aws.Regions[e.cloud.Region]; ok {
			e.cloud.Endpoint = region.EC2Endpoint
		}
	}

	var err error
	e.ec2, err = awsClient(e.cloud)
	if err != nil {
		return nil, errors.Trace(err)
	}

	if err := e.SetConfig(args.Config); err != nil {
		return nil, errors.Trace(err)
	}
	return e, nil
}
56846
func newCSCloud(cfg *CSConfig) (*CSCloud, error) {
	cs := &CSCloud{
		projectID: cfg.Global.ProjectID,
		zone:      cfg.Global.Zone,
	}

	exe, err := osext.Executable()
	if err != nil {
		return nil, fmt.Errorf("cloud not find the service executable: %v", err)
	}

	// When running the kubelet service it's fine to not specify a config file (or only a
	// partial config file) as all needed info can be retrieved anonymously using metadata.
	if filepath.Base(exe) == "kubelet" || filepath.Base(exe) == "kubelet.exe" {
		// In CloudStack your metadata is always served by the DHCP server.
		dhcpServer, err := findDHCPServer()
		if err == nil {
			klog.V(4).Infof("Found metadata server: %v", dhcpServer)
			cs.metadata = &metadata{dhcpServer: dhcpServer, zone: cs.zone}
		} else {
			klog.Errorf("Error searching metadata server: %v", err)
		}
	}

	if cfg.Global.APIURL != "" && cfg.Global.APIKey != "" && cfg.Global.SecretKey != "" {
		cs.client = cloudstack.NewAsyncClient(cfg.Global.APIURL, cfg.Global.APIKey, cfg.Global.SecretKey, !cfg.Global.SSLNoVerify)
	}

	if cs.client == nil {
		if cs.metadata != nil {
			klog.V(2).Infof("No API URL, key and secret are provided, so only using metadata!")
		} else {
			return nil, errors.New("no cloud provider config given")
		}
	}

	return cs, nil
}