// DefaultInstanceType determines an instance type for the specified cluster & instance group
543115
func (c *awsCloudImplementation) DefaultInstanceType(cluster *kops.Cluster, ig *kops.InstanceGroup) (string, error) {
	var candidates []string

	switch ig.Spec.Role {
	case kops.InstanceGroupRoleMaster:
		// Some regions do not (currently) support the m3 family; the c4 large is the cheapest non-burstable instance
		// (us-east-2, ca-central-1, eu-west-2, ap-northeast-2).
		// Also some accounts are no longer supporting m3 in us-east-1 zones
		candidates = []string{"m3.medium", "c4.large"}

	case kops.InstanceGroupRoleNode:
		candidates = []string{"t2.medium"}

	case kops.InstanceGroupRoleBastion:
		candidates = []string{"t2.micro"}

	default:
		return "", fmt.Errorf("unhandled role %q", ig.Spec.Role)
	}

	// Find the AZs the InstanceGroup targets
	igZones, err := model.FindZonesForInstanceGroup(cluster, ig)
	if err != nil {
		return "", err
	}
	igZonesSet := sets.NewString(igZones...)

	// TODO: Validate that instance type exists in all AZs, but skip AZs that don't support any VPC stuff
	for _, instanceType := range candidates {
		zones, err := c.zonesWithInstanceType(instanceType)
		if err != nil {
			return "", err
		}
		if zones.IsSuperset(igZonesSet) {
			return instanceType, nil
		} else {
			glog.V(2).Infof("can't use instance type %q, available in zones %v but need %v", instanceType, zones, igZones)
		}
	}

	return "", fmt.Errorf("could not find a suitable supported instance type for the instance group %q (type %q) in region %q", ig.Name, ig.Spec.Role, c.region)
}
647211
func (s *UpdateStackInput) SetDefaultInstanceProfileArn(v string) *UpdateStackInput {
	s.DefaultInstanceProfileArn = &v
	return s
}
558205
func (s *Cluster) SetInstanceCollectionType(v string) *Cluster {
	s.InstanceCollectionType = &v
	return s
}
421916
func (o *Compute) SetInstanceTypes(v *InstanceTypes) *Compute {
	if o.InstanceTypes = v; o.InstanceTypes == nil {
		o.nullFields = append(o.nullFields, "InstanceTypes")
	}
	return o
}
746178
func (s *ContainerDetail) SetInstanceType(v string) *ContainerDetail {
	s.InstanceType = &v
	return s
}
902471
func (s *InstanceTypeSpecification) SetInstanceType(v string) *InstanceTypeSpecification {
	s.InstanceType = &v
	return s
}
1160299
func (env *environ) InstanceTypes(ctx context.ProviderCallContext, c constraints.Value) (instances.InstanceTypesWithCostMetadata, error) {
	reg, err := env.Region()
	if err != nil {
		return instances.InstanceTypesWithCostMetadata{}, errors.Trace(err)
	}
	zones, err := env.gce.AvailabilityZones(reg.Region)
	if err != nil {
		return instances.InstanceTypesWithCostMetadata{}, google.HandleCredentialError(errors.Trace(err), ctx)
	}
	resultUnique := map[string]instances.InstanceType{}

	for _, z := range zones {
		if !z.Available() {
			continue
		}
		machines, err := env.gce.ListMachineTypes(z.Name())
		if err != nil {
			return instances.InstanceTypesWithCostMetadata{}, google.HandleCredentialError(errors.Trace(err), ctx)
		}
		for _, m := range machines {
			i := instances.InstanceType{
				Id:       strconv.FormatUint(m.Id, 10),
				Name:     m.Name,
				CpuCores: uint64(m.GuestCpus),
				Mem:      uint64(m.MemoryMb),
				Arches:   []string{arch.AMD64},
				VirtType: &virtType,
			}
			resultUnique[m.Name] = i
		}
	}

	result := make([]instances.InstanceType, len(resultUnique))
	i := 0
	for _, it := range resultUnique {
		result[i] = it
		i++
	}
	result, err = instances.MatchingInstanceTypes(result, "", c)
	if err != nil {
		return instances.InstanceTypesWithCostMetadata{}, errors.Trace(err)
	}
	return instances.InstanceTypesWithCostMetadata{InstanceTypes: result}, nil
}
1107175
func (s *UpdateFleetInput) SetInstanceType(v string) *UpdateFleetInput {
	s.InstanceType = &v
	return s
}
884630
func (s *ReservedElasticsearchInstance) SetElasticsearchInstanceType(v string) *ReservedElasticsearchInstance {
	s.ElasticsearchInstanceType = &v
	return s
}
428151
func (s *InstanceGroup) SetInstanceType(v string) *InstanceGroup {
	s.InstanceType = &v
	return s
}
626782
func (s *NodeConfiguration) SetInstanceType(v string) *NodeConfiguration {
	s.InstanceType = &v
	return s
}
1253782
func (s *CreateFleetInput) SetEC2InstanceType(v string) *CreateFleetInput {
	s.EC2InstanceType = &v
	return s
}
1166042
func (s *DescribeBrokerInstanceOptionsInput) SetHostInstanceType(v string) *DescribeBrokerInstanceOptionsInput {
	s.HostInstanceType = &v
	return s
}
856226
func MatchingInstanceTypes(allInstanceTypes []InstanceType, region string, cons constraints.Value) ([]InstanceType, error) {
	var itypes []InstanceType

	// Rules used to select instance types:
	// - non memory constraints like cores etc are always honoured
	// - if no mem constraint specified and instance-type not specified,
	//   try opinionated default with enough mem to run a server.
	// - if no matches and no mem constraint specified, try again and
	//   return any matching instance with the largest memory
	origCons := cons
	if !cons.HasInstanceType() && cons.Mem == nil {
		minMem := uint64(minMemoryHeuristic)
		cons.Mem = &minMem
	}
	itypes = matchingTypesForConstraint(allInstanceTypes, cons)

	// No matches using opinionated default, so if no mem constraint specified,
	// look for matching instance with largest memory.
	if len(itypes) == 0 && cons.Mem != origCons.Mem {
		itypes = matchingTypesForConstraint(allInstanceTypes, origCons)
		if len(itypes) > 0 {
			sort.Sort(byMemory(itypes))
			itypes = []InstanceType{itypes[len(itypes)-1]}
		}
	}
	// If we have matching instance types, we can return those, sorted by cost.
	if len(itypes) > 0 {
		sort.Sort(byCost(itypes))
		return itypes, nil
	}

	// No luck, so report the error.
	return nil, fmt.Errorf("no instance types in %s matching constraints %q", region, origCons)
}
1012107
func (o *OracleEnviron) InstanceTypes(context.ProviderCallContext, constraints.Value) (envinstance.InstanceTypesWithCostMetadata, error) {
	var i envinstance.InstanceTypesWithCostMetadata
	return i, nil
}
1141525
func newInstanceType(size compute.VirtualMachineSize) instances.InstanceType {
	// We're not doing real costs for now; just made-up, relative
	// costs, to ensure we choose the right VMs given matching
	// constraints. This was based on the pricing for West US,
	// and assumes that all regions have the same relative costs.
	//
	// DS is the same price as D, but is targeted at Premium Storage.
	// Likewise for GS and G. We put the premium storage variants
	// directly after their non-premium counterparts.
	machineSizeCost := []string{
		"Standard_A0",
		"Standard_A1",
		"Standard_D1",
		"Standard_DS1",
		"Standard_D1_v2",
		"Standard_A2",
		"Standard_D2",
		"Standard_DS2",
		"Standard_D2_v2",
		"Standard_D11",
		"Standard_DS11",
		"Standard_D11_v2",
		"Standard_A3",
		"Standard_D3",
		"Standard_DS3",
		"Standard_D3_v2",
		"Standard_D12",
		"Standard_DS12",
		"Standard_D12_v2",
		"Standard_A5", // Yes, A5 is cheaper than A4.
		"Standard_A4",
		"Standard_A6",
		"Standard_G1",
		"Standard_GS1",
		"Standard_D4",
		"Standard_DS4",
		"Standard_D4_v2",
		"Standard_D13",
		"Standard_DS13",
		"Standard_D13_v2",
		"Standard_A7",
		"Standard_A10",
		"Standard_G2",
		"Standard_GS2",
		"Standard_D5_v2",
		"Standard_D14",
		"Standard_DS14",
		"Standard_D14_v2",
		"Standard_A8",
		"Standard_A11",
		"Standard_G3",
		"Standard_GS3",
		"Standard_A9",
		"Standard_G4",
		"Standard_GS4",
		"Standard_GS5",
		"Standard_G5",

		// Basic instances are less capable than standard
		// ones, so we don't want to be providing them as
		// a default. This is achieved by costing them at
		// a higher price, even though they are cheaper
		// in reality.
		"Basic_A0",
		"Basic_A1",
		"Basic_A2",
		"Basic_A3",
		"Basic_A4",
	}

	// Anything not in the list is more expensive that is in the list.
	cost := len(machineSizeCost)
	sizeName := to.String(size.Name)
	for i, name := range machineSizeCost {
		if sizeName == name {
			cost = i
			break
		}
	}
	if cost == len(machineSizeCost) {
		logger.Debugf("found unknown VM size %q", sizeName)
	}

	vtype := "Hyper-V"
	return instances.InstanceType{
		Id:       sizeName,
		Name:     sizeName,
		Arches:   []string{arch.AMD64},
		CpuCores: uint64(to.Int32(size.NumberOfCores)),
		Mem:      uint64(to.Int32(size.MemoryInMB)),
		// NOTE(axw) size.OsDiskSizeInMB is the *maximum*
		// OS-disk size. When we create a VM, we can create
		// one that is smaller.
		RootDisk: mbToMib(uint64(to.Int32(size.OsDiskSizeInMB))),
		Cost:     uint64(cost),
		VirtType: &vtype,
		// tags are not currently supported by azure
	}
}
687840
func (s *ContainerOverrides) SetInstanceType(v string) *ContainerOverrides {
	s.InstanceType = &v
	return s
}