github.com/ystia/yorc/v4@v4.3.0/storage/internal/elastic/config.go (about)

     1  // Copyright 2019 Bull S.A.S. Atos Technologies - Bull, Rue Jean Jaures, B.P.68, 78340, Les Clayes-sous-Bois, France.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package elastic
    16  
    17  import (
    18  	"reflect"
    19  	"time"
    20  
    21  	"github.com/pkg/errors"
    22  	"github.com/spf13/cast"
    23  	"github.com/ystia/yorc/v4/config"
    24  	"github.com/ystia/yorc/v4/log"
    25  )
    26  
    27  var elasticStoreConfType = reflect.TypeOf(elasticStoreConf{})
    28  
    29  // elasticStoreConf represents the elastic store configuration that can be set in store.properties configuration.
    30  type elasticStoreConf struct {
    31  	// The ES cluster urls (array or CSV)
    32  	esUrls []string `json:"es_urls"`
    33  	// The path to the CACert file when TLS is activated for ES
    34  	caCertPath string `json:"ca_cert_path"`
    35  	// The path to a PEM encoded certificate file when TLS is activated for ES
    36  	certPath string `json:"cert_path"`
    37  	// The path to a PEM encoded private key file when TLS is activated for ES
    38  	keyPath string `json:"key_path"`
    39  	// All index used by yorc will be prefixed by this prefix
    40  	indicePrefix string `json:"index_prefix" default:"yorc_"`
    41  	// When querying logs and event, we wait this timeout before each request when it returns nothing
    42  	// (until something is returned or the waitTimeout is reached)
    43  	esQueryPeriod time.Duration `json:"es_query_period" default:"4s"`
    44  	// This timeout is used to wait for more than refresh_interval = 1s when querying logs and events indexes
    45  	esRefreshWaitTimeout time.Duration `json:"es_refresh_wait_timeout" default:"2s"`
    46  	// When querying ES, force refresh index before waiting for refresh
    47  	esForceRefresh bool `json:"es_force_refresh" default:"false"`
    48  	// This is the maximum size (in kB) of bulk request sent while migrating data
    49  	maxBulkSize int `json:"max_bulk_size" default:"4000"`
    50  	// This is the maximum size (in term of number of documents) of bulk request sent while migrating data
    51  	maxBulkCount int `json:"max_bulk_count" default:"1000"`
    52  	// This optional ID will be used to distinguish logs & events in the indexes. If not set, we'll use the Consul.Datacenter
    53  	clusterID string `json:"cluster_id"`
    54  	// Set to true if you want to print ES requests (for debug only)
    55  	traceRequests bool `json:"trace_requests" default:"false"`
    56  	// Set to true if you want to trace events & logs when sent (for debug only)
    57  	traceEvents bool `json:"trace_events" default:"false"`
    58  	// Inital shards at index creation
    59  	InitialShards int `json:"initial_shards" default:"-1"`
    60  	// Initial replicas at index creation
    61  	InitialReplicas int `json:"initial_replicas" default:"-1"`
    62  }
    63  
    64  // Get the tag for this field (for internal usage only: fatal if not found !).
    65  func getElasticStorageConfigPropertyTag(fn string, tn string) (tagValue string, e error) {
    66  	f, found := elasticStoreConfType.FieldByName(fn)
    67  	if !found {
    68  		e = errors.Errorf("Not able to get field %s on elasticStoreConf struct, there is an issue with this code !", fn)
    69  		return
    70  	}
    71  	tagValue = f.Tag.Get(tn)
    72  	if tagValue == "" {
    73  		e = errors.Errorf("Not able to get field %s's tag %s value on elasticStoreConf struct, there is an issue with this code !\"", fn, tn)
    74  		return
    75  	}
    76  	return
    77  }
    78  
    79  // The configuration of the elastic store is defined regarding default values and store 'properties' dynamic map.
    80  // Will fail if the required es_urls is not set in store 'properties'
    81  func getElasticStoreConfig(yorcConfig config.Configuration, storeConfig config.Store) (cfg elasticStoreConf, e error) {
    82  	storeProperties := storeConfig.Properties
    83  	var t string
    84  	// The ES urls is required
    85  	t, e = getElasticStorageConfigPropertyTag("esUrls", "json")
    86  	if e != nil {
    87  		return
    88  	}
    89  	if storeProperties.IsSet(t) {
    90  		cfg.esUrls = storeProperties.GetStringSlice(t)
    91  		if cfg.esUrls == nil || len(cfg.esUrls) == 0 {
    92  			e = errors.Errorf("Not able to get ES configuration for elastic store, es_urls store property seems empty : %+v", storeProperties.Get(t))
    93  			return
    94  		}
    95  	} else {
    96  		log.Fatal("Not able to get ES configuration for elastic store, es_urls store property should be set !")
    97  	}
    98  	// Define the clusterID
    99  	t, e = getElasticStorageConfigPropertyTag("clusterID", "json")
   100  	if e != nil {
   101  		return
   102  	}
   103  	if storeProperties.IsSet(t) {
   104  		cfg.clusterID = storeProperties.GetString(t)
   105  	}
   106  	if len(cfg.clusterID) == 0 {
   107  		cfg.clusterID = yorcConfig.Consul.Datacenter
   108  		log.Printf("clusterID not provided or empty, using consul datacenter (%s) as clusterID", yorcConfig.Consul.Datacenter)
   109  	}
   110  	if len(cfg.clusterID) == 0 {
   111  		e = errors.Errorf("Not able to define clusterID, please check configuration !")
   112  		return
   113  	}
   114  	// Define store optional / default configuration
   115  	t, e = getElasticStorageConfigPropertyTag("caCertPath", "json")
   116  	if e != nil {
   117  		return
   118  	}
   119  
   120  	if storeProperties.IsSet(t) {
   121  		cfg.caCertPath = storeProperties.GetString(t)
   122  	}
   123  	t, e = getElasticStorageConfigPropertyTag("certPath", "json")
   124  	if e != nil {
   125  		return
   126  	}
   127  
   128  	if storeProperties.IsSet(t) {
   129  		cfg.certPath = storeProperties.GetString(t)
   130  	}
   131  	t, e = getElasticStorageConfigPropertyTag("keyPath", "json")
   132  	if e != nil {
   133  		return
   134  	}
   135  
   136  	if storeProperties.IsSet(t) {
   137  		cfg.keyPath = storeProperties.GetString(t)
   138  	}
   139  	cfg.esForceRefresh, e = getBoolFromSettingsOrDefaults("esForceRefresh", storeProperties)
   140  	if e != nil {
   141  		return
   142  	}
   143  
   144  	t, e = getElasticStorageConfigPropertyTag("indicePrefix", "json")
   145  	if e != nil {
   146  		return
   147  	}
   148  
   149  	if storeProperties.IsSet(t) {
   150  		cfg.indicePrefix = storeProperties.GetString(t)
   151  	} else {
   152  		cfg.indicePrefix, e = getElasticStorageConfigPropertyTag("indicePrefix", "default")
   153  		if e != nil {
   154  			return
   155  		}
   156  	}
   157  	cfg.esQueryPeriod, e = getDurationFromSettingsOrDefaults("esQueryPeriod", storeProperties)
   158  	if e != nil {
   159  		return
   160  	}
   161  
   162  	cfg.esRefreshWaitTimeout, e = getDurationFromSettingsOrDefaults("esRefreshWaitTimeout", storeProperties)
   163  	if e != nil {
   164  		return
   165  	}
   166  
   167  	cfg.maxBulkSize, e = getIntFromSettingsOrDefaults("maxBulkSize", storeProperties)
   168  	if e != nil {
   169  		return
   170  	}
   171  	cfg.maxBulkCount, e = getIntFromSettingsOrDefaults("maxBulkCount", storeProperties)
   172  	if e != nil {
   173  		return
   174  	}
   175  
   176  	cfg.traceRequests, e = getBoolFromSettingsOrDefaults("traceRequests", storeProperties)
   177  	if e != nil {
   178  		return
   179  	}
   180  
   181  	cfg.traceEvents, e = getBoolFromSettingsOrDefaults("traceEvents", storeProperties)
   182  	if e != nil {
   183  		return
   184  	}
   185  
   186  	cfg.InitialShards, e = getIntFromSettingsOrDefaults("InitialShards", storeProperties)
   187  	if e != nil {
   188  		return
   189  	}
   190  
   191  	cfg.InitialReplicas, e = getIntFromSettingsOrDefaults("InitialReplicas", storeProperties)
   192  	if e != nil {
   193  		return
   194  	}
   195  
   196  	return
   197  }
   198  
   199  // Get the duration from store config properties, fallback to required default value defined in struc.
   200  func getDurationFromSettingsOrDefaults(fn string, dm config.DynamicMap) (v time.Duration, er error) {
   201  	t, er := getElasticStorageConfigPropertyTag(fn, "json")
   202  	if er != nil {
   203  		return
   204  	}
   205  	if dm.IsSet(t) {
   206  		v = dm.GetDuration(t)
   207  		return
   208  	}
   209  	t, er = getElasticStorageConfigPropertyTag(fn, "default")
   210  	if er != nil {
   211  		return
   212  	}
   213  	v = cast.ToDuration(t)
   214  	return
   215  }
   216  
   217  // Get the int from store config properties, fallback to required default value defined in struc.
   218  func getIntFromSettingsOrDefaults(fn string, dm config.DynamicMap) (v int, err error) {
   219  	t, err := getElasticStorageConfigPropertyTag(fn, "json")
   220  	if err != nil {
   221  		return
   222  	}
   223  	if dm.IsSet(t) {
   224  		v = dm.GetInt(t)
   225  		return
   226  	}
   227  	t, err = getElasticStorageConfigPropertyTag(fn, "default")
   228  	if err != nil {
   229  		return
   230  	}
   231  	v = cast.ToInt(t)
   232  	return
   233  }
   234  
   235  // Get the bool from store config properties, fallback to required default value defined in struc.
   236  func getBoolFromSettingsOrDefaults(fn string, dm config.DynamicMap) (v bool, e error) {
   237  	t, e := getElasticStorageConfigPropertyTag(fn, "json")
   238  	if e != nil {
   239  		return
   240  	}
   241  	if dm.IsSet(t) {
   242  		v = dm.GetBool(t)
   243  		return
   244  	}
   245  	t, e = getElasticStorageConfigPropertyTag(fn, "default")
   246  	if e != nil {
   247  		return
   248  	}
   249  	v = cast.ToBool(t)
   250  	return
   251  }