func NewConfigManager()

in src/go/configmanager/config_manager.go [77:203]


func NewConfigManager(mf *metadata.MetadataFetcher, opts options.ConfigGeneratorOptions) (*ConfigManager, error) {
	m := &ConfigManager{
		metadataFetcher:    mf,
		envoyConfigOptions: opts,
	}
	m.cache = cache.NewSnapshotCache(true, m, m)

	// If service config is provided as a file, just use it and disable managed rollout
	if *ServicePath != "" {
		// Following flags will not be used
		if *ServiceName != "" {
			glog.Infof("flag --service is ignored when --service_json_path is specified.")
		}
		if *ServiceConfigId != "" {
			glog.Infof("flag --service_config_id is ignored when --service_json_path is specified.")
		}
		if *RolloutStrategy != "fixed" {
			glog.Infof("flag --rollout_strategy will be fixed when --service_json_path is specified.")
		}

		if err := m.readAndApplyServiceConfig(*ServicePath); err != nil {
			return nil, err
		}

		glog.Infof("create new Config Manager from static service config json file at %v", *ServicePath)
		return m, nil
	}

	m.serviceName = *ServiceName
	checkMetadata := *CheckMetadata
	var err error

	if m.serviceName == "" && checkMetadata && mf != nil {
		m.serviceName, err = mf.FetchServiceName()
		if m.serviceName == "" || err != nil {
			return nil, fmt.Errorf("failed to read metadata with key endpoints-service-name from metadata server: %v", err)
		}
	} else if m.serviceName == "" && !checkMetadata {
		return nil, fmt.Errorf("service name is not specified, required because metadata fetching is disabled")
	} else if m.serviceName == "" && mf == nil {
		return nil, fmt.Errorf("service name is not specified, required on a non-gcp deployment")
	}
	rolloutStrategy := *RolloutStrategy
	// try to fetch from metadata, if not found, set to fixed instead of throwing an error
	if rolloutStrategy == "" && checkMetadata && mf != nil {
		rolloutStrategy, _ = mf.FetchRolloutStrategy()
	}
	if rolloutStrategy == "" {
		rolloutStrategy = util.FixedRolloutStrategy
	}
	if !(rolloutStrategy == util.FixedRolloutStrategy || rolloutStrategy == util.ManagedRolloutStrategy) {
		return nil, fmt.Errorf(`failed to set rollout strategy. It must be either "managed" or "fixed"`)
	}

	// when --non_gcp  is set, instance metadata server(imds) is not defined. So
	// accessToken is unavailable from imds and --service_account_key must be
	// set to generate accessToken.
	// The inverse is not true. We can still use IMDS on GCP when service account key is specified.
	if mf == nil && opts.ServiceAccountKey == "" && !opts.EnableApplicationDefaultCredentials {
		return nil, fmt.Errorf("if flag --non_gcp is specified, flag --service_account_key or --enable_application_default_credentials must be specified")
	}

	accessToken := func() (string, time.Duration, error) {
		if opts.EnableApplicationDefaultCredentials {
			return tokengenerator.GenerateApplicationDefaultCredentialsToken()
		}
		if opts.ServiceAccountKey != "" {
			return tokengenerator.GenerateAccessTokenFromFile(opts.ServiceAccountKey)
		}
		return mf.FetchAccessToken()
	}

	client, err := httpsClient(opts)
	if err != nil {
		return nil, fmt.Errorf("fail to init httpsClient: %v", err)
	}

	m.serviceConfigFetcher = sc.NewServiceConfigFetcher(client, opts.ServiceManagementURL,
		m.serviceName, accessToken)

	configId := ""
	if rolloutStrategy == util.FixedRolloutStrategy {
		configId = *ServiceConfigId
		if configId == "" {
			if mf == nil {
				return nil, fmt.Errorf("service config id is not specified, required on a non-gcp deployment")
			}

			if !checkMetadata {
				return nil, fmt.Errorf("service config id is not specified, required because metadata fetching is disabled")
			}

			configId, err = mf.FetchConfigId()
			if configId == "" || err != nil {
				return nil, fmt.Errorf("failed to read metadata with key endpoints-service-version from metadata server: %v", err)
			}
		}
	} else if rolloutStrategy == util.ManagedRolloutStrategy {
		configId, err = m.serviceConfigFetcher.LoadConfigIdFromRollouts()
		if err != nil {
			return nil, err
		}
	}

	if err = m.fetchAndApplyServiceConfig(configId); err != nil {
		return nil, fmt.Errorf("fail to fetch and apply the startup service config, %v", err)
	}

	if rolloutStrategy == util.ManagedRolloutStrategy {
		m.rolloutIdChangeDetector = sc.NewRolloutIdChangeDetector(client, opts.ServiceControlURL, m.serviceName, accessToken)
		m.rolloutIdChangeDetector.SetDetectRolloutIdChangeTimer(*checkNewRolloutInterval, func() {
			latestConfigId, err := m.serviceConfigFetcher.LoadConfigIdFromRollouts()
			if err != nil {
				glog.Errorf("error occurred when getting configId by fetching rollout, %v", err)
				return
			}

			if err = m.fetchAndApplyServiceConfig(latestConfigId); err != nil {
				glog.Errorf("error occurred when fetching and applying new service config, %v", err)
			}
		})
	}

	glog.Infof("create new Config Manager for service (%v) with configuration id (%v), %v rollout strategy",
		m.serviceName, m.curConfigId(), rolloutStrategy)
	return m, nil
}