How to use choice parameter integer value as array in Jenkins Declarative pipeline file - for-loop

I have a Jenkins choice parameter which is integer value. I need to loop through the parameter value in my Jenkins File to run a function [i] times.
Say for Ex: Choice Parameter has ['1','2','3','4'] in drop down. If I chooses 4, the loop should go through 4 times.
But my below code only displays I choose in the parameter which is '4' while echoing it. Could someone help me in loop through.
script {
def loop_value = "${params.choiceparameter}"
loop_value.each() {
echo it
}
}

Use it like this:
pipeline {
agent any
parameters {
choice choices: ['1', '2', '3', '4', '5'], description: '', name: 'choiceParameter'
}
stages {
stage("stage1") {
steps {
script {
for (i = 0; i < params.choiceParameter.toInteger(); i ++) {
print(i)
}
}
}
}
}
}

Groovy Solution
Here is a groovy solution more similar to your own
script {
def loop_value = "${params.choiceparameter}"
1.upto(loop_value.toInteger()) {
println it
}
}

Related

Ruby print or return specific field from object

How do I print the group_id from the returned object?
The following is returned from a function. I want to print the group_id or maybe return the group_id
{
:security_groups=>[
{
:description=>"Created By ManageIQ",
:group_name=>"MIQ_019",
:ip_permissions=>[
{
:from_port=>22,
:ip_protocol=>"tcp",
:ip_ranges=>[
{
:cidr_ip=>"0.0.0.0/0",
:description=>nil
}
],
:ipv_6_ranges=>[],
:prefix_list_ids=>[],
:to_port=>22,
:user_id_group_pairs=>[]
}
],
:owner_id=>"943755119718",
:group_id=>"sg-0c2c5f219f1bafc1a",
:ip_permissions_egress=>[
{
:from_port=>nil,
:ip_protocol=>"-1",
:ip_ranges=>[
{
:cidr_ip=>"0.0.0.0/0",
:description=>nil
}
],
:ipv_6_ranges=>[],
:prefix_list_ids=>[],
:to_port=>nil,
:user_id_group_pairs=>[]
}
],
:tags=>[],
:vpc_id=>"vpc-d817c1b3"
}
],
:next_token=>nil
}
This is the function: I want to return security_group.group_id
def describe_security_group (
group_name
)
ec2 = get_aws_client
security_group = ec2.describe_security_groups(
filters: [
{name: 'group-name', values: [ group_name ]}]
)
puts "Describing security group '#{group_name}' with ID " \
"'#{security_group}'"
return security_group
rescue StandardError => e
puts "Error describing security group: #{e.message}"
return
end
So, returning value seems like a hash, or you can make it hash exactly.
For case with one-element array you can simple use ruby dig method.
And according to your datum and comment below we can access needed element like this:
# from your ec2 api call
security_group = ec2.describe_security_groups(...)
# Result value is stored in `security_group` variable,
# and looks exactly like hash below
{
:security_groups=>[
{
:description=>"Created By ManageIQ",
:group_name=>"MIQ_019",
:ip_permissions=>[
{
:from_port=>22,
:ip_protocol=>"tcp",
:ip_ranges=>[
{
:cidr_ip=>"0.0.0.0/0",
:description=>nil
}
],
:ipv_6_ranges=>[],
:prefix_list_ids=>[],
:to_port=>22,
:user_id_group_pairs=>[]
}
],
:owner_id=>"943755119718",
:group_id=>"sg-0c2c5f219f1bafc1a",
:ip_permissions_egress=>[
{
:from_port=>nil,
:ip_protocol=>"-1",
:ip_ranges=>[
{
:cidr_ip=>"0.0.0.0/0",
:description=>nil
}
],
:ipv_6_ranges=>[],
:prefix_list_ids=>[],
:to_port=>nil,
:user_id_group_pairs=>[]
}
],
:tags=>[],
:vpc_id=>"vpc-d817c1b3"
}
],
:next_token=>nil
}
# And this is a target value, that you can store in another one,
# return from method or simply print to output
security_group.dig(:security_groups)
.try(:[], 0)
.dig(:group_id)
=> "sg-0c2c5f219f1bafc1a"
But if you need to search in array with multiple elements, methods from Ruby's Enumerable module could be helpful (like select or reject).
UPDATE with OpenStruct, if you prefer such method calls with dot notation:
json = security_group.to_json
os = JSON.parse(json, object_class: OpenStruct)
os.security_groups.first.group_id
=> "sg-0c2c5f219f1bafc1a"

How to implement subscriptions in graphql.js?

This is a pretty simple question.
How to implement subscriptions in graphql?
I'm asking specifically for when using graphql.js constructors like below ?
I could not find a clean/simple implementation.
There is another question here, but it deals with relay.js - i don't want to unnecessarily increase the nr of external dependencies in my app.
What i have:
module.exports = function (database){
return new GraphQLSchema(
{ query: RootQuery(database)
, mutation: RootMutation(database)
, subscription: RootSubscription(database) -- i can see this in graphiql - see below
}
);
}
function RootSubscription(database){
return new GraphQLObjectType(
{ name: "RootSubscriptionType"
, fields:
{ getCounterEvery2Seconds:
{ type: new GraphQLNonNull(GraphQLInt)
, args :
{ id: { type: GraphQLString }
}
, subscribe(parent, args, context){
// this subscribe function is never called .. why?
const iterator = simpleIterator()
return iterator
}
}
}
}
)
}
I learned that i need a subscribe() which must return an iterator from this github issue.
And here is a simple async iterator. All this iterator does - is to increase and return the counter every 2 seconds. When it reaches 10 it stops.
function simpleIterator(){
return {
[ Symbol.asyncIterator ]: () => {
let i = 0
return {
next: async function(){
i++
await delay(2000)
if(i > 10){
return { done: true }
}
return {
value: i,
done: false
}
}
}
}
}
}
When i run the graphiql subscription, it returns null for some reason:
I'm piecing together code from multiple sources - wasting time and hacking it basically. Can you help me figure this one out?
Subscriptions are such a big feature, where are they properly documented? Where is that snippet of code which you just copy paste - like queries are for example - look here.
Also, i can't use an example where the schema is separate - as a string/from a file. I already created my schema as javascript constructors. Now since im trying to add subscriptions i can't just move back to using a schema as a string. Requires rewriting the entire project. Or can i actually have both? Thanks :)

Jenkins pipeline to verify multpile file existence in when condition

I need to verify multiple file existence in single when condition using && operation.
check for any file that ends with .doc along with final.txt and proceed further.
Second fileexistence(final.txt) seems to be working fine seperately. Please suggest on this
when {
expression
{
return (fileExists("""ls ${Path}/${version}/test/*.doc""")) && !(fileExists("""${Path}/${Version}/test2/final.txt"""))
}
}
You could use allOf and not
when {
allOf {
expression {
return fileExists("ls ${Path}/${version}/test/*.doc")
}
not {
expression {
return fileExists("${Path}/${Version}/test2/final.txt")
}
}
}
}

Conditional input step in declarative pipeline

using Jenkins v2.138.2 and workflow-aggregator v2.6, I'm trying to define a conditional input step that depends on the value of a job parameter as follows:
stage('apply') {
when { expression { params.apply_plan != 'no' } }
if (params.apply_plan != 'yes') {
input {
message 'Apply this plan?'
}
}
steps {
withAWS(region: 'us-east-1', role: assume_role) {
dir(path: tf_dir) {
sh "make apply"
}
}
}
}
However this if { ( ... ) input { ...} } syntax gives me a run-time error:
java.lang.ClassCastException: org.jenkinsci.plugins.workflow.support.steps.input.InputStep.message expects class java.lang.String but received class org.jenkinsci.plugins.workflow.cps.CpsClosure2
Any idea how to do this?
Thanks,
Chris
I think you are using the wrong syntax here. The input { … } is only valid as a directive (outside of the steps directly below stage). What you want to use is the input step which is described here. Basically you just need to remove the curly braces and put it into a script within steps:
stage("stage") {
steps {
script {
if (params.apply_plan != 'yes') {
input message: 'Apply this plan?'
}
}
withAWS(region: 'us-east-1', role: assume_role) {
dir(path: tf_dir) {
sh "make apply"
}
}
}
}

Using event field as hash variable

I'm receving events in Logstash containing measurement, values and tags. I do not know ahead of time what field there are and what tags. So i wanted to do something like this:
input {
http {}
}
filter {
ruby {
code => '
tags = event.get("stats_tags").split(",")
samples = event.get("stats_samples").split(" ")
datapoints = {}
samples.each {|s|
splat = s.split(" ")
datapoints[splat[0]] = splat[1]
}
event.set("[#metadata][stats-send-as-tags]", tags)
event.set("[#metadata][stats-datapoints]", datapoints)
'
}
}
output {
influxdb {
host => "influxdb"
db => "events_db"
measurement => measurement
send_as_tags => [#metadata][stats-send-as-tags]
data_points => [#metadata][stats-datapoints]
}
}
But this produce error. After much googling to no avail i'm starting to think this is imposible.
Is there a way to pass hash and array from event field to output/filter configuration?
EDIT: If i doublequote it, the error i'm getting is
output {
influxdb {
# This setting must be a hash
# This field must contain an even number of items, got 1
data_points => "[#metadata][stats-datapoints]"
...
}
}

Resources