Esempio n. 1
0
func validateConfig(newCfg, oldCfg *config.Config) (*azureModelConfig, error) {
	err := config.Validate(newCfg, oldCfg)
	if err != nil {
		return nil, err
	}

	validated, err := newCfg.ValidateUnknownAttrs(configFields, configDefaults)
	if err != nil {
		return nil, err
	}

	// Ensure required configuration is provided.
	for _, key := range requiredConfigAttributes {
		if value, ok := validated[key].(string); !ok || value == "" {
			return nil, errors.Errorf("%q config not specified", key)
		}
	}
	if oldCfg != nil {
		// Ensure immutable configuration isn't changed.
		oldUnknownAttrs := oldCfg.UnknownAttrs()
		for _, key := range immutableConfigAttributes {
			oldValue, hadValue := oldUnknownAttrs[key].(string)
			if hadValue {
				newValue, haveValue := validated[key].(string)
				if !haveValue {
					return nil, errors.Errorf(
						"cannot remove immutable %q config", key,
					)
				}
				if newValue != oldValue {
					return nil, errors.Errorf(
						"cannot change immutable %q config (%v -> %v)",
						key, oldValue, newValue,
					)
				}
			}
			// It's valid to go from not having to having.
		}
		// TODO(axw) figure out how we intend to handle changing
		// secrets, such as application key
	}

	// Resource group names must not exceed 80 characters. Resource group
	// names are based on the model UUID and model name, the latter of
	// which the model creator controls.
	modelTag := names.NewModelTag(newCfg.UUID())
	resourceGroup := resourceGroupName(modelTag, newCfg.Name())
	if n := len(resourceGroup); n > resourceNameLengthMax {
		smallestResourceGroup := resourceGroupName(modelTag, "")
		return nil, errors.Errorf(`resource group name %q is too long

Please choose a model name of no more than %d characters.`,
			resourceGroup,
			resourceNameLengthMax-len(smallestResourceGroup),
		)
	}

	location := canonicalLocation(validated[configAttrLocation].(string))
	endpoint := validated[configAttrEndpoint].(string)
	storageEndpoint := validated[configAttrStorageEndpoint].(string)
	appId := validated[configAttrAppId].(string)
	subscriptionId := validated[configAttrSubscriptionId].(string)
	tenantId := validated[configAttrTenantId].(string)
	appPassword := validated[configAttrAppPassword].(string)
	storageAccount, _ := validated[configAttrStorageAccount].(string)
	storageAccountKey, _ := validated[configAttrStorageAccountKey].(string)
	storageAccountType := validated[configAttrStorageAccountType].(string)
	controllerResourceGroup := validated[configAttrControllerResourceGroup].(string)

	if newCfg.FirewallMode() == config.FwGlobal {
		// We do not currently support the "global" firewall mode.
		return nil, errNoFwGlobal
	}

	if !isKnownStorageAccountType(storageAccountType) {
		return nil, errors.Errorf(
			"invalid storage account type %q, expected one of: %q",
			storageAccountType, knownStorageAccountTypes,
		)
	}

	// The Azure storage code wants the endpoint host only, not the URL.
	storageEndpointURL, err := url.Parse(storageEndpoint)
	if err != nil {
		return nil, errors.Annotate(err, "parsing storage endpoint URL")
	}

	token, err := azure.NewServicePrincipalToken(
		appId, appPassword, tenantId,
		azure.AzureResourceManagerScope,
	)
	if err != nil {
		return nil, errors.Annotate(err, "constructing service principal token")
	}

	azureConfig := &azureModelConfig{
		newCfg,
		token,
		subscriptionId,
		location,
		endpoint,
		storageEndpointURL.Host,
		storageAccount,
		storageAccountKey,
		storage.AccountType(storageAccountType),
		controllerResourceGroup,
	}

	return azureConfig, nil
}
Esempio n. 2
0
func validateConfig(newCfg, oldCfg *config.Config) (*azureModelConfig, error) {
	err := config.Validate(newCfg, oldCfg)
	if err != nil {
		return nil, err
	}

	validated, err := newCfg.ValidateUnknownAttrs(configFields, configDefaults)
	if err != nil {
		return nil, err
	}

	// Ensure required configuration is provided.
	for _, key := range requiredConfigAttributes {
		if value, ok := validated[key].(string); !ok || value == "" {
			return nil, errors.Errorf("%q config not specified", key)
		}
	}
	if oldCfg != nil {
		// Ensure immutable configuration isn't changed.
		oldUnknownAttrs := oldCfg.UnknownAttrs()
		for _, key := range immutableConfigAttributes {
			oldValue, hadValue := oldUnknownAttrs[key].(string)
			if hadValue {
				newValue, haveValue := validated[key].(string)
				if !haveValue {
					return nil, errors.Errorf(
						"cannot remove immutable %q config", key,
					)
				}
				if newValue != oldValue {
					return nil, errors.Errorf(
						"cannot change immutable %q config (%v -> %v)",
						key, oldValue, newValue,
					)
				}
			}
			// It's valid to go from not having to having.
		}
		// TODO(axw) figure out how we intend to handle changing
		// secrets, such as application key
	}

	location := canonicalLocation(validated[configAttrLocation].(string))
	appId := validated[configAttrAppId].(string)
	subscriptionId := validated[configAttrSubscriptionId].(string)
	tenantId := validated[configAttrTenantId].(string)
	appPassword := validated[configAttrAppPassword].(string)
	storageAccount, _ := validated[configAttrStorageAccount].(string)
	storageAccountKey, _ := validated[configAttrStorageAccountKey].(string)
	storageAccountType := validated[configAttrStorageAccountType].(string)
	controllerResourceGroup := validated[configAttrControllerResourceGroup].(string)

	if newCfg.FirewallMode() == config.FwGlobal {
		// We do not currently support the "global" firewall mode.
		return nil, errNoFwGlobal
	}

	if !isKnownStorageAccountType(storageAccountType) {
		return nil, errors.Errorf(
			"invalid storage account type %q, expected one of: %q",
			storageAccountType, knownStorageAccountTypes,
		)
	}

	token, err := azure.NewServicePrincipalToken(
		appId, appPassword, tenantId,
		azure.AzureResourceManagerScope,
	)
	if err != nil {
		return nil, errors.Annotate(err, "constructing service principal token")
	}

	azureConfig := &azureModelConfig{
		newCfg,
		token,
		subscriptionId,
		location,
		storageAccount,
		storageAccountKey,
		storage.AccountType(storageAccountType),
		controllerResourceGroup,
	}

	return azureConfig, nil
}
Esempio n. 3
0
File: config.go Progetto: bac/juju
func validateConfig(newCfg, oldCfg *config.Config) (*azureModelConfig, error) {
	err := config.Validate(newCfg, oldCfg)
	if err != nil {
		return nil, err
	}

	validated, err := newCfg.ValidateUnknownAttrs(configFields, configDefaults)
	if err != nil {
		return nil, err
	}

	if oldCfg != nil {
		// Ensure immutable configuration isn't changed.
		oldUnknownAttrs := oldCfg.UnknownAttrs()
		for _, key := range immutableConfigAttributes {
			oldValue, hadValue := oldUnknownAttrs[key].(string)
			if hadValue {
				newValue, haveValue := validated[key].(string)
				if !haveValue {
					return nil, errors.Errorf(
						"cannot remove immutable %q config", key,
					)
				}
				if newValue != oldValue {
					return nil, errors.Errorf(
						"cannot change immutable %q config (%v -> %v)",
						key, oldValue, newValue,
					)
				}
			}
			// It's valid to go from not having to having.
		}
	}

	// Resource group names must not exceed 80 characters. Resource group
	// names are based on the model UUID and model name, the latter of
	// which the model creator controls.
	modelTag := names.NewModelTag(newCfg.UUID())
	resourceGroup := resourceGroupName(modelTag, newCfg.Name())
	if n := len(resourceGroup); n > resourceNameLengthMax {
		smallestResourceGroup := resourceGroupName(modelTag, "")
		return nil, errors.Errorf(`resource group name %q is too long

Please choose a model name of no more than %d characters.`,
			resourceGroup,
			resourceNameLengthMax-len(smallestResourceGroup),
		)
	}

	if newCfg.FirewallMode() == config.FwGlobal {
		// We do not currently support the "global" firewall mode.
		return nil, errNoFwGlobal
	}

	storageAccountType := validated[configAttrStorageAccountType].(string)
	if !isKnownStorageAccountType(storageAccountType) {
		return nil, errors.Errorf(
			"invalid storage account type %q, expected one of: %q",
			storageAccountType, knownStorageAccountTypes,
		)
	}

	azureConfig := &azureModelConfig{
		newCfg,
		storageAccountType,
	}
	return azureConfig, nil
}