Rundeck job notification error (server response: 415 Unsupported Media Type) - webhooks

rundeck ver: 4.0.0
I want to send job execution result to specific webhook url.
So I set job notification use GUI
Trigger: On success
Notification Type: Send Webhook
URL(s): specific incoming webhook url
Payload Format: JSON
Method: POST
Rundeck job notification error is occured. (server response: 415 Unsupported Media Type)
Is there a configuration file that needs to be added other than the job notifications settings?

To send the job execution result you can use the HTTP notification plugin and put an export variable (containing the result) in the body section.
For this, you need to "capture" the output and store it on a global variable to put in the notification, I made a workable example that works with webhooks.site test service:
- defaultTab: nodes
description: ''
executionEnabled: true
id: bcee72e0-b6fa-4e8e-a065-9937a67f3de7
loglevel: INFO
name: HelloWorld
nodeFilterEditable: false
notification:
onsuccess:
plugin:
configuration:
authentication: None
body: ${export.myexport}
contentType: application/json
method: POST
remoteUrl: https://webhook.site/xxxx-xxxx-xxxx-xxxx-xxxx
timeout: '30000'
type: HttpNotification
notifyAvgDurationThreshold: null
options:
- name: opt1
value: localhost
plugins:
ExecutionLifecycle: null
scheduleEnabled: true
sequence:
commands:
- exec: nmap ${option.opt1}
plugins:
LogFilter:
- config:
hideOutput: 'false'
logData: 'true'
name: myoutput
regex: (.*)
type: key-value-data-multilines
- description: only for debug
exec: echo ${data.myoutput}
- configuration:
export: myexport
group: export
value: ${data.myoutput*}
nodeStep: false
type: export-var
keepgoing: false
strategy: node-first
uuid: bcee72e0-b6fa-4e8e-a065-9937a67f3de7
Run command and capture the output in a data capture filter, I use the Multiline Regex Data Capture plugin, now the output is saved on a data variable called ${data.myoutput}.
Then using the Global Variable Workflow Step, take the ${data.myoutput} (using the ${data.myoutput*} format) and create the ${export.myexport} variable to use in notifications (just putting the ${export.myexport} variable).
Check the result.

Related

How to get content-encoding from ApiGateway caching resource

We have an endpoint that returns a gzip encoding. We want to cache the value and we are using ApiGateway to do that for us. The resource method is defined as follows,
GetManifestApiGatewayMethod: # very good
Type: "AWS::ApiGateway::Method"
Properties:
AuthorizationType: "NONE"
HttpMethod: "GET"
ResourceId:
Ref: ManifestConfigurationResource
RestApiId:
Ref: ApiGatewayRestApi
RequestParameters:
method.request.path.seasonCode: true
method.request.path.facilityCode: true
method.request.path.configurationCode: true
method.request.querystring.policyCode: true
method.request.header.PAC-Authorization: true
method.request.header.PAC-Application-ID: true
method.request.header.PAC-API-Key: true
method.request.header.PAC-Channel-Code: true
method.request.header.PAC-Organization-ID: true
method.request.header.PAC-Developer-ID: true
method.request.header.PAC-Request-ID: false
method.request.header.Accept-Encoding: true
MethodResponses:
- StatusCode: 200
# ResponseParameters:
# method.response.header.Content-Encoding: true
Integration:
IntegrationHttpMethod: GET
Type: HTTP
Uri: https://${self:provider.environment.PDI_HOST}/pdi/v1/manifest/{seasonCode}/{facilityCode}/{configurationCode}
PassthroughBehavior: WHEN_NO_MATCH
CacheKeyParameters:
- method.request.path.seasonCode
- method.request.path.facilityCode
- method.request.path.configurationCode
- method.request.querystring.policyCode
IntegrationResponses:
- StatusCode: 200
SelectionPattern: '\d\d\d'
# ResponseParameters:
# method.response.header.content-encoding: integration.response.body.headers.content-encoding
RequestParameters:
integration.request.path.seasonCode: method.request.path.seasonCode
integration.request.path.facilityCode: method.request.path.facilityCode
integration.request.path.configurationCode: method.request.path.configurationCode
integration.request.querystring.policyCode: method.request.querystring.policyCode
integration.request.header.Authorization: method.request.header.PAC-Authorization
integration.request.header.PAC-Application-ID: method.request.header.PAC-Application-ID
integration.request.header.PAC-API-Key: method.request.header.PAC-API-Key
integration.request.header.PAC-Channel-Code: method.request.header.PAC-Channel-Code
integration.request.header.PAC-Organization-ID: method.request.header.PAC-Organization-ID
integration.request.header.PAC-Developer-ID: method.request.header.PAC-Developer-ID
integration.request.header.PAC-Request-ID: method.request.header.PAC-Request-ID
integration.request.header.Accept-Encoding: method.request.header.Accept-Encoding
http.get method has the following logic in it:
const encoding = response.headers["content-encoding"];
if (encoding && encoding.indexOf("gzip") >= 0) {...} // handle the gzip
but when we use the integration method above, I am not getting that header that I would normally get from directly hitting the api it proxies to. There is some commented code where I tried to pass that along but Im getting internal server error when those response mappings are used.
From the looks of your code template, the Method response header looks correct.
method.response.header.Content-Encoding: true
However your integration response, ResponseParameters is seems wrong.
method.response.header.content-encoding: integration.response.body.headers.content-encoding
Firstly, the property Key should exactly match, so potentially the capitalisation may be adding to the issue. However, your Value looks to be the real issue. As per the AWS Documentation:
Use the destination as the key and the source as the value:
The destination must be an existing response parameter in the
MethodResponse property.
The source must be an existing method request parameter or a static
value. You must enclose static values in single quotation marks and
pre-encode these values based on the destination specified in the
request.
It looks as if you're trying to map a integration response method to the value instead of a Method Request parameter.

Karate - When i run a basic feature with get call, i get karate exception as INSTANCE on the line where get is called [duplicate]

I'm trying use karate for e2e tests and have started with a minimal setup. I want to create some config items in karate-config.js for use in the tests but karate is reporting that file is not a js function and hence the test fails trying to get the config:
Warning: Nashorn engine is planned to be removed from a future JDK release
12:16:35.264 [Test worker] WARN com.intuit.karate - not a js function or feature file: read('classpath:karate-config.js') - [type: NULL, value: null]
---------------------------------------------------------
feature: classpath:karate/insurer.feature
scenarios: 1 | passed: 0 | failed: 1 | time: 0.0163
---------------------------------------------------------
HTML report: (paste into browser to view) | Karate version: 0.9.1
file:/Users/srowatt/dev/repos/api/price-service/build/surefire-reports/karate.insurer.html
---------------------------------------------------------
-unknown-:4 - javascript evaluation failed: priceBaseUrl, ReferenceError: "priceBaseUrl" is not defined in <eval> at line number 1
org.opentest4j.AssertionFailedError: -unknown-:4 - javascript evaluation failed: priceBaseUrl, ReferenceError: "priceBaseUrl" is not defined in <eval> at line number 1
This is my karate-config.js:
function fn() {
return {
priceBaseUrl: "http://localhost:8080"
};
}
This is my insurer.feature test:
Feature: which creates insurers
Background:
* url priceBaseUrl
* configure logPrettyRequest = true
* configure logPrettyResponse = true
Scenario: basic roundtrip
# create a new insurer
Given path 'insurers'
And request { name: 'Sammy Insurance', companyCode: '99' }
When method post
Then status 201
And match response == { resourceId: '#number', version: 0, createdBy: 'anonymousUser' }
* def insurerId = response.resourceId
# get insurer by resource id
Given path 'insurers', insurerId
When method get
Then status 200
And match response == { id: '#(id)', name: 'Sammy Insurance', companyCode: '99' }
This is the InsurerTest.java test runner:
package karate;
import com.intuit.karate.junit5.Karate;
class InsurerTest {
#Karate.Test
public Karate testInsurer() {
return new Karate().feature("classpath:karate/insurer.feature");
}
}
Please use below code in the karate-config.js
function() {
return priceBaseUrl='http://localhost:8080';
}
When I see this:
Warning: Nashorn engine is planned to be removed from a future JDK release
I suspect you are on Java 9 or 11 ? To be honest, we haven't fully tested Karate on those versions of Java yet. Would it be possible for you to confirm that Java 8 (maybe 9 / 10 also) is OK.
That said, we are interested in resolving this as soon as possible, so if you can submit a sample project where we can replicate this, please do so: https://github.com/intuit/karate/wiki/How-to-Submit-an-Issue
EDIT: Karate 1.0 will use GraalVM instead of Nashorn and will run on even JDK 16: https://software-that-matters.com/2021/01/27/7-new-features-in-karate-test-automation-version-1_0/

Iterate over a Puppet Hiera hash in a puppet manifest

Update 1
I've changed the structure of the Hiera data a little and trying a different manifest style.
I'm trying to iterate over the following Hiera hash in a Puppet manifest:
windows-10.yaml:
---
message: "This node is using Windows 10 data"
#profile::hiera_test::backups_enabled: false
profile::hiera_test::firewall:
rule1:
groupName: 'Cortana'
profileNames: ['Private','Public']
action: 'Deny'
rule2:
groupName: 'Microsoft Photos'
profileNames: 'Public'
action: 'Deny'
Although I've updated the data structure and puppet lookup... returns what appears to be valid, I'm not entirely confident in the structure.
I have tried multiple permutations of the manifest. The latest of which looks like the following (based on this answer given by Matt Schuchard):
hiera_test.pp:
class profile::hiera_test (
Hash $data = lookup('profile::hiera_test::firewall', "merge" => 'hash'),
){
$data.each | String $key, Hash $value = {}|{
notify {
default:
name => "Demo_${key}",
message => 'Item DEFAULT',
;
$key:
* => $value,
}
}
}
And the error / output from the above:
PS C:\Users\LocalAdmin> puppet agent -t
Notice: Local environment: 'production' doesn't match server specified node environment 'development', switching agent to 'development'.
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Retrieving locales
Info: Loading facts
Error: Could not retrieve catalog from remote server: Error 500 on SERVER: Server Error: no parameter named 'groupName' (file: /etc/puppetlabs/code/environments/development/site-modules/profile/manifests/hiera_test.pp, line: 31) on Notify[rule1] (file: /etc/puppetlabs/code/environments/development/site-modules/profile/manifests/hiera_test.pp, line: 31) on node winnode1.domain.com
Warning: Not using cache on failed catalog
Error: Could not retrieve catalog; skipping run
Ideally, I want it to work inside a class declaration (why?, because that's about as far as my Puppet learning has got, but happy to further my learning. I'm also using Puppet Enterprise (2019.0.2)).
There are several similar questions around the internet, but they are either out of date (Hiera <5), have incomplete examples including this, or I can't work out how to transpose them into what I need. Apparently create_resources is due for depreciation
?
If anyone can tell me where I'm going wrong that would be great.
I have got a working solution, but hopefully someone can chime in with a better way.
With the example in the question, the line * => $value substitutes * with keys from the Hiera hash. These keys are used as parameters of the notify resource and as per the error, there is no such parameter groupName for notify. I'd either have to change the keys in my Hiera data to match the parameters of notify which wouldn't make much sense or learn how to use the Hiera data keys as parameters...
Anyway, the Hiera data is the same as in the question, but the class is as follows:
class profile::hiera_test (
Hash $data = lookup('profile::hiera_test::firewall', "merge" => 'hash'),
){
$data.each | String $key, Hash $value = {}|{
notify {
default:
name => "Demo_${key}",
message => 'Item DEFAULT',
;
$key:
name => "Demo_${key}",
message => "Output: GroupName: ${value['groupName']}, Profile Names: ${value['profileNames']}, Action: ${value['action']}",
}
}
}
As you can see, I've replaced * with valid parameters of the notify resource.
And the output:
Notice: Output: GroupName: Cortana, Profile Names: [Private, Public], Action: Deny
Notice: Output: GroupName: Microsoft Photos, Profile Names: Public, Action: Deny
Now to replace Notify with the real exec resource. Converting the profileNames array to PowerShell will be fun, I have no doubt.

Serverless: Your serverless.yml has an invalid value with key: "Ref"

While installing serverless with following command
sls plugin install -n serverless-alexa-skills --stage dev
I am getting an error like Your serverless.yml has an invalid value with key: "Ref"
The following is my sample serverless.yml file
plugins:
- serverless-webpack
- serverless-s3-sync
- serverless-plugin-git-variables
- serverless-alexa-skills
functions: ${file(./deploy/${opt:stage}.yml):functions}
resources: ${file(./deploy/${opt:stage}.yml):resources}
custom: ${file(./deploy/${opt:stage}.yml):custom}
outputs:
DialogflowFunctionArn:
Value:
Ref:
Got a block here. can some one help me here.
Ref is a Cloudformation intrinsic function. It needs to reference a resource. The whole outputs section is also optional, use it only if you need to reference the resources from one stack in another.
It basically says that Ref: is expecting a value. You have defined it but not assigned any value to it. If there is no use then you should remove this part from your code:
outputs:
DialogflowFunctionArn:
Value:
Ref:
Ref expects to reference something, right now you are not passing it anything to reference.
So, assuming you want the ARN of DialogflowFunction and that function config looks something like this in your functions file:
DialogflowFunction:
description: get the flow
handler: src/functions/dialog-controller.flow
events:
- http:
path: '/dialog/flow'
method: get
cors: true
Then your ref would look something like this:
outputs:
DialogflowFunctionArn:
Value:
Ref: DialogflowFunction
Ref takes the logical id of the resource for which you want to reference, in this case that is DialogflowFunction, and will return the ARN of that resource.

What is the difference between command and option in [yargs]

I am using yargs for getting CLI arguments. I want to know the difference between command and option.
const argv = yargs
.command(
'add',
'Add a new note',
{
title: titleOptions,
body: bodyOptions
})
.argv;
And
const argv = yargs
.option('address', {
alias: 'a',
demand: true,
describe: 'Address for fetching weather'
})
.help()
.alias('help', 'h')
.argv
One difference is semantics: commands perform actions, options alter the way the actions are to be performed. Another important difference is that options can be assigned values. For example:
git commit --message "Initial commit"
In the example above, commit is the command, and message is the option. The message option has a value of "Initial commit". You can also have options without values, which are referred to as "flags".
git fetch --no-tags
Here we're using the no-tags flag to tell Git to fetch everything from the upstream branch but exclude tags.

Resources