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
}