mirror of
https://github.com/SAP/jenkins-library.git
synced 2025-01-04 04:07:16 +02:00
[ANS] Step implementation (#3764)
* Add ans implementation * Remove todo comment * Rename test function Co-authored-by: Linda Siebert <39100394+LindaSieb@users.noreply.github.com> * Better wording Co-authored-by: Linda Siebert <39100394+LindaSieb@users.noreply.github.com> * Add reading of response body function * Use http pkg ReadResponseBody * Check read error * Better test case description * Fix formatting * Create own package for read response body * Omit empty nested resource struct * Separate Resource struct from Event struct * Merge and unmarshall instead of only unmarshalling * Improve status code error message * Remove unchangeable event fields * Separate event parts * Change log level setter function * Restructure ans send test * Revert exporting readResponseBody function Instead the code is duplicated in the xsuaa and ans package * Add check correct ans setup request * Add set options function for mocking * Review fixes * Correct function name * Use strict unmarshalling * Validate event * Move functions * Add documentation comments * improve test * Validate event * Add logrus hook for ans * Set defaults on new hook creation * Fix log level on error * Don't alter entry log level * Set severity fatal on 'fatal error' log message * Ensure that log entries don't affect each other * Remove unnecessary correlationID * Use file path instead of event template string * Improve warning messages * Add empty log message check * Allow configuration from file and string * Add sourceEventId to tags * Change resourceType to Pipeline * Use structured config approach * Use new log level set function * Check correct setup and return error * Mock http requests * Only send log level warning or higher * Use new function name * One-liner ifs * Improve test name * Fix tests * Prevent double firing * Reduce Fire test size * Add error message to test * Reduce newANSHook test size * Further check error * Rename to defaultEvent in hook struct * Reduce ifs further * Fix set error category test The ansHook Fire test cannot run in parallel, as it would affect the other tests that use the error category. * Change function name to SetServiceKey * Validate event * Rename to eventTemplate in hook struct * Move copy to event.go * Fix function mix * Remove unnecessary cleanup * Remove parallel test The translation fails now and again when parallel is on. * Remove prefix test * Remove unused copyEvent function * Fix ifs * Add docu comment * Register ans hook from pkg * register hook and setup event template seperately * Exclusively read eventTemplate from environment * setupEventTemplate tests * adjust hook levels test * sync tests- wlill still fail * migrate TestANSHook_registerANSHook test * fixes * Add ans send event step * Fix tests * Add groovy wrapper * Add groovy wrapper test * Fix function names * Reduce ifs * Fix docu * We always set the timestamp * Validate event * Test unknown field in json * Make test list test * Set all event fields as separate parameters * Generate and fix code * Review fixes * Format test file * Format go code * Fix common steps tests * Print event to console if verbose Co-authored-by: Linda Siebert <39100394+LindaSieb@users.noreply.github.com> Co-authored-by: Roland Stengel <r.stengel@sap.com>
This commit is contained in:
parent
cdea4b7713
commit
810d197665
57
cmd/ansSendEvent.go
Normal file
57
cmd/ansSendEvent.go
Normal file
@ -0,0 +1,57 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/SAP/jenkins-library/pkg/ans"
|
||||
"github.com/SAP/jenkins-library/pkg/log"
|
||||
"github.com/SAP/jenkins-library/pkg/telemetry"
|
||||
"time"
|
||||
)
|
||||
|
||||
func ansSendEvent(config ansSendEventOptions, telemetryData *telemetry.CustomData) {
|
||||
err := runAnsSendEvent(&config, &ans.ANS{})
|
||||
if err != nil {
|
||||
log.Entry().WithError(err).Fatal("step execution failed")
|
||||
}
|
||||
}
|
||||
|
||||
func runAnsSendEvent(config *ansSendEventOptions, c ans.Client) error {
|
||||
ansServiceKey, err := ans.UnmarshallServiceKeyJSON(config.AnsServiceKey)
|
||||
if err != nil {
|
||||
log.SetErrorCategory(log.ErrorConfiguration)
|
||||
return err
|
||||
}
|
||||
c.SetServiceKey(ansServiceKey)
|
||||
|
||||
event := ans.Event{
|
||||
EventType: config.EventType,
|
||||
Severity: config.Severity,
|
||||
Category: config.Category,
|
||||
Subject: config.Subject,
|
||||
Body: config.Body,
|
||||
Priority: config.Priority,
|
||||
Tags: config.Tags,
|
||||
Resource: &ans.Resource{
|
||||
ResourceName: config.ResourceName,
|
||||
ResourceType: config.ResourceType,
|
||||
ResourceInstance: config.ResourceInstance,
|
||||
Tags: config.ResourceTags,
|
||||
},
|
||||
}
|
||||
|
||||
if GeneralConfig.Verbose {
|
||||
eventJson, _ := json.MarshalIndent(event, "", " ")
|
||||
log.Entry().Infof("Event details: %s", eventJson)
|
||||
}
|
||||
|
||||
if err = event.Validate(); err != nil {
|
||||
log.SetErrorCategory(log.ErrorConfiguration)
|
||||
return err
|
||||
}
|
||||
// We set the time
|
||||
event.EventTimestamp = time.Now().Unix()
|
||||
if err = c.Send(event); err != nil {
|
||||
log.SetErrorCategory(log.ErrorService)
|
||||
}
|
||||
return err
|
||||
}
|
269
cmd/ansSendEvent_generated.go
Normal file
269
cmd/ansSendEvent_generated.go
Normal file
@ -0,0 +1,269 @@
|
||||
// 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/SAP/jenkins-library/pkg/validation"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type ansSendEventOptions struct {
|
||||
AnsServiceKey string `json:"ansServiceKey,omitempty"`
|
||||
EventType string `json:"eventType,omitempty"`
|
||||
Severity string `json:"severity,omitempty" validate:"possible-values=INFO NOTICE WARNING ERROR FATAL"`
|
||||
Category string `json:"category,omitempty" validate:"possible-values=NOTIFICATION ALERT EXCEPTION"`
|
||||
Subject string `json:"subject,omitempty"`
|
||||
Body string `json:"body,omitempty"`
|
||||
Priority int `json:"priority,omitempty"`
|
||||
Tags map[string]interface{} `json:"tags,omitempty"`
|
||||
ResourceName string `json:"resourceName,omitempty"`
|
||||
ResourceType string `json:"resourceType,omitempty"`
|
||||
ResourceInstance string `json:"resourceInstance,omitempty"`
|
||||
ResourceTags map[string]interface{} `json:"resourceTags,omitempty"`
|
||||
}
|
||||
|
||||
// AnsSendEventCommand Send Event to the SAP Alert Notification Service
|
||||
func AnsSendEventCommand() *cobra.Command {
|
||||
const STEP_NAME = "ansSendEvent"
|
||||
|
||||
metadata := ansSendEventMetadata()
|
||||
var stepConfig ansSendEventOptions
|
||||
var startTime time.Time
|
||||
var logCollector *log.CollectorHook
|
||||
var splunkClient *splunk.Splunk
|
||||
telemetryClient := &telemetry.Telemetry{}
|
||||
|
||||
var createAnsSendEventCmd = &cobra.Command{
|
||||
Use: STEP_NAME,
|
||||
Short: "Send Event to the SAP Alert Notification Service",
|
||||
Long: `With this step one can send an Event to the SAP Alert Notification Service.`,
|
||||
PreRunE: func(cmd *cobra.Command, _ []string) error {
|
||||
startTime = time.Now()
|
||||
log.SetStepName(STEP_NAME)
|
||||
log.SetVerbose(GeneralConfig.Verbose)
|
||||
|
||||
GeneralConfig.GitHubAccessTokens = ResolveAccessTokens(GeneralConfig.GitHubTokens)
|
||||
|
||||
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.AnsServiceKey)
|
||||
|
||||
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 {
|
||||
splunkClient = &splunk.Splunk{}
|
||||
logCollector = &log.CollectorHook{CorrelationID: GeneralConfig.CorrelationID}
|
||||
log.RegisterHook(logCollector)
|
||||
}
|
||||
|
||||
validation, err := validation.New(validation.WithJSONNamesForStructFields(), validation.WithPredefinedErrorMessages())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = validation.ValidateStruct(stepConfig); err != nil {
|
||||
log.SetErrorCategory(log.ErrorConfiguration)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
Run: func(_ *cobra.Command, _ []string) {
|
||||
stepTelemetryData := telemetry.CustomData{}
|
||||
stepTelemetryData.ErrorCode = "1"
|
||||
handler := func() {
|
||||
config.RemoveVaultSecretFiles()
|
||||
stepTelemetryData.Duration = fmt.Sprintf("%v", time.Since(startTime).Milliseconds())
|
||||
stepTelemetryData.ErrorCategory = log.GetErrorCategory().String()
|
||||
stepTelemetryData.PiperCommitHash = GitCommit
|
||||
telemetryClient.SetData(&stepTelemetryData)
|
||||
telemetryClient.Send()
|
||||
if len(GeneralConfig.HookConfig.SplunkConfig.Dsn) > 0 {
|
||||
splunkClient.Send(telemetryClient.GetData(), logCollector)
|
||||
}
|
||||
}
|
||||
log.DeferExitHandler(handler)
|
||||
defer handler()
|
||||
telemetryClient.Initialize(GeneralConfig.NoTelemetry, STEP_NAME)
|
||||
if len(GeneralConfig.HookConfig.SplunkConfig.Dsn) > 0 {
|
||||
splunkClient.Initialize(GeneralConfig.CorrelationID,
|
||||
GeneralConfig.HookConfig.SplunkConfig.Dsn,
|
||||
GeneralConfig.HookConfig.SplunkConfig.Token,
|
||||
GeneralConfig.HookConfig.SplunkConfig.Index,
|
||||
GeneralConfig.HookConfig.SplunkConfig.SendLogs)
|
||||
}
|
||||
ansSendEvent(stepConfig, &stepTelemetryData)
|
||||
stepTelemetryData.ErrorCode = "0"
|
||||
log.Entry().Info("SUCCESS")
|
||||
},
|
||||
}
|
||||
|
||||
addAnsSendEventFlags(createAnsSendEventCmd, &stepConfig)
|
||||
return createAnsSendEventCmd
|
||||
}
|
||||
|
||||
func addAnsSendEventFlags(cmd *cobra.Command, stepConfig *ansSendEventOptions) {
|
||||
cmd.Flags().StringVar(&stepConfig.AnsServiceKey, "ansServiceKey", os.Getenv("PIPER_ansServiceKey"), "Service key JSON string to access the SAP Alert Notification Service")
|
||||
cmd.Flags().StringVar(&stepConfig.EventType, "eventType", `Piper`, "Type of the event")
|
||||
cmd.Flags().StringVar(&stepConfig.Severity, "severity", `INFO`, "Event severity")
|
||||
cmd.Flags().StringVar(&stepConfig.Category, "category", `NOTIFICATION`, "Event category")
|
||||
cmd.Flags().StringVar(&stepConfig.Subject, "subject", `ansSendEvent`, "Short description of the event")
|
||||
cmd.Flags().StringVar(&stepConfig.Body, "body", `Call from Piper step ansSendEvent`, "Detailed description of the event")
|
||||
cmd.Flags().IntVar(&stepConfig.Priority, "priority", 0, "Event priority in the range of 1 to 1000")
|
||||
|
||||
cmd.Flags().StringVar(&stepConfig.ResourceName, "resourceName", `Pipeline`, "Unique resource name")
|
||||
cmd.Flags().StringVar(&stepConfig.ResourceType, "resourceType", `Pipeline`, "Resource type identifier")
|
||||
cmd.Flags().StringVar(&stepConfig.ResourceInstance, "resourceInstance", os.Getenv("PIPER_resourceInstance"), "Optional resource instance identifier")
|
||||
|
||||
cmd.MarkFlagRequired("ansServiceKey")
|
||||
}
|
||||
|
||||
// retrieve step metadata
|
||||
func ansSendEventMetadata() config.StepData {
|
||||
var theMetaData = config.StepData{
|
||||
Metadata: config.StepMetadata{
|
||||
Name: "ansSendEvent",
|
||||
Aliases: []config.Alias{},
|
||||
Description: "Send Event to the SAP Alert Notification Service",
|
||||
},
|
||||
Spec: config.StepSpec{
|
||||
Inputs: config.StepInputs{
|
||||
Secrets: []config.StepSecrets{
|
||||
{Name: "ansServiceKeyCredentialsId", Description: "Jenkins secret text credential ID containing the service key to access the SAP Alert Notification Service", Type: "jenkins"},
|
||||
},
|
||||
Parameters: []config.StepParameters{
|
||||
{
|
||||
Name: "ansServiceKey",
|
||||
ResourceRef: []config.ResourceReference{
|
||||
{
|
||||
Name: "ansServiceKeyCredentialsId",
|
||||
Param: "ansServiceKey",
|
||||
Type: "secret",
|
||||
},
|
||||
},
|
||||
Scope: []string{"PARAMETERS"},
|
||||
Type: "string",
|
||||
Mandatory: true,
|
||||
Aliases: []config.Alias{},
|
||||
Default: os.Getenv("PIPER_ansServiceKey"),
|
||||
},
|
||||
{
|
||||
Name: "eventType",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||
Type: "string",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{},
|
||||
Default: `Piper`,
|
||||
},
|
||||
{
|
||||
Name: "severity",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||
Type: "string",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{},
|
||||
Default: `INFO`,
|
||||
},
|
||||
{
|
||||
Name: "category",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||
Type: "string",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{},
|
||||
Default: `NOTIFICATION`,
|
||||
},
|
||||
{
|
||||
Name: "subject",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||
Type: "string",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{},
|
||||
Default: `ansSendEvent`,
|
||||
},
|
||||
{
|
||||
Name: "body",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||
Type: "string",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{},
|
||||
Default: `Call from Piper step ansSendEvent`,
|
||||
},
|
||||
{
|
||||
Name: "priority",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||
Type: "int",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{},
|
||||
Default: 0,
|
||||
},
|
||||
{
|
||||
Name: "tags",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||
Type: "map[string]interface{}",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{},
|
||||
},
|
||||
{
|
||||
Name: "resourceName",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||
Type: "string",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{},
|
||||
Default: `Pipeline`,
|
||||
},
|
||||
{
|
||||
Name: "resourceType",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||
Type: "string",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{},
|
||||
Default: `Pipeline`,
|
||||
},
|
||||
{
|
||||
Name: "resourceInstance",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||
Type: "string",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{},
|
||||
Default: os.Getenv("PIPER_resourceInstance"),
|
||||
},
|
||||
{
|
||||
Name: "resourceTags",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||
Type: "map[string]interface{}",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
return theMetaData
|
||||
}
|
17
cmd/ansSendEvent_generated_test.go
Normal file
17
cmd/ansSendEvent_generated_test.go
Normal file
@ -0,0 +1,17 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestAnsSendEventCommand(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCmd := AnsSendEventCommand()
|
||||
|
||||
// only high level testing performed - details are tested in step generation procedure
|
||||
assert.Equal(t, "ansSendEvent", testCmd.Use, "command name incorrect")
|
||||
|
||||
}
|
129
cmd/ansSendEvent_test.go
Normal file
129
cmd/ansSendEvent_test.go
Normal file
@ -0,0 +1,129 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/SAP/jenkins-library/pkg/ans"
|
||||
"github.com/SAP/jenkins-library/pkg/xsuaa"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const testTimestamp = 1651585103
|
||||
|
||||
func TestRunAnsSendEvent(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
config ansSendEventOptions
|
||||
ansMock ansMock
|
||||
wantErrMsg string
|
||||
}{
|
||||
{
|
||||
name: "overwriting EventType",
|
||||
config: defaultEventOptions(),
|
||||
},
|
||||
{
|
||||
name: "bad service key",
|
||||
config: ansSendEventOptions{AnsServiceKey: `{"forgot": "closing", "bracket": "json"`},
|
||||
wantErrMsg: `error unmarshalling ANS serviceKey: unexpected end of JSON input`,
|
||||
},
|
||||
{
|
||||
name: "invalid event json",
|
||||
config: ansSendEventOptions{AnsServiceKey: goodServiceKey, Severity: "WRONG_SEVERITY"},
|
||||
wantErrMsg: `Severity must be one of [INFO NOTICE WARNING ERROR FATAL]: event JSON failed the validation`,
|
||||
},
|
||||
{
|
||||
name: "fail to send",
|
||||
config: defaultEventOptions(),
|
||||
ansMock: ansMock{failToSend: true},
|
||||
wantErrMsg: `failed to send`,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if err := runAnsSendEvent(&tt.config, &tt.ansMock); tt.wantErrMsg != "" {
|
||||
assert.EqualError(t, err, tt.wantErrMsg)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "https://my.test.backend", tt.ansMock.testANS.URL)
|
||||
assert.Equal(t, defaultXsuaa(), tt.ansMock.testANS.XSUAA)
|
||||
assert.Equal(t, defaultEvent(), tt.ansMock.testEvent)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func defaultEventOptions() ansSendEventOptions {
|
||||
return ansSendEventOptions{
|
||||
AnsServiceKey: goodServiceKey,
|
||||
EventType: "myEvent",
|
||||
Severity: "INFO",
|
||||
Category: "NOTIFICATION",
|
||||
Subject: "testStep",
|
||||
Body: "Call from Piper step: testStep",
|
||||
Priority: 123,
|
||||
Tags: map[string]interface{}{"myNumber": 456},
|
||||
ResourceName: "myResourceName",
|
||||
ResourceType: "myResourceType",
|
||||
ResourceInstance: "myResourceInstance",
|
||||
ResourceTags: map[string]interface{}{"myBoolean": true},
|
||||
}
|
||||
}
|
||||
|
||||
func defaultEvent() ans.Event {
|
||||
return ans.Event{
|
||||
EventType: "myEvent",
|
||||
EventTimestamp: testTimestamp,
|
||||
Severity: "INFO",
|
||||
Category: "NOTIFICATION",
|
||||
Subject: "testStep",
|
||||
Body: "Call from Piper step: testStep",
|
||||
Priority: 123,
|
||||
Tags: map[string]interface{}{"myNumber": 456},
|
||||
Resource: &ans.Resource{
|
||||
ResourceName: "myResourceName",
|
||||
ResourceType: "myResourceType",
|
||||
ResourceInstance: "myResourceInstance",
|
||||
Tags: map[string]interface{}{"myBoolean": true},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func defaultXsuaa() xsuaa.XSUAA {
|
||||
return xsuaa.XSUAA{
|
||||
OAuthURL: "https://my.test.oauth.provider",
|
||||
ClientID: "myTestClientID",
|
||||
ClientSecret: "super secret",
|
||||
}
|
||||
}
|
||||
|
||||
const goodServiceKey = `{
|
||||
"url": "https://my.test.backend",
|
||||
"client_id": "myTestClientID",
|
||||
"client_secret": "super secret",
|
||||
"oauth_url": "https://my.test.oauth.provider"
|
||||
}`
|
||||
|
||||
type ansMock struct {
|
||||
testANS ans.ANS
|
||||
testEvent ans.Event
|
||||
failToSend bool
|
||||
}
|
||||
|
||||
func (am *ansMock) Send(event ans.Event) error {
|
||||
if am.failToSend {
|
||||
return fmt.Errorf("failed to send")
|
||||
}
|
||||
event.EventTimestamp = testTimestamp
|
||||
am.testEvent = event
|
||||
return nil
|
||||
}
|
||||
|
||||
func (am ansMock) CheckCorrectSetup() error {
|
||||
return fmt.Errorf("not implemented")
|
||||
}
|
||||
|
||||
func (am *ansMock) SetServiceKey(serviceKey ans.ServiceKey) {
|
||||
am.testANS.SetServiceKey(serviceKey)
|
||||
}
|
@ -25,6 +25,7 @@ func GetAllStepMetadata() map[string]config.StepData {
|
||||
"abapEnvironmentPushATCSystemConfig": abapEnvironmentPushATCSystemConfigMetadata(),
|
||||
"abapEnvironmentRunATCCheck": abapEnvironmentRunATCCheckMetadata(),
|
||||
"abapEnvironmentRunAUnitTest": abapEnvironmentRunAUnitTestMetadata(),
|
||||
"ansSendEvent": ansSendEventMetadata(),
|
||||
"apiKeyValueMapDownload": apiKeyValueMapDownloadMetadata(),
|
||||
"apiKeyValueMapUpload": apiKeyValueMapUploadMetadata(),
|
||||
"apiProviderDownload": apiProviderDownloadMetadata(),
|
||||
|
@ -188,6 +188,7 @@ func Execute() {
|
||||
rootCmd.AddCommand(AzureBlobUploadCommand())
|
||||
rootCmd.AddCommand(AwsS3UploadCommand())
|
||||
rootCmd.AddCommand(ApiProxyListCommand())
|
||||
rootCmd.AddCommand(AnsSendEventCommand())
|
||||
|
||||
addRootFlags(rootCmd)
|
||||
|
||||
|
118
resources/metadata/ansSendEvent.yaml
Normal file
118
resources/metadata/ansSendEvent.yaml
Normal file
@ -0,0 +1,118 @@
|
||||
metadata:
|
||||
name: ansSendEvent
|
||||
description: Send Event to the SAP Alert Notification Service
|
||||
longDescription: |
|
||||
With this step one can send an Event to the SAP Alert Notification Service.
|
||||
|
||||
spec:
|
||||
inputs:
|
||||
secrets:
|
||||
- name: ansServiceKeyCredentialsId
|
||||
description: Jenkins secret text credential ID containing the service key to access the SAP Alert Notification Service
|
||||
type: jenkins
|
||||
params:
|
||||
- name: ansServiceKey
|
||||
type: string
|
||||
description: Service key JSON string to access the SAP Alert Notification Service
|
||||
scope:
|
||||
- PARAMETERS
|
||||
mandatory: true
|
||||
secret: true
|
||||
resourceRef:
|
||||
- name: ansServiceKeyCredentialsId
|
||||
type: secret
|
||||
param: ansServiceKey
|
||||
- name: eventType
|
||||
type: string
|
||||
description: Type of the event
|
||||
default: "Piper"
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
- name: severity
|
||||
type: string
|
||||
description: Event severity
|
||||
default: "INFO"
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
possibleValues:
|
||||
- INFO
|
||||
- NOTICE
|
||||
- WARNING
|
||||
- ERROR
|
||||
- FATAL
|
||||
- name: category
|
||||
type: string
|
||||
description: Event category
|
||||
default: "NOTIFICATION"
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
possibleValues:
|
||||
- NOTIFICATION
|
||||
- ALERT
|
||||
- EXCEPTION
|
||||
- name: subject
|
||||
type: string
|
||||
description: Short description of the event
|
||||
default: "ansSendEvent"
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
- name: body
|
||||
type: string
|
||||
description: Detailed description of the event
|
||||
default: "Call from Piper step ansSendEvent"
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
- name: priority
|
||||
type: int
|
||||
description: Event priority in the range of 1 to 1000
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
- name: tags
|
||||
type: "map[string]interface{}"
|
||||
description: Optional key-value pairs describing the event in details
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
- name: resourceName
|
||||
type: string
|
||||
description: Unique resource name
|
||||
default: "Pipeline"
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
- name: resourceType
|
||||
type: string
|
||||
description: Resource type identifier
|
||||
default: "Pipeline"
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
- name: resourceInstance
|
||||
type: string
|
||||
description: Optional resource instance identifier
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
- name: resourceTags
|
||||
type: "map[string]interface{}"
|
||||
description: Optional key-value pairs describing the resource in details
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
56
test/groovy/AnsSendEventTest.groovy
Normal file
56
test/groovy/AnsSendEventTest.groovy
Normal file
@ -0,0 +1,56 @@
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.RuleChain
|
||||
import util.BasePiperTest
|
||||
import util.JenkinsReadYamlRule
|
||||
import util.JenkinsStepRule
|
||||
import util.Rules
|
||||
|
||||
import static org.hamcrest.Matchers.allOf
|
||||
import static org.hamcrest.Matchers.hasEntry
|
||||
import static org.hamcrest.Matchers.is
|
||||
import static org.junit.Assert.assertThat
|
||||
|
||||
public class AnsSendEventTest extends BasePiperTest {
|
||||
|
||||
private JenkinsStepRule stepRule = new JenkinsStepRule(this)
|
||||
private JenkinsReadYamlRule readYamlRule = new JenkinsReadYamlRule(this)
|
||||
|
||||
@Rule
|
||||
public RuleChain ruleChain = Rules
|
||||
.getCommonRules(this)
|
||||
.around(stepRule)
|
||||
.around(readYamlRule)
|
||||
|
||||
@Test
|
||||
void testCallGoWrapper() {
|
||||
|
||||
def calledWithParameters,
|
||||
calledWithStepName,
|
||||
calledWithMetadata
|
||||
List calledWithCredentials
|
||||
|
||||
helper.registerAllowedMethod(
|
||||
'piperExecuteBin',
|
||||
[Map, String, String, List],
|
||||
{
|
||||
params, stepName, metaData, creds ->
|
||||
calledWithParameters = params
|
||||
calledWithStepName = stepName
|
||||
calledWithMetadata = metaData
|
||||
calledWithCredentials = creds
|
||||
}
|
||||
)
|
||||
|
||||
stepRule.step.ansSendEvent(script: nullScript, abc: 'ABC')
|
||||
|
||||
assertThat(calledWithParameters.size(), is(2))
|
||||
assertThat(calledWithParameters.script, is(nullScript))
|
||||
assertThat(calledWithParameters.abc, is('ABC'))
|
||||
|
||||
assertThat(calledWithStepName, is('ansSendEvent'))
|
||||
assertThat(calledWithMetadata, is('metadata/ansSendEvent.yaml'))
|
||||
assertThat(calledWithCredentials[0].size(), is(3))
|
||||
assertThat(calledWithCredentials[0], allOf(hasEntry('type', 'token'), hasEntry('id', 'ansServiceKeyCredentialsId'), hasEntry('env', ['PIPER_ansServiceKey'])))
|
||||
}
|
||||
}
|
@ -220,7 +220,8 @@ public class CommonStepsTest extends BasePiperTest{
|
||||
'awsS3Upload',
|
||||
'apiProxyList', //implementing new golang pattern without fields
|
||||
'azureBlobUpload',
|
||||
'awsS3Upload'
|
||||
'awsS3Upload',
|
||||
'ansSendEvent'
|
||||
]
|
||||
|
||||
@Test
|
||||
|
11
vars/ansSendEvent.groovy
Normal file
11
vars/ansSendEvent.groovy
Normal file
@ -0,0 +1,11 @@
|
||||
import groovy.transform.Field
|
||||
|
||||
@Field String STEP_NAME = getClass().getName()
|
||||
@Field String METADATA_FILE = 'metadata/ansSendEvent.yaml'
|
||||
|
||||
void call(Map parameters = [:]) {
|
||||
List credentials = [
|
||||
[type: 'token', id: 'ansServiceKeyCredentialsId', env: ['PIPER_ansServiceKey']]
|
||||
]
|
||||
piperExecuteBin(parameters, STEP_NAME, METADATA_FILE, credentials)
|
||||
}
|
Loading…
Reference in New Issue
Block a user