Esempio n. 1
0
// Provide implements DockerConfigProvider
func (g *containerRegistryProvider) Provide() credentialprovider.DockerConfig {
	cfg := credentialprovider.DockerConfig{}

	tokenJsonBlob, err := credentialprovider.ReadUrl(metadataToken, g.Client, metadataHeader)
	if err != nil {
		glog.Errorf("while reading access token endpoint: %v", err)
		return cfg
	}

	email, err := credentialprovider.ReadUrl(metadataEmail, g.Client, metadataHeader)
	if err != nil {
		glog.Errorf("while reading email endpoint: %v", err)
		return cfg
	}

	var parsedBlob tokenBlob
	if err := json.Unmarshal([]byte(tokenJsonBlob), &parsedBlob); err != nil {
		glog.Errorf("while parsing json blob %s: %v", tokenJsonBlob, err)
		return cfg
	}

	entry := credentialprovider.DockerConfigEntry{
		Username: "******",
		Password: parsedBlob.AccessToken,
		Email:    string(email),
	}

	// Add our entry for each of the supported container registry URLs
	for _, k := range containerRegistryUrls {
		cfg[k] = entry
	}
	return cfg
}
Esempio n. 2
0
// Enabled implements a special metadata-based check, which verifies the
// storage scope is available on the GCE VM.
// If running on a GCE VM, check if 'default' service account exists.
// If it does not exist, assume that registry is not enabled.
// If default service account exists, check if relevant scopes exist in the default service account.
// The metadata service can become temporarily inaccesible. Hence all requests to the metadata
// service will be retried until the metadata server returns a `200`.
// It is expected that "http://metadata.google.internal./computeMetadata/v1/instance/service-accounts/" will return a `200`
// and "http://metadata.google.internal./computeMetadata/v1/instance/service-accounts/default/scopes" will also return `200`.
// More information on metadata service can be found here - https://cloud.google.com/compute/docs/storing-retrieving-metadata
func (g *containerRegistryProvider) Enabled() bool {
	if !onGCEVM() {
		return false
	}
	// Given that we are on GCE, we should keep retrying until the metadata server responds.
	value := runWithBackoff(func() ([]byte, error) {
		value, err := credentialprovider.ReadUrl(serviceAccounts, g.Client, metadataHeader)
		if err != nil {
			glog.V(2).Infof("Failed to Get service accounts from gce metadata server: %v", err)
		}
		return value, err
	})
	// We expect the service account to return a list of account directories separated by newlines, e.g.,
	//   sv-account-name1/
	//   sv-account-name2/
	// ref: https://cloud.google.com/compute/docs/storing-retrieving-metadata
	defaultServiceAccountExists := false
	for _, sa := range strings.Split(string(value), "\n") {
		if strings.TrimSpace(sa) == defaultServiceAccount {
			defaultServiceAccountExists = true
			break
		}
	}
	if !defaultServiceAccountExists {
		glog.V(2).Infof("'default' service account does not exist. Found following service accounts: %q", string(value))
		return false
	}
	url := metadataScopes + "?alt=json"
	value = runWithBackoff(func() ([]byte, error) {
		value, err := credentialprovider.ReadUrl(url, g.Client, metadataHeader)
		if err != nil {
			glog.V(2).Infof("Failed to Get scopes in default service account from gce metadata server: %v", err)
		}
		return value, err
	})
	var scopes []string
	if err := json.Unmarshal(value, &scopes); err != nil {
		glog.Errorf("Failed to unmarshal scopes: %v", err)
		return false
	}
	for _, v := range scopes {
		// cloudPlatformScope implies storage scope.
		if strings.HasPrefix(v, storageScopePrefix) || strings.HasPrefix(v, cloudPlatformScopePrefix) {
			return true
		}
	}
	glog.Warningf("Google container registry is disabled, no storage scope is available: %s", value)
	return false
}
Esempio n. 3
0
// Enabled implements a special metadata-based check, which verifies the
// storage scope is available on the GCE VM.
func (g *containerRegistryProvider) Enabled() bool {
	value, err := credentialprovider.ReadUrl(metadataScopes+"?alt=json", g.Client, metadataHeader)
	if err != nil {
		return false
	}
	var scopes []string
	if err := json.Unmarshal([]byte(value), &scopes); err != nil {
		return false
	}

	for _, v := range scopes {
		if strings.HasPrefix(v, storageScopePrefix) {
			return true
		}
	}
	glog.Warningf("Google container registry is disabled, no storage scope is available: %s", value)
	return false
}
Esempio n. 4
0
// Provide implements DockerConfigProvider
func (g *dockerConfigUrlKeyProvider) Provide() credentialprovider.DockerConfig {
	// Read the contents of the google-dockercfg-url key and load a .dockercfg from there
	if url, err := credentialprovider.ReadUrl(dockerConfigUrlKey, g.Client, metadataHeader); err != nil {
		glog.Errorf("while reading 'google-dockercfg-url' metadata: %v", err)
	} else {
		if strings.HasPrefix(string(url), "http") {
			if cfg, err := credentialprovider.ReadDockerConfigFileFromUrl(string(url), g.Client, nil); err != nil {
				glog.Errorf("while reading 'google-dockercfg-url'-specified url: %s, %v", string(url), err)
			} else {
				return cfg
			}
		} else {
			// TODO(mattmoor): support reading alternate scheme URLs (e.g. gs:// or s3://)
			glog.Errorf("Unsupported URL scheme: %s", string(url))
		}
	}

	return credentialprovider.DockerConfig{}
}
Esempio n. 5
0
// Enabled implements DockerConfigProvider for all of the Google implementations.
func (g *metadataProvider) Enabled() bool {
	_, err := credentialprovider.ReadUrl(metadataUrl, g.Client, metadataHeader)
	return err == nil
}