You've already forked sap-jenkins-library
							
							
				mirror of
				https://github.com/SAP/jenkins-library.git
				synced 2025-10-30 23:57:50 +02:00 
			
		
		
		
	Added go-based influxWriteData step (#2890)
* Added go-based influxWriteData step * Wrote tests & fixed issues * Fixed issues * Created go-based step tests. Fixed issues * Fixed issues * Integration test was added Co-authored-by: Oliver Nocon <33484802+OliverNocon@users.noreply.github.com> Co-authored-by: Sven Merk <33895725+nevskrem@users.noreply.github.com>
This commit is contained in:
		
				
					committed by
					
						 GitHub
						GitHub
					
				
			
			
				
	
			
			
			
						parent
						
							3f6eb603c7
						
					
				
				
					commit
					54f2a0d471
				
			
							
								
								
									
										42
									
								
								cmd/influxWriteData.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								cmd/influxWriteData.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| package cmd | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/influx" | ||||
| 	"github.com/SAP/jenkins-library/pkg/log" | ||||
| 	"github.com/SAP/jenkins-library/pkg/telemetry" | ||||
| 	influxdb2 "github.com/influxdata/influxdb-client-go/v2" | ||||
| ) | ||||
|  | ||||
| func influxWriteData(config influxWriteDataOptions, _ *telemetry.CustomData) { | ||||
| 	influxClient := influxdb2.NewClient(config.ServerURL, config.AuthToken) | ||||
| 	// Error situations should be bubbled up until they reach the line below which will then stop execution | ||||
| 	// through the log.Entry().Fatal() call leading to an os.Exit(1) in the end. | ||||
| 	err := writeData(&config, influxClient) | ||||
| 	if err != nil { | ||||
| 		log.Entry().WithError(err).Fatal("step execution failed") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func writeData(config *influxWriteDataOptions, influxClient influxdb2.Client) error { | ||||
| 	log.Entry().Info("influxWriteData step") | ||||
|  | ||||
| 	client := influx.NewClient(influxClient, config.Organization, config.Bucket) | ||||
| 	var dataMap map[string]map[string]interface{} | ||||
| 	if err := json.Unmarshal([]byte(config.DataMap), &dataMap); err != nil { | ||||
| 		return fmt.Errorf("Failed to unmarshal dataMap: %v", err) | ||||
| 	} | ||||
| 	var dataMapTags map[string]map[string]string | ||||
| 	if config.DataMapTags != "" { | ||||
| 		if err := json.Unmarshal([]byte(config.DataMapTags), &dataMapTags); err != nil { | ||||
| 			return fmt.Errorf("Failed to unmarshal dataMapTags: %v", err) | ||||
| 		} | ||||
| 	} | ||||
| 	if err := client.WriteMetrics(dataMap, dataMapTags); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	log.Entry().Info("Metrics have been written successfully") | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										196
									
								
								cmd/influxWriteData_generated.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										196
									
								
								cmd/influxWriteData_generated.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,196 @@ | ||||
| // Code generated by piper's step-generator. DO NOT EDIT. | ||||
|  | ||||
| package cmd | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/config" | ||||
| 	"github.com/SAP/jenkins-library/pkg/log" | ||||
| 	"github.com/SAP/jenkins-library/pkg/splunk" | ||||
| 	"github.com/SAP/jenkins-library/pkg/telemetry" | ||||
| 	"github.com/spf13/cobra" | ||||
| ) | ||||
|  | ||||
| type influxWriteDataOptions struct { | ||||
| 	ServerURL    string `json:"serverUrl,omitempty"` | ||||
| 	AuthToken    string `json:"authToken,omitempty"` | ||||
| 	Bucket       string `json:"bucket,omitempty"` | ||||
| 	Organization string `json:"organization,omitempty"` | ||||
| 	DataMap      string `json:"dataMap,omitempty"` | ||||
| 	DataMapTags  string `json:"dataMapTags,omitempty"` | ||||
| } | ||||
|  | ||||
| // InfluxWriteDataCommand Writes metrics to influxdb | ||||
| func InfluxWriteDataCommand() *cobra.Command { | ||||
| 	const STEP_NAME = "influxWriteData" | ||||
|  | ||||
| 	metadata := influxWriteDataMetadata() | ||||
| 	var stepConfig influxWriteDataOptions | ||||
| 	var startTime time.Time | ||||
| 	var logCollector *log.CollectorHook | ||||
|  | ||||
| 	var createInfluxWriteDataCmd = &cobra.Command{ | ||||
| 		Use:   STEP_NAME, | ||||
| 		Short: "Writes metrics to influxdb", | ||||
| 		Long:  `In this step, the metrics are written to the timeseries database [InfluxDB](https://www.influxdata.com/time-series-platform/influxdb/)`, | ||||
| 		PreRunE: func(cmd *cobra.Command, _ []string) error { | ||||
| 			startTime = time.Now() | ||||
| 			log.SetStepName(STEP_NAME) | ||||
| 			log.SetVerbose(GeneralConfig.Verbose) | ||||
|  | ||||
| 			path, _ := os.Getwd() | ||||
| 			fatalHook := &log.FatalHook{CorrelationID: GeneralConfig.CorrelationID, Path: path} | ||||
| 			log.RegisterHook(fatalHook) | ||||
|  | ||||
| 			err := PrepareConfig(cmd, &metadata, STEP_NAME, &stepConfig, config.OpenPiperFile) | ||||
| 			if err != nil { | ||||
| 				log.SetErrorCategory(log.ErrorConfiguration) | ||||
| 				return err | ||||
| 			} | ||||
| 			log.RegisterSecret(stepConfig.AuthToken) | ||||
|  | ||||
| 			if len(GeneralConfig.HookConfig.SentryConfig.Dsn) > 0 { | ||||
| 				sentryHook := log.NewSentryHook(GeneralConfig.HookConfig.SentryConfig.Dsn, GeneralConfig.CorrelationID) | ||||
| 				log.RegisterHook(&sentryHook) | ||||
| 			} | ||||
|  | ||||
| 			if len(GeneralConfig.HookConfig.SplunkConfig.Dsn) > 0 { | ||||
| 				logCollector = &log.CollectorHook{CorrelationID: GeneralConfig.CorrelationID} | ||||
| 				log.RegisterHook(logCollector) | ||||
| 			} | ||||
|  | ||||
| 			return nil | ||||
| 		}, | ||||
| 		Run: func(_ *cobra.Command, _ []string) { | ||||
| 			telemetryData := telemetry.CustomData{} | ||||
| 			telemetryData.ErrorCode = "1" | ||||
| 			handler := func() { | ||||
| 				config.RemoveVaultSecretFiles() | ||||
| 				telemetryData.Duration = fmt.Sprintf("%v", time.Since(startTime).Milliseconds()) | ||||
| 				telemetryData.ErrorCategory = log.GetErrorCategory().String() | ||||
| 				telemetry.Send(&telemetryData) | ||||
| 				if len(GeneralConfig.HookConfig.SplunkConfig.Dsn) > 0 { | ||||
| 					splunk.Send(&telemetryData, logCollector) | ||||
| 				} | ||||
| 			} | ||||
| 			log.DeferExitHandler(handler) | ||||
| 			defer handler() | ||||
| 			telemetry.Initialize(GeneralConfig.NoTelemetry, STEP_NAME) | ||||
| 			if len(GeneralConfig.HookConfig.SplunkConfig.Dsn) > 0 { | ||||
| 				splunk.Initialize(GeneralConfig.CorrelationID, | ||||
| 					GeneralConfig.HookConfig.SplunkConfig.Dsn, | ||||
| 					GeneralConfig.HookConfig.SplunkConfig.Token, | ||||
| 					GeneralConfig.HookConfig.SplunkConfig.Index, | ||||
| 					GeneralConfig.HookConfig.SplunkConfig.SendLogs) | ||||
| 			} | ||||
| 			influxWriteData(stepConfig, &telemetryData) | ||||
| 			telemetryData.ErrorCode = "0" | ||||
| 			log.Entry().Info("SUCCESS") | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	addInfluxWriteDataFlags(createInfluxWriteDataCmd, &stepConfig) | ||||
| 	return createInfluxWriteDataCmd | ||||
| } | ||||
|  | ||||
| func addInfluxWriteDataFlags(cmd *cobra.Command, stepConfig *influxWriteDataOptions) { | ||||
| 	cmd.Flags().StringVar(&stepConfig.ServerURL, "serverUrl", os.Getenv("PIPER_serverUrl"), "Base URL to the InfluxDB server") | ||||
| 	cmd.Flags().StringVar(&stepConfig.AuthToken, "authToken", os.Getenv("PIPER_authToken"), "Token to authenticate to the Influxdb") | ||||
| 	cmd.Flags().StringVar(&stepConfig.Bucket, "bucket", `piper`, "Name of database (1.8) or bucket (2.0)") | ||||
| 	cmd.Flags().StringVar(&stepConfig.Organization, "organization", os.Getenv("PIPER_organization"), "Name of influx organization. Only for Influxdb 2.0") | ||||
| 	cmd.Flags().StringVar(&stepConfig.DataMap, "dataMap", os.Getenv("PIPER_dataMap"), "Map of fields for each measurements. It has to be a JSON string. For example: {'series_1':{'field_a':11,'field_b':12},'series_2':{'field_c':21,'field_d':22}}") | ||||
| 	cmd.Flags().StringVar(&stepConfig.DataMapTags, "dataMapTags", os.Getenv("PIPER_dataMapTags"), "Map of tags for each measurements. It has to be a JSON string. For example: {'series_1':{'tag_a':'a','tag_b':'b'},'series_2':{'tag_c':'c','tag_d':'d'}}") | ||||
|  | ||||
| 	cmd.MarkFlagRequired("serverUrl") | ||||
| 	cmd.MarkFlagRequired("authToken") | ||||
| 	cmd.MarkFlagRequired("dataMap") | ||||
| } | ||||
|  | ||||
| // retrieve step metadata | ||||
| func influxWriteDataMetadata() config.StepData { | ||||
| 	var theMetaData = config.StepData{ | ||||
| 		Metadata: config.StepMetadata{ | ||||
| 			Name:        "influxWriteData", | ||||
| 			Aliases:     []config.Alias{}, | ||||
| 			Description: "Writes metrics to influxdb", | ||||
| 		}, | ||||
| 		Spec: config.StepSpec{ | ||||
| 			Inputs: config.StepInputs{ | ||||
| 				Secrets: []config.StepSecrets{ | ||||
| 					{Name: "influxAuthTokenId", Description: "Influxdb token for authentication to the InfluxDB. In 1.8 version use 'username:password' instead.", Type: "jenkins"}, | ||||
| 				}, | ||||
| 				Parameters: []config.StepParameters{ | ||||
| 					{ | ||||
| 						Name:        "serverUrl", | ||||
| 						ResourceRef: []config.ResourceReference{}, | ||||
| 						Scope:       []string{"PARAMETERS", "STAGES", "STEPS", "GENERAL"}, | ||||
| 						Type:        "string", | ||||
| 						Mandatory:   true, | ||||
| 						Aliases:     []config.Alias{}, | ||||
| 						Default:     os.Getenv("PIPER_serverUrl"), | ||||
| 					}, | ||||
| 					{ | ||||
| 						Name: "authToken", | ||||
| 						ResourceRef: []config.ResourceReference{ | ||||
| 							{ | ||||
| 								Name: "influxAuthTokenId", | ||||
| 								Type: "secret", | ||||
| 							}, | ||||
|  | ||||
| 							{ | ||||
| 								Name:  "", | ||||
| 								Paths: []string{"$(vaultPath)/influxdb", "$(vaultBasePath)/$(vaultPipelineName)/influxdb", "$(vaultBasePath)/GROUP-SECRETS/influxdb"}, | ||||
| 								Type:  "vaultSecret", | ||||
| 							}, | ||||
| 						}, | ||||
| 						Scope:     []string{"PARAMETERS", "STAGES", "STEPS"}, | ||||
| 						Type:      "string", | ||||
| 						Mandatory: true, | ||||
| 						Aliases:   []config.Alias{}, | ||||
| 						Default:   os.Getenv("PIPER_authToken"), | ||||
| 					}, | ||||
| 					{ | ||||
| 						Name:        "bucket", | ||||
| 						ResourceRef: []config.ResourceReference{}, | ||||
| 						Scope:       []string{"PARAMETERS", "STAGES", "STEPS"}, | ||||
| 						Type:        "string", | ||||
| 						Mandatory:   false, | ||||
| 						Aliases:     []config.Alias{}, | ||||
| 						Default:     `piper`, | ||||
| 					}, | ||||
| 					{ | ||||
| 						Name:        "organization", | ||||
| 						ResourceRef: []config.ResourceReference{}, | ||||
| 						Scope:       []string{"PARAMETERS", "STAGES", "STEPS"}, | ||||
| 						Type:        "string", | ||||
| 						Mandatory:   false, | ||||
| 						Aliases:     []config.Alias{}, | ||||
| 						Default:     os.Getenv("PIPER_organization"), | ||||
| 					}, | ||||
| 					{ | ||||
| 						Name:        "dataMap", | ||||
| 						ResourceRef: []config.ResourceReference{}, | ||||
| 						Scope:       []string{"PARAMETERS", "STAGES", "STEPS"}, | ||||
| 						Type:        "string", | ||||
| 						Mandatory:   true, | ||||
| 						Aliases:     []config.Alias{}, | ||||
| 						Default:     os.Getenv("PIPER_dataMap"), | ||||
| 					}, | ||||
| 					{ | ||||
| 						Name:        "dataMapTags", | ||||
| 						ResourceRef: []config.ResourceReference{}, | ||||
| 						Scope:       []string{"PARAMETERS", "STAGES", "STEPS"}, | ||||
| 						Type:        "string", | ||||
| 						Mandatory:   false, | ||||
| 						Aliases:     []config.Alias{}, | ||||
| 						Default:     os.Getenv("PIPER_dataMapTags"), | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	return theMetaData | ||||
| } | ||||
							
								
								
									
										17
									
								
								cmd/influxWriteData_generated_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								cmd/influxWriteData_generated_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| package cmd | ||||
|  | ||||
| import ( | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| func TestInfluxWriteDataCommand(t *testing.T) { | ||||
| 	t.Parallel() | ||||
|  | ||||
| 	testCmd := InfluxWriteDataCommand() | ||||
|  | ||||
| 	// only high level testing performed - details are tested in step generation procedure | ||||
| 	assert.Equal(t, "influxWriteData", testCmd.Use, "command name incorrect") | ||||
|  | ||||
| } | ||||
							
								
								
									
										77
									
								
								cmd/influxWriteData_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								cmd/influxWriteData_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,77 @@ | ||||
| package cmd | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/influx/mocks" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| 	"github.com/stretchr/testify/mock" | ||||
| ) | ||||
|  | ||||
| func TestWriteData(t *testing.T) { | ||||
| 	options := &influxWriteDataOptions{ | ||||
| 		ServerURL:    "http://localhost:8086", | ||||
| 		AuthToken:    "authToken", | ||||
| 		Bucket:       "piper", | ||||
| 		Organization: "org", | ||||
| 	} | ||||
| 	errString := "some error" | ||||
| 	errWriteData := errors.New(errString) | ||||
| 	tests := []struct { | ||||
| 		name          string | ||||
| 		dataMap       string | ||||
| 		dataMapTags   string | ||||
| 		writeDataErr  error | ||||
| 		errExpected   bool | ||||
| 		errIncludeStr string | ||||
| 	}{ | ||||
| 		{ | ||||
| 			"Test writing metrics with correct json data - success", | ||||
| 			`{"series_1": {"field_a": 11, "field_b": 12}, "series_2": {"field_c": 21, "field_d": 22}}`, | ||||
| 			`{"series_1": {"tag_a": "a", "tag_b": "b"}, "series_2": {"tag_c": "c", "tag_d": "d"}}`, | ||||
| 			nil, | ||||
| 			false, | ||||
| 			"", | ||||
| 		}, | ||||
| 		{ | ||||
| 			"Test writing metrics with invalid dataMap", | ||||
| 			`"series_1": {"field_a": 11, "field_b": 12}, "series_2": {"field_c": 21, "field_d": 22}`, | ||||
| 			`{"series_1": {"tag_a": "a", "tag_b": "b"}, "series_2": {"tag_c": "c", "tag_d": "d"}}`, | ||||
| 			nil, | ||||
| 			false, | ||||
| 			"Failed to unmarshal dataMap:", | ||||
| 		}, | ||||
| 		{ | ||||
| 			"Test writing metrics with invalid dataMapTags", | ||||
| 			`{"series_1": {"field_a": 11, "field_b": 12}, "series_2": {"field_c": 21, "field_d": 22}}`, | ||||
| 			`{"series_1": {"tag_a": 2, "tag_b": "b"}, "series_2": {"tag_c": "c", "tag_d": "d"}}`, | ||||
| 			nil, | ||||
| 			false, | ||||
| 			"Failed to unmarshal dataMapTags:", | ||||
| 		}, | ||||
| 		{ | ||||
| 			"Test writing metrics with correct json data - failed", | ||||
| 			`{"series_1": {"field_a": 11, "field_b": 12}, "series_2": {"field_c": 21, "field_d": 22}}`, | ||||
| 			`{"series_1": {"tag_a": "a", "tag_b": "b"}, "series_2": {"tag_c": "c", "tag_d": "d"}}`, | ||||
| 			errWriteData, | ||||
| 			true, | ||||
| 			errString, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	for _, tt := range tests { | ||||
| 		t.Run(tt.name, func(t *testing.T) { | ||||
| 			influxClientMock := &mocks.Client{} | ||||
| 			writeAPIBlockingMock := &mocks.WriteAPIBlocking{} | ||||
| 			writeAPIBlockingMock.On("WritePoint", mock.Anything, mock.Anything).Return(tt.writeDataErr) | ||||
| 			influxClientMock.On("WriteAPIBlocking", mock.Anything, mock.Anything).Return(writeAPIBlockingMock) | ||||
| 			options.DataMap = tt.dataMap | ||||
| 			options.DataMapTags = tt.dataMapTags | ||||
| 			err := writeData(options, influxClientMock) | ||||
| 			if err != nil { | ||||
| 				assert.Contains(t, err.Error(), tt.errIncludeStr) | ||||
| 			} | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| @@ -47,6 +47,7 @@ func GetAllStepMetadata() map[string]config.StepData { | ||||
| 		"githubSetCommitStatus":                     githubSetCommitStatusMetadata(), | ||||
| 		"gitopsUpdateDeployment":                    gitopsUpdateDeploymentMetadata(), | ||||
| 		"hadolintExecute":                           hadolintExecuteMetadata(), | ||||
| 		"influxWriteData":                           influxWriteDataMetadata(), | ||||
| 		"integrationArtifactDeploy":                 integrationArtifactDeployMetadata(), | ||||
| 		"integrationArtifactDownload":               integrationArtifactDownloadMetadata(), | ||||
| 		"integrationArtifactGetMplStatus":           integrationArtifactGetMplStatusMetadata(), | ||||
|   | ||||
| @@ -156,6 +156,7 @@ func Execute() { | ||||
| 	rootCmd.AddCommand(TransportRequestReqIDFromGitCommand()) | ||||
| 	rootCmd.AddCommand(WritePipelineEnv()) | ||||
| 	rootCmd.AddCommand(ReadPipelineEnv()) | ||||
| 	rootCmd.AddCommand(InfluxWriteDataCommand()) | ||||
|  | ||||
| 	addRootFlags(rootCmd) | ||||
| 	if err := rootCmd.Execute(); err != nil { | ||||
|   | ||||
							
								
								
									
										1
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								go.mod
									
									
									
									
									
								
							| @@ -31,6 +31,7 @@ require ( | ||||
| 	github.com/hashicorp/vault/api v1.1.0 | ||||
| 	github.com/huandu/xstrings v1.3.2 // indirect | ||||
| 	github.com/imdario/mergo v0.3.11 // indirect | ||||
| 	github.com/influxdata/influxdb-client-go/v2 v2.4.0 | ||||
| 	github.com/jarcoal/httpmock v1.0.8 | ||||
| 	github.com/magiconair/properties v1.8.4 | ||||
| 	github.com/magicsong/color-glog v0.0.1 // indirect | ||||
|   | ||||
							
								
								
									
										29
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								go.sum
									
									
									
									
									
								
							| @@ -327,10 +327,13 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsr | ||||
| github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= | ||||
| github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w= | ||||
| github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= | ||||
| github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= | ||||
| github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||
| github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||
| github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||||
| github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||
| github.com/deepmap/oapi-codegen v1.6.0 h1:w/d1ntwh91XI0b/8ja7+u5SvA4IFfM0UNNLmiDR1gg0= | ||||
| github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M= | ||||
| github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc h1:VRRKCwnzqk8QCaRC4os14xoKDdbHqqlJtJA0oc1ZAjg= | ||||
| github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= | ||||
| github.com/denverdino/aliyungo v0.0.0-20170926055100-d3308649c661 h1:lrWnAyy/F72MbxIxFUzKmcMCdt9Oi8RzpAxzTNQHD7o= | ||||
| @@ -428,6 +431,7 @@ github.com/gammazero/deque v0.0.0-20190130191400-2afb3858e9c7/go.mod h1:GeIq9qoE | ||||
| github.com/gammazero/workerpool v0.0.0-20190406235159-88d534f22b56 h1:VzbudKn/nvxYKOdzgkEBS6SSreRjAgoJ+ZeS4wPFkgc= | ||||
| github.com/gammazero/workerpool v0.0.0-20190406235159-88d534f22b56/go.mod h1:w9RqFVO2BM3xwWEcAB8Fwp0OviTBBEiRmSBDfbXnd3w= | ||||
| github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= | ||||
| github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= | ||||
| github.com/getsentry/sentry-go v0.7.0 h1:MR2yfR4vFfv/2+iBuSnkdQwVg7N9cJzihZ6KJu7srwQ= | ||||
| github.com/getsentry/sentry-go v0.7.0/go.mod h1:pLFpD2Y5RHIKF9Bw3KH6/68DeN2K/XBJd8awjdPnUwg= | ||||
| github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= | ||||
| @@ -447,6 +451,7 @@ github.com/go-asn1-ber/asn1-ber v1.4.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkPro | ||||
| github.com/go-asn1-ber/asn1-ber v1.5.1 h1:pDbRAunXzIUXfx4CB2QJFv5IuPiuoW+sWvr/Us009o8= | ||||
| github.com/go-asn1-ber/asn1-ber v1.5.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= | ||||
| github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= | ||||
| github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= | ||||
| github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= | ||||
| github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= | ||||
| github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= | ||||
| @@ -499,8 +504,9 @@ github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+ | ||||
| github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= | ||||
| github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= | ||||
| github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= | ||||
| github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w= | ||||
| github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= | ||||
| github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= | ||||
| github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= | ||||
| github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= | ||||
| github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= | ||||
| github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= | ||||
| @@ -651,6 +657,7 @@ github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8l | ||||
| github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= | ||||
| github.com/golang/snappy v0.0.2 h1:aeE13tS0IiQgFjYdoL8qN3K1N2bXXtI6Vi51/y7BpMw= | ||||
| github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= | ||||
| github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= | ||||
| github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= | ||||
| github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= | ||||
| github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= | ||||
| @@ -715,8 +722,9 @@ github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75/go.mod h1:g2644b0 | ||||
| github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= | ||||
| github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= | ||||
| github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= | ||||
| github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc= | ||||
| github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= | ||||
| github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= | ||||
| github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= | ||||
| github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= | ||||
| github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= | ||||
| github.com/gorilla/sessions v1.2.0 h1:S7P+1Hm5V/AT9cjEcUD5uDaQSX0OE577aCXgoaKpYbQ= | ||||
| @@ -949,7 +957,11 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH | ||||
| github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= | ||||
| github.com/influxdata/influxdb v0.0.0-20190411212539-d24b7ba8c4c4 h1:3K3KcD4S6/Y2hevi70EzUTNKOS3cryQyhUnkjE6Tz0w= | ||||
| github.com/influxdata/influxdb v0.0.0-20190411212539-d24b7ba8c4c4/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= | ||||
| github.com/influxdata/influxdb-client-go/v2 v2.4.0 h1:HGBfZYStlx3Kqvsv1h2pJixbCl/jhnFtxpKFAv9Tu5k= | ||||
| github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8= | ||||
| github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= | ||||
| github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 h1:W9WBk7wlPfJLvMCdtV4zPulc4uCPrlywQOmbFOhgQNU= | ||||
| github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= | ||||
| github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= | ||||
| github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= | ||||
| github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI= | ||||
| @@ -1054,6 +1066,7 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= | ||||
| github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= | ||||
| github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= | ||||
| github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= | ||||
| github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= | ||||
| github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= | ||||
| github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= | ||||
| github.com/lestrrat-go/jwx v0.9.0/go.mod h1:iEoxlYfZjvoGpuWwxUz+eR5e6KTJGsaRcy/YNA/UnBk= | ||||
| @@ -1087,6 +1100,7 @@ github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsI | ||||
| github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= | ||||
| github.com/martini-contrib/render v0.0.0-20150707142108-ec18f8345a11 h1:YFh+sjyJTMQSYjKwM4dFKhJPJC/wfo98tPUc17HdoYw= | ||||
| github.com/martini-contrib/render v0.0.0-20150707142108-ec18f8345a11/go.mod h1:Ah2dBMoxZEqk118as2T4u4fjfXarE0pPnMJaArZQZsI= | ||||
| github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= | ||||
| github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= | ||||
| github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= | ||||
| github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= | ||||
| @@ -1464,6 +1478,7 @@ github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKn | ||||
| github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= | ||||
| github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= | ||||
| github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= | ||||
| github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= | ||||
| github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= | ||||
| github.com/vdemeester/k8s-pkg-credentialprovider v1.17.4/go.mod h1:inCTmtUdr5KJbreVojo06krnTgaeAz/Z7lynpPk/Q2c= | ||||
| github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= | ||||
| @@ -1660,8 +1675,9 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R | ||||
| golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= | ||||
| golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= | ||||
| golang.org/x/net v0.0.0-20201002202402-0a1ea396d57c/go.mod h1:iQL9McJNjoIa5mjH6nYTCTZXUN6RP+XW3eib7Ya3XcI= | ||||
| golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME= | ||||
| golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= | ||||
| golang.org/x/net v0.0.0-20210119194325-5f4716e94777 h1:003p0dJM77cxMSyCPFphvZf/Y5/NXf5fzg6ufd1/Oew= | ||||
| golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= | ||||
| golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= | ||||
| golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= | ||||
| golang.org/x/oauth2 v0.0.0-20190130055435-99b60b757ec1/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= | ||||
| @@ -1686,8 +1702,9 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cO | ||||
| golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||
| golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ= | ||||
| golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/term v0.0.0-20201117132131-f5c789dd3221 h1:/ZHdbVpdR/jk3g30/d4yUL0JU9kksj8+F/bnQUVLGDM= | ||||
| golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= | ||||
| golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= | ||||
| golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | ||||
| golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||||
| golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||||
| golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||||
| @@ -1702,8 +1719,10 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb | ||||
| golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= | ||||
| golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= | ||||
| golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= | ||||
| golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e h1:EHBhcS0mlXEAVwNyO2dLfjToGsyY4j24pTs2ScHnX7s= | ||||
| golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= | ||||
| golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= | ||||
| golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE= | ||||
| golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= | ||||
| golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||||
| golang.org/x/tools v0.0.0-20180810170437-e96c4e24768d/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||||
| golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||||
|   | ||||
							
								
								
									
										92
									
								
								integration/integration_influx_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								integration/integration_influx_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,92 @@ | ||||
| // +build integration | ||||
| // can be execute with go test -tags=integration ./integration/... | ||||
|  | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"fmt" | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/influx" | ||||
| 	influxdb2 "github.com/influxdata/influxdb-client-go/v2" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| 	"github.com/testcontainers/testcontainers-go" | ||||
| 	"github.com/testcontainers/testcontainers-go/wait" | ||||
| ) | ||||
|  | ||||
| func TestWriteMetrics(t *testing.T) { | ||||
| 	t.Parallel() | ||||
| 	ctx := context.Background() | ||||
| 	const authToken = "influx-token" | ||||
| 	const username = "username" | ||||
| 	const password = "password" | ||||
| 	const bucket = "piper" | ||||
| 	const organization = "org" | ||||
|  | ||||
| 	req := testcontainers.GenericContainerRequest{ | ||||
| 		ContainerRequest: testcontainers.ContainerRequest{ | ||||
| 			AlwaysPullImage: true, | ||||
| 			Image:           "influxdb:2.0", | ||||
| 			ExposedPorts:    []string{"8086/tcp"}, | ||||
| 			Env: map[string]string{ | ||||
| 				"DOCKER_INFLUXDB_INIT_MODE":        "setup", | ||||
| 				"DOCKER_INFLUXDB_INIT_USERNAME":    username, | ||||
| 				"DOCKER_INFLUXDB_INIT_PASSWORD":    password, | ||||
| 				"DOCKER_INFLUXDB_INIT_ORG":         organization, | ||||
| 				"DOCKER_INFLUXDB_INIT_BUCKET":      bucket, | ||||
| 				"DOCKER_INFLUXDB_INIT_ADMIN_TOKEN": authToken, | ||||
| 			}, | ||||
| 			WaitingFor: wait.ForListeningPort("8086/tcp"), | ||||
| 		}, | ||||
| 		Started: true, | ||||
| 	} | ||||
|  | ||||
| 	influxContainer, err := testcontainers.GenericContainer(ctx, req) | ||||
| 	assert.NoError(t, err) | ||||
| 	defer influxContainer.Terminate(ctx) | ||||
|  | ||||
| 	ip, err := influxContainer.Host(ctx) | ||||
| 	assert.NoError(t, err) | ||||
| 	port, err := influxContainer.MappedPort(ctx, "8086") | ||||
| 	host := fmt.Sprintf("http://%s:%s", ip, port.Port()) | ||||
| 	dataMap := map[string]map[string]interface{}{ | ||||
| 		"series_1": {"field_a": 11, "field_b": 12}, | ||||
| 		"series_2": {"field_c": 21, "field_d": 22}, | ||||
| 	} | ||||
| 	dataMapTags := map[string]map[string]string{ | ||||
| 		"series_1": {"tag_a": "a", "tag_b": "b"}, | ||||
| 		"series_2": {"tag_c": "c", "tag_d": "d"}, | ||||
| 	} | ||||
| 	influxClient := influxdb2.NewClient(host, authToken) | ||||
| 	defer influxClient.Close() | ||||
| 	client := influx.NewClient(influxClient, organization, bucket) | ||||
| 	err = client.WriteMetrics(dataMap, dataMapTags) | ||||
| 	assert.NoError(t, err) | ||||
|  | ||||
| 	queryAPI := influxClient.QueryAPI(organization) | ||||
| 	result, err := queryAPI.Query(context.Background(), | ||||
| 		`from(bucket:"piper")|> range(start: -1h) |> filter(fn: (r) => r._measurement == "series_1" or r._measurement == "series_2")`) | ||||
| 	assert.NoError(t, err) | ||||
| 	valuesMap := map[string]map[string]interface{}{} | ||||
| 	expectedValuesMap := map[string]map[string]interface{}{ | ||||
| 		"series_1_field_a": {"_field": "field_a", "_measurement": "series_1", "_value": int64(11), "tag_a": "a", "tag_b": "b"}, | ||||
| 		"series_1_field_b": {"_field": "field_b", "_measurement": "series_1", "_value": int64(12), "tag_a": "a", "tag_b": "b"}, | ||||
| 		"series_2_field_c": {"_field": "field_c", "_measurement": "series_2", "_value": int64(21), "tag_c": "c", "tag_d": "d"}, | ||||
| 		"series_2_field_d": {"_field": "field_d", "_measurement": "series_2", "_value": int64(22), "tag_c": "c", "tag_d": "d"}, | ||||
| 	} | ||||
| 	for result.Next() { | ||||
| 		values := result.Record().Values() | ||||
| 		measurement := values["_measurement"] | ||||
| 		field := values["_field"] | ||||
| 		delete(values, "_start") | ||||
| 		delete(values, "_stop") | ||||
| 		delete(values, "_time") | ||||
| 		delete(values, "result") | ||||
| 		delete(values, "table") | ||||
| 		valuesMap[fmt.Sprintf("%v_%v", measurement, field)] = values | ||||
| 	} | ||||
| 	assert.NoError(t, result.Err()) | ||||
| 	assert.Equal(t, len(expectedValuesMap), len(valuesMap)) | ||||
| 	assert.Equal(t, expectedValuesMap, valuesMap) | ||||
| } | ||||
							
								
								
									
										45
									
								
								pkg/influx/client.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								pkg/influx/client.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| package influx | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"time" | ||||
|  | ||||
| 	influxdb2 "github.com/influxdata/influxdb-client-go/v2" | ||||
| ) | ||||
|  | ||||
| // Client handles communication with InfluxDB | ||||
| type Client struct { | ||||
| 	client       influxdb2.Client | ||||
| 	ctx          context.Context | ||||
| 	organization string | ||||
| 	bucket       string | ||||
| } | ||||
|  | ||||
| // NewClient instantiates a Client | ||||
| func NewClient(influxClient influxdb2.Client, organization string, bucket string) *Client { | ||||
| 	ctx := context.Background() | ||||
| 	client := Client{ | ||||
| 		client:       influxClient, | ||||
| 		ctx:          ctx, | ||||
| 		organization: organization, | ||||
| 		bucket:       bucket, | ||||
| 	} | ||||
| 	return &client | ||||
| } | ||||
|  | ||||
| // WriteMetrics writes metrics to InfluxDB | ||||
| func (c *Client) WriteMetrics(dataMap map[string]map[string]interface{}, dataMapTags map[string]map[string]string) error { | ||||
| 	writeAPI := c.client.WriteAPIBlocking(c.organization, c.bucket) | ||||
|  | ||||
| 	for measurement, fields := range dataMap { | ||||
| 		tags := dataMapTags[measurement] | ||||
| 		point := influxdb2.NewPoint(measurement, | ||||
| 			tags, | ||||
| 			fields, | ||||
| 			time.Now()) | ||||
| 		if err := writeAPI.WritePoint(c.ctx, point); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										62
									
								
								pkg/influx/client_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								pkg/influx/client_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | ||||
| package influx | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/influx/mocks" | ||||
| 	"github.com/stretchr/testify/mock" | ||||
| ) | ||||
|  | ||||
| func TestWriteMetrics(t *testing.T) { | ||||
| 	errWriteMetrics := errors.New("error") | ||||
| 	tests := []struct { | ||||
| 		name          string | ||||
| 		dataMap       map[string]map[string]interface{} | ||||
| 		dataMapTags   map[string]map[string]string | ||||
| 		writePointErr error | ||||
| 		err           error | ||||
| 	}{ | ||||
| 		{ | ||||
| 			"Test writing metrics - success", | ||||
| 			map[string]map[string]interface{}{ | ||||
| 				"series_1": {"field_a": 11, "field_b": 12}, | ||||
| 				"series_2": {"field_c": 21, "field_d": 22}, | ||||
| 			}, | ||||
| 			map[string]map[string]string{ | ||||
| 				"series_1": {"tag_a": "a", "tag_b": "b"}, | ||||
| 				"series_2": {"tag_c": "c", "tag_d": "d"}, | ||||
| 			}, | ||||
| 			nil, | ||||
| 			nil, | ||||
| 		}, | ||||
| 		{ | ||||
| 			"Test writing metrics - failed", | ||||
| 			map[string]map[string]interface{}{ | ||||
| 				"series_1": {"field_a": 11, "field_b": 12}, | ||||
| 				"series_2": {"field_c": 21, "field_d": 22}, | ||||
| 			}, | ||||
| 			map[string]map[string]string{ | ||||
| 				"series_1": {"tag_a": "a", "tag_b": "b"}, | ||||
| 				"series_2": {"tag_c": "c", "tag_d": "d"}, | ||||
| 			}, | ||||
| 			errWriteMetrics, | ||||
| 			errWriteMetrics, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	for _, tt := range tests { | ||||
| 		t.Run(tt.name, func(t *testing.T) { | ||||
| 			influxClientMock := &mocks.Client{} | ||||
| 			client := NewClient(influxClientMock, "org", "piper") | ||||
| 			writeAPIBlockingMock := &mocks.WriteAPIBlocking{} | ||||
| 			writeAPIBlockingMock.On("WritePoint", client.ctx, mock.Anything).Return(tt.writePointErr) | ||||
| 			influxClientMock.On("WriteAPIBlocking", client.organization, client.bucket).Return(writeAPIBlockingMock) | ||||
| 			err := client.WriteMetrics(tt.dataMap, tt.dataMapTags) | ||||
| 			if err != tt.err { | ||||
| 				t.Errorf("\nactual: %q\nexpected: %q\n", err, tt.err) | ||||
| 			} | ||||
| 		}) | ||||
| 	} | ||||
|  | ||||
| } | ||||
							
								
								
									
										300
									
								
								pkg/influx/mocks/client.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										300
									
								
								pkg/influx/mocks/client.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,300 @@ | ||||
| // Code generated by mockery v2.7.4. DO NOT EDIT. | ||||
|  | ||||
| package mocks | ||||
|  | ||||
| import ( | ||||
| 	context "context" | ||||
|  | ||||
| 	api "github.com/influxdata/influxdb-client-go/v2/api" | ||||
|  | ||||
| 	domain "github.com/influxdata/influxdb-client-go/v2/domain" | ||||
|  | ||||
| 	http "github.com/influxdata/influxdb-client-go/v2/api/http" | ||||
|  | ||||
| 	influxdb2 "github.com/influxdata/influxdb-client-go/v2" | ||||
|  | ||||
| 	mock "github.com/stretchr/testify/mock" | ||||
| ) | ||||
|  | ||||
| // Client is an autogenerated mock type for the Client type | ||||
| type Client struct { | ||||
| 	mock.Mock | ||||
| } | ||||
|  | ||||
| // AuthorizationsAPI provides a mock function with given fields: | ||||
| func (_m *Client) AuthorizationsAPI() api.AuthorizationsAPI { | ||||
| 	ret := _m.Called() | ||||
|  | ||||
| 	var r0 api.AuthorizationsAPI | ||||
| 	if rf, ok := ret.Get(0).(func() api.AuthorizationsAPI); ok { | ||||
| 		r0 = rf() | ||||
| 	} else { | ||||
| 		if ret.Get(0) != nil { | ||||
| 			r0 = ret.Get(0).(api.AuthorizationsAPI) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return r0 | ||||
| } | ||||
|  | ||||
| // BucketsAPI provides a mock function with given fields: | ||||
| func (_m *Client) BucketsAPI() api.BucketsAPI { | ||||
| 	ret := _m.Called() | ||||
|  | ||||
| 	var r0 api.BucketsAPI | ||||
| 	if rf, ok := ret.Get(0).(func() api.BucketsAPI); ok { | ||||
| 		r0 = rf() | ||||
| 	} else { | ||||
| 		if ret.Get(0) != nil { | ||||
| 			r0 = ret.Get(0).(api.BucketsAPI) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return r0 | ||||
| } | ||||
|  | ||||
| // Close provides a mock function with given fields: | ||||
| func (_m *Client) Close() { | ||||
| 	_m.Called() | ||||
| } | ||||
|  | ||||
| // DeleteAPI provides a mock function with given fields: | ||||
| func (_m *Client) DeleteAPI() api.DeleteAPI { | ||||
| 	ret := _m.Called() | ||||
|  | ||||
| 	var r0 api.DeleteAPI | ||||
| 	if rf, ok := ret.Get(0).(func() api.DeleteAPI); ok { | ||||
| 		r0 = rf() | ||||
| 	} else { | ||||
| 		if ret.Get(0) != nil { | ||||
| 			r0 = ret.Get(0).(api.DeleteAPI) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return r0 | ||||
| } | ||||
|  | ||||
| // HTTPService provides a mock function with given fields: | ||||
| func (_m *Client) HTTPService() http.Service { | ||||
| 	ret := _m.Called() | ||||
|  | ||||
| 	var r0 http.Service | ||||
| 	if rf, ok := ret.Get(0).(func() http.Service); ok { | ||||
| 		r0 = rf() | ||||
| 	} else { | ||||
| 		if ret.Get(0) != nil { | ||||
| 			r0 = ret.Get(0).(http.Service) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return r0 | ||||
| } | ||||
|  | ||||
| // Health provides a mock function with given fields: ctx | ||||
| func (_m *Client) Health(ctx context.Context) (*domain.HealthCheck, error) { | ||||
| 	ret := _m.Called(ctx) | ||||
|  | ||||
| 	var r0 *domain.HealthCheck | ||||
| 	if rf, ok := ret.Get(0).(func(context.Context) *domain.HealthCheck); ok { | ||||
| 		r0 = rf(ctx) | ||||
| 	} else { | ||||
| 		if ret.Get(0) != nil { | ||||
| 			r0 = ret.Get(0).(*domain.HealthCheck) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	var r1 error | ||||
| 	if rf, ok := ret.Get(1).(func(context.Context) error); ok { | ||||
| 		r1 = rf(ctx) | ||||
| 	} else { | ||||
| 		r1 = ret.Error(1) | ||||
| 	} | ||||
|  | ||||
| 	return r0, r1 | ||||
| } | ||||
|  | ||||
| // LabelsAPI provides a mock function with given fields: | ||||
| func (_m *Client) LabelsAPI() api.LabelsAPI { | ||||
| 	ret := _m.Called() | ||||
|  | ||||
| 	var r0 api.LabelsAPI | ||||
| 	if rf, ok := ret.Get(0).(func() api.LabelsAPI); ok { | ||||
| 		r0 = rf() | ||||
| 	} else { | ||||
| 		if ret.Get(0) != nil { | ||||
| 			r0 = ret.Get(0).(api.LabelsAPI) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return r0 | ||||
| } | ||||
|  | ||||
| // Options provides a mock function with given fields: | ||||
| func (_m *Client) Options() *influxdb2.Options { | ||||
| 	ret := _m.Called() | ||||
|  | ||||
| 	var r0 *influxdb2.Options | ||||
| 	if rf, ok := ret.Get(0).(func() *influxdb2.Options); ok { | ||||
| 		r0 = rf() | ||||
| 	} else { | ||||
| 		if ret.Get(0) != nil { | ||||
| 			r0 = ret.Get(0).(*influxdb2.Options) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return r0 | ||||
| } | ||||
|  | ||||
| // OrganizationsAPI provides a mock function with given fields: | ||||
| func (_m *Client) OrganizationsAPI() api.OrganizationsAPI { | ||||
| 	ret := _m.Called() | ||||
|  | ||||
| 	var r0 api.OrganizationsAPI | ||||
| 	if rf, ok := ret.Get(0).(func() api.OrganizationsAPI); ok { | ||||
| 		r0 = rf() | ||||
| 	} else { | ||||
| 		if ret.Get(0) != nil { | ||||
| 			r0 = ret.Get(0).(api.OrganizationsAPI) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return r0 | ||||
| } | ||||
|  | ||||
| // QueryAPI provides a mock function with given fields: org | ||||
| func (_m *Client) QueryAPI(org string) api.QueryAPI { | ||||
| 	ret := _m.Called(org) | ||||
|  | ||||
| 	var r0 api.QueryAPI | ||||
| 	if rf, ok := ret.Get(0).(func(string) api.QueryAPI); ok { | ||||
| 		r0 = rf(org) | ||||
| 	} else { | ||||
| 		if ret.Get(0) != nil { | ||||
| 			r0 = ret.Get(0).(api.QueryAPI) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return r0 | ||||
| } | ||||
|  | ||||
| // Ready provides a mock function with given fields: ctx | ||||
| func (_m *Client) Ready(ctx context.Context) (bool, error) { | ||||
| 	ret := _m.Called(ctx) | ||||
|  | ||||
| 	var r0 bool | ||||
| 	if rf, ok := ret.Get(0).(func(context.Context) bool); ok { | ||||
| 		r0 = rf(ctx) | ||||
| 	} else { | ||||
| 		r0 = ret.Get(0).(bool) | ||||
| 	} | ||||
|  | ||||
| 	var r1 error | ||||
| 	if rf, ok := ret.Get(1).(func(context.Context) error); ok { | ||||
| 		r1 = rf(ctx) | ||||
| 	} else { | ||||
| 		r1 = ret.Error(1) | ||||
| 	} | ||||
|  | ||||
| 	return r0, r1 | ||||
| } | ||||
|  | ||||
| // ServerURL provides a mock function with given fields: | ||||
| func (_m *Client) ServerURL() string { | ||||
| 	ret := _m.Called() | ||||
|  | ||||
| 	var r0 string | ||||
| 	if rf, ok := ret.Get(0).(func() string); ok { | ||||
| 		r0 = rf() | ||||
| 	} else { | ||||
| 		r0 = ret.Get(0).(string) | ||||
| 	} | ||||
|  | ||||
| 	return r0 | ||||
| } | ||||
|  | ||||
| // Setup provides a mock function with given fields: ctx, username, password, org, bucket, retentionPeriodHours | ||||
| func (_m *Client) Setup(ctx context.Context, username string, password string, org string, bucket string, retentionPeriodHours int) (*domain.OnboardingResponse, error) { | ||||
| 	ret := _m.Called(ctx, username, password, org, bucket, retentionPeriodHours) | ||||
|  | ||||
| 	var r0 *domain.OnboardingResponse | ||||
| 	if rf, ok := ret.Get(0).(func(context.Context, string, string, string, string, int) *domain.OnboardingResponse); ok { | ||||
| 		r0 = rf(ctx, username, password, org, bucket, retentionPeriodHours) | ||||
| 	} else { | ||||
| 		if ret.Get(0) != nil { | ||||
| 			r0 = ret.Get(0).(*domain.OnboardingResponse) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	var r1 error | ||||
| 	if rf, ok := ret.Get(1).(func(context.Context, string, string, string, string, int) error); ok { | ||||
| 		r1 = rf(ctx, username, password, org, bucket, retentionPeriodHours) | ||||
| 	} else { | ||||
| 		r1 = ret.Error(1) | ||||
| 	} | ||||
|  | ||||
| 	return r0, r1 | ||||
| } | ||||
|  | ||||
| // TasksAPI provides a mock function with given fields: | ||||
| func (_m *Client) TasksAPI() api.TasksAPI { | ||||
| 	ret := _m.Called() | ||||
|  | ||||
| 	var r0 api.TasksAPI | ||||
| 	if rf, ok := ret.Get(0).(func() api.TasksAPI); ok { | ||||
| 		r0 = rf() | ||||
| 	} else { | ||||
| 		if ret.Get(0) != nil { | ||||
| 			r0 = ret.Get(0).(api.TasksAPI) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return r0 | ||||
| } | ||||
|  | ||||
| // UsersAPI provides a mock function with given fields: | ||||
| func (_m *Client) UsersAPI() api.UsersAPI { | ||||
| 	ret := _m.Called() | ||||
|  | ||||
| 	var r0 api.UsersAPI | ||||
| 	if rf, ok := ret.Get(0).(func() api.UsersAPI); ok { | ||||
| 		r0 = rf() | ||||
| 	} else { | ||||
| 		if ret.Get(0) != nil { | ||||
| 			r0 = ret.Get(0).(api.UsersAPI) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return r0 | ||||
| } | ||||
|  | ||||
| // WriteAPI provides a mock function with given fields: org, bucket | ||||
| func (_m *Client) WriteAPI(org string, bucket string) api.WriteAPI { | ||||
| 	ret := _m.Called(org, bucket) | ||||
|  | ||||
| 	var r0 api.WriteAPI | ||||
| 	if rf, ok := ret.Get(0).(func(string, string) api.WriteAPI); ok { | ||||
| 		r0 = rf(org, bucket) | ||||
| 	} else { | ||||
| 		if ret.Get(0) != nil { | ||||
| 			r0 = ret.Get(0).(api.WriteAPI) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return r0 | ||||
| } | ||||
|  | ||||
| // WriteAPIBlocking provides a mock function with given fields: org, bucket | ||||
| func (_m *Client) WriteAPIBlocking(org string, bucket string) api.WriteAPIBlocking { | ||||
| 	ret := _m.Called(org, bucket) | ||||
|  | ||||
| 	var r0 api.WriteAPIBlocking | ||||
| 	if rf, ok := ret.Get(0).(func(string, string) api.WriteAPIBlocking); ok { | ||||
| 		r0 = rf(org, bucket) | ||||
| 	} else { | ||||
| 		if ret.Get(0) != nil { | ||||
| 			r0 = ret.Get(0).(api.WriteAPIBlocking) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return r0 | ||||
| } | ||||
							
								
								
									
										57
									
								
								pkg/influx/mocks/writeAPIBlocking.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								pkg/influx/mocks/writeAPIBlocking.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | ||||
| // Code generated by mockery v2.7.4. DO NOT EDIT. | ||||
|  | ||||
| package mocks | ||||
|  | ||||
| import ( | ||||
| 	context "context" | ||||
|  | ||||
| 	write "github.com/influxdata/influxdb-client-go/v2/api/write" | ||||
| 	mock "github.com/stretchr/testify/mock" | ||||
| ) | ||||
|  | ||||
| // WriteAPIBlocking is an autogenerated mock type for the WriteAPIBlocking type | ||||
| type WriteAPIBlocking struct { | ||||
| 	mock.Mock | ||||
| } | ||||
|  | ||||
| // WritePoint provides a mock function with given fields: ctx, point | ||||
| func (_m *WriteAPIBlocking) WritePoint(ctx context.Context, point ...*write.Point) error { | ||||
| 	_va := make([]interface{}, len(point)) | ||||
| 	for _i := range point { | ||||
| 		_va[_i] = point[_i] | ||||
| 	} | ||||
| 	var _ca []interface{} | ||||
| 	_ca = append(_ca, ctx) | ||||
| 	_ca = append(_ca, _va...) | ||||
| 	ret := _m.Called(_ca...) | ||||
|  | ||||
| 	var r0 error | ||||
| 	if rf, ok := ret.Get(0).(func(context.Context, ...*write.Point) error); ok { | ||||
| 		r0 = rf(ctx, point...) | ||||
| 	} else { | ||||
| 		r0 = ret.Error(0) | ||||
| 	} | ||||
|  | ||||
| 	return r0 | ||||
| } | ||||
|  | ||||
| // WriteRecord provides a mock function with given fields: ctx, line | ||||
| func (_m *WriteAPIBlocking) WriteRecord(ctx context.Context, line ...string) error { | ||||
| 	_va := make([]interface{}, len(line)) | ||||
| 	for _i := range line { | ||||
| 		_va[_i] = line[_i] | ||||
| 	} | ||||
| 	var _ca []interface{} | ||||
| 	_ca = append(_ca, ctx) | ||||
| 	_ca = append(_ca, _va...) | ||||
| 	ret := _m.Called(_ca...) | ||||
|  | ||||
| 	var r0 error | ||||
| 	if rf, ok := ret.Get(0).(func(context.Context, ...string) error); ok { | ||||
| 		r0 = rf(ctx, line...) | ||||
| 	} else { | ||||
| 		r0 = ret.Error(0) | ||||
| 	} | ||||
|  | ||||
| 	return r0 | ||||
| } | ||||
							
								
								
									
										73
									
								
								resources/metadata/influx.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								resources/metadata/influx.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | ||||
| metadata: | ||||
|   name: influxWriteData | ||||
|   description: Writes metrics to influxdb | ||||
|   longDescription: | | ||||
|     In this step, the metrics are written to the timeseries database [InfluxDB](https://www.influxdata.com/time-series-platform/influxdb/) | ||||
| spec: | ||||
|   inputs: | ||||
|     secrets: | ||||
|       - name: influxAuthTokenId | ||||
|         description: Influxdb token for authentication to the InfluxDB. In 1.8 version use 'username:password' instead. | ||||
|         type: jenkins | ||||
|     params: | ||||
|       - name: serverUrl | ||||
|         type: string | ||||
|         description: Base URL to the InfluxDB server | ||||
|         scope: | ||||
|           - PARAMETERS | ||||
|           - STAGES | ||||
|           - STEPS | ||||
|           - GENERAL | ||||
|         mandatory: true | ||||
|       - name: authToken | ||||
|         type: string | ||||
|         description: Token to authenticate to the Influxdb | ||||
|         scope: | ||||
|           - PARAMETERS | ||||
|           - STAGES | ||||
|           - STEPS | ||||
|         mandatory: true | ||||
|         secret: true | ||||
|         resourceRef: | ||||
|           - name: influxAuthTokenId | ||||
|             type: secret | ||||
|           - type: vaultSecret | ||||
|             paths: | ||||
|               - $(vaultPath)/influxdb | ||||
|               - $(vaultBasePath)/$(vaultPipelineName)/influxdb | ||||
|               - $(vaultBasePath)/GROUP-SECRETS/influxdb | ||||
|       - name: bucket | ||||
|         type: string | ||||
|         description: Name of database (1.8) or bucket (2.0) | ||||
|         scope: | ||||
|           - PARAMETERS | ||||
|           - STAGES | ||||
|           - STEPS | ||||
|         default: "piper" | ||||
|       - name: organization | ||||
|         type: string | ||||
|         description: Name of influx organization. Only for Influxdb 2.0 | ||||
|         scope: | ||||
|           - PARAMETERS | ||||
|           - STAGES | ||||
|           - STEPS | ||||
|       - name: dataMap | ||||
|         type: string | ||||
|         description: | ||||
|           "Map of fields for each measurements. It has to be a JSON string. | ||||
|           For example: {'series_1':{'field_a':11,'field_b':12},'series_2':{'field_c':21,'field_d':22}}" | ||||
|         scope: | ||||
|           - PARAMETERS | ||||
|           - STAGES | ||||
|           - STEPS | ||||
|         mandatory: true | ||||
|       - name: dataMapTags | ||||
|         type: string | ||||
|         description: | ||||
|           "Map of tags for each measurements. It has to be a JSON string. | ||||
|           For example: {'series_1':{'tag_a':'a','tag_b':'b'},'series_2':{'tag_c':'c','tag_d':'d'}}" | ||||
|         scope: | ||||
|           - PARAMETERS | ||||
|           - STAGES | ||||
|           - STEPS | ||||
|         mandatory: false | ||||
		Reference in New Issue
	
	Block a user