groovy command curl on windows Jenkins - windows

I have a groovy script that work on Linux Jenkins
import groovy.json.JsonSlurper
try {
List<String> artifacts = new ArrayList<String>()
//jira get summery for list by issue type story and label demo and project 11411
def artifactsUrl = 'https://companyname.atlassian.net/rest/api/2/search?jql=project=11411%20and%20issuetype%20in%20(Story)%20and%20labels%20in%20(demo)+&fields=summary' ;
def artifactsObjectRaw = ["curl", "-u", "someusername#xxxx.com:tokenkey" ,"-X" ,"GET", "-H", "Content-Type: application/json", "-H", "accept: application/json","-K", "--url","${artifactsUrl}"].execute().text;
def parser = new JsonSlurper();
def json = parser.parseText(artifactsObjectRaw );
//insert all result into list
for(item in json.issues){
artifacts.add( item.fields.summary);
}
//return list to extended result
return artifacts ;
}catch (Exception e) {
println "There was a problem fetching the artifacts " + e.message;
}
This script return all the names from Jira jobs by the API ,
But when I tried to run this groovy on Windows Jenkins the script will not work because windows do not have the command curl
def artifactsObjectRaw = ["curl", "-u","someusername#xxxx.com:tokenkey" ,"-X" ,"GET", "-H", "Content-Type: application/json", "-H", "accept: application/json","-K","--url","${artifactsUrl}"].execute().text;
how should I preform this command?

The following code:
import groovy.json.JsonSlurper
try {
def baseUrl = 'https://companyname.atlassian.net'
def artifactsUrl = "${baseUrl}/rest/api/2/search?jql=project=MYPROJECT&fields=summary"
def auth = "someusername#somewhere.com:tokenkey".bytes.encodeBase64()
def headers = ['Content-Type': "application/json",
'Authorization': "Basic ${auth}"]
def response = artifactsUrl.toURL().getText(requestProperties: headers)
def json = new JsonSlurper().parseText(response)
// the below will implicitly return a list of summaries, no
// need to define an 'artifacts' list beforehand
def artifacts = json.issues.collect { issue -> issue.fields.summary }
} catch (Exception e) {
e.printStackTrace()
}
is pure groovy, i.e. no need for curl. It gets the items from the jira instance and returns a List<String> of summaries. Since we don't want any external dependencies like HttpBuidler (as you are doing this from jenkins) we have to manually do the basic auth encoding.
Script tested (the connecting and getting json part, did not test the extraction of summary fields) with:
Groovy Version: 2.4.15 JVM: 1.8.0_201 Vendor: Oracle Corporation OS: Linux
against an atlassian on demand cloud instance.
I removed your jql query as it didn't work for me but you should be able to add it back as needed.

Install curl and set the path in environment variable of windows.
Please follow the link to download curl on windows.

I would consider using HTTP request plugin when making HTTP Requests.
Since you are using a plugin, it does not matter if you are running in Windows or .
Linux as your Jenkins Host

Related

Ajax.post --> dom.fetch

I'm trying to use the dom.fetch (or dom.Fetch.fetch) api instead of Ajax.post and have a few problems:
Is this a correct translation from ajax to fetch?
Ajax.post(
url = "http://localhost:8080/ajax/myMethod",
data = byteBuffer2typedArray(Pickle.intoBytes(req.payload)),
responseType = "arraybuffer",
headers = Map("Content-Type" -> "application/octet-stream"),
)
dom.fetch(
"http://localhost:8080/fetch/myMethod",
new RequestInit {
method = HttpMethod.POST
body = byteBuffer2typedArray(Pickle.intoBytes(req.payload))
headers = new Headers {
js.Array(
js.Array("Content-Type", "application/octet-stream")
)
}
}
)
A "ReferenceError: fetch is not defined" is thrown on the js side though, same if replacing with dom.Fetch.fetch.
My setup:
Fresh jsdom 19.0.0 with
npm init private
npm install jsdom
project/plugins.sbt
libraryDependencies += "org.scala-js" %% "scalajs-env-jsdom-nodejs" % "1.1.0"
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.8.0")
build.sbt (in js project)
libraryDependencies += "org.scala-js" %%% "scalajs-dom" % "2.0.0"
jsEnv := new JSDOMNodeJSEnv(JSDOMNodeJSEnv.Config()
.withArgs(List("--dns-result-order=ipv4first")))
Thought that the jsEnv workaround was not needed on Scala.js 1.8 (see https://github.com/scala-js/scala-js-js-envs/issues/12#issuecomment-958925883). But it is still needed when I run the ajax version. With the workaround, my ajax version works fine, so it seems that my node installation is fine.
The fetch API is only available by-default in browser environments, and not in Node. node-fetch is also not pulled in (or at least not re-exported) by jsdom, so fetch is not available with the current package/environment setup.
Possible solutions:
Set the ScalaJS side up in such a way that it would call node-fetch on NodeJS and fetch on browser
Use XMLHttpRequest which is available on both platforms
(Please see the #scala-js channel in the Scala Discord for a related conversation).
Got help on the scala-js channel on Discord from #Aly here and #armanbilge here who pointed out that:
fetch is not available by default in Node.js or JSDOM, only in browsers.
scala-js-dom provides typesafe access to browser APIs, not Node.js APIs.
The distinction between browser API and Node API wasn't clear for me before, although it is well described in step 6 of the scala-js tutorial.
So, dom.fetch of the scala-js-dom API works when running a js program in a browser, but not if running a test that uses the Node jsEnv(ironment)! To fetch in a test one would have to npm install node-fetch and use node-fetch, maybe by making a facade with scala-js.
Since I want my code to work for both browser (scala-js-dom) and test (Node.js), I ended up falling back to simply using the Ajax.post implementation with XMLHttpRequest:
case class PostException(xhr: dom.XMLHttpRequest) extends Exception {
def isTimeout: Boolean = xhr.status == 0 && xhr.readyState == 4
}
val url = s"http://$interface:$port/ajax/" + slothReq.path.mkString("/")
val byteBuffer = Pickle.intoBytes(slothReq.payload)
val requestData = byteBuffer.typedArray().subarray(byteBuffer.position, byteBuffer.limit)
val req = new dom.XMLHttpRequest()
val promise = Promise[dom.XMLHttpRequest]()
req.onreadystatechange = { (e: dom.Event) =>
if (req.readyState == 4) {
if ((req.status >= 200 && req.status < 300) || req.status == 304)
promise.success(req)
else
promise.failure(PostException(req))
}
}
req.open("POST", url) // (I only need to POST)
req.responseType = "arraybuffer"
req.timeout = 0
req.withCredentials = false
req.setRequestHeader("Content-Type", "application/octet-stream")
req.send(requestData)
promise.future.recover {
case PostException(xhr) =>
val msg = xhr.status match {
case 0 => "Ajax call failed: server not responding."
case n => s"Ajax call failed: XMLHttpRequest.status = $n."
}
println(msg)
xhr
}.flatMap { req =>
val raw = req.response.asInstanceOf[ArrayBuffer]
val dataBytes = TypedArrayBuffer.wrap(raw.slice(1))
Future.successful(dataBytes)
}

No such DSL method 'httpRequest' found among steps

I am trying to request info from A REST API in my Jenkins pipeline, I have tried this code in various ways, but I keep getting this error:
java.lang.NoSuchMethodError: No such DSL method 'httpRequest' found among steps
I am beginning to think that it has something to do with my syntax, but I cannot figure out what.
Can anyone see what I am doing wrong?
Here is the code:
stage('Check Change No'){
steps{
script{
def response = httpRequest contentType: 'APPLICATION_JSON',
httpMode: 'GET',
validResponseCodes: '100:499',
url: "http://info-service-helm-chart-microservice-bin-deploy.apps.c01u.paas.mynet.com/v3/isDeployAlloved/123456"
echo response.status.toString()
if(response.status.toString() != "200"){
def jsonSlurper = new JsonSlurper()
def responseObject = jsonSlurper.parseText(response.getContent())
String errorMsg = responseObject.errors[0]
println "ERROR:"+ errorMsg
}
else{
println "ALL OK!!!. Change Approved."
}
}
}
}
I managed to figure it out, the solution is to install the jenkins plugin "HTTP requests" it was not installed on the jenkins instance i worked on.

Terraform template_cloudinit_config multiple part execution order is wrong

I am using the terraform to build my ec2-instances as part of instance bootstrap, added cloud-init config to run multiple userdata scripts. but the content_type = "text/x-shellscript" always executed first. I verified the cat /var/log/cloud-init-output.log file. it shows the shell script is invoked first. How do I config the shell script to run at last?
data "template_cloudinit_config" "myapp_cloudinit_config" {
gzip = false
base64_encode = false
# Main cloud-config configuration file.
part {
content_type = "text/cloud-config"
content = "${data.template_file.base_bootstrap_file.rendered}"
merge_type = "list(append)+dict(recurse_array)+str()"
}
part {
content_type = "text/cloud-config"
content = "${module.template_file_appsec_init.appsec_user_data_rendered}"
merge_type = "list(append)+dict(recurse_array)+str()"
}
part {
content_type = "text/x-shellscript"
content = "${module.template_file_beat_init.beat_user_data_rendered}"
}
}
Shell script looks like below
module " template_file_beat_init" {
source = "url" #the source url contains the zip file which includes the below shell script
}
#!/bin/sh
deploy_the_app() {
//invoke ansible playbook execution
}
deploy_the_app
Cloud provider: AWS
OS : RHEL 8.3
cloud-init --version: /usr/bin/cloud-init 19.4
Terraform v0.11.8

Jenkins custom pipeline and how to add property to be set in jenkinsfile

I'm trying to create a custom pipeline with groovy but I can't find anywhere on the web where it is discussed how to add a property that can be set in the jenkinsfile. I'm trying to add a curl command but need the URL to be set in the jenkinsfile because it will be different for each build.
Can anyone explain how that should be done or links where it has been discussed?
Example Jenkinsfile:
msBuildPipelinePlugin
{
curl_url = "http://webhook.url.com"
}
custom pipeline groovy code:
def response = sh(script: 'curl -i -X POST -H 'Content-Type: application/json' -d '{"text","Jenkins Info.\nThis is more text"}' curl_url, returnStdout: true)
Thanks
If you want to specify the URL as a string during every build, you can do either of the following:
Declarative Pipeline
Use the parameters {} directive:
pipeline {
agent {
label 'rhel-7'
}
parameters {
string(
name: 'CURL_URL',
defaultValue: 'http://www.google.com',
description: 'Enter the URL for file download'
)
}
stages {
stage('download-file') {
steps {
echo "The URL is ${params.CURL_URL}"
}
}
}
}
Scripted Pipeline
Use the properties([parameters([...])]) step:
parameters([
string(
name: 'CURL_URL',
defaultValue: 'http://www.google.com',
description: 'Enter the URL for file download'
)
])
node('rhel-7') {
stage('download-file') {
echo "The URL is ${params.CURL_URL}"
}
}
You can choose to leave the values of defaultValue and description empty.
Job GUI
Either of the above syntax will be rendered in the GUI as:
I got it to work using
//response is just the output of the curl statement
def response = ["curl", "-i", "-v", "-X", "POST", "--data-urlencode", "payload={\"text\":\"message body\"}", "curl url goes here"].execute().text
Thanks

How do I use the DSC package resource to install MongoDB?

I tried what seemed to be the straight-forward approach, and added a Package resource in my node configuration for the MongoDB MSI. I got the following error: "Could not get the https stream for file".
Here's the package configuration I tried:
package MongoDB {
Name = "MongoDB 3.6.11 2008R2Plus SSL (64 bit)"
Path = "https://fastdl.mongodb.org/win32/mongodb-win32-x86_64-2008plus-ssl-3.6.11-signed.msi"
ProductId = "88F7AA23-BDD2-4EBE-9985-EBB5D2E23E83"
Arguments = "ADDLOCAL=`"all`" SHOULD_INSTALL_COMPASS=`"0`" INSTALLLOCATION=`"C:\MongoDB\Server\3.6`""
}
(I had $ConfigurationData references in there, but substituted for literals for simplicity)
I get the following error:
Could not get the https stream for file
Possible TLS version issue? I found that Invoke-WebRequest needed the following to get it to work with that same mongo download URL. Is there a way to do this with the package resource?
[Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls"
Using nmap to interrogate both nodejs.org and fastdl.mongodb.org (which is actually on cloudfront) it was indeed true that TLS support differed. Node still supports TLS version 1.0, which so happens to work with PowerShell. But MongoDB's site only supports TLS versions 1.1 or 1.2.
As I mentioned in my question, I suspected that setting the .Net security protocol work, and indeed it does. There's no way to add arbitrary script to the DSC package resource, so I needed to make a script block just to run this code, and have the package resource depend on it.
This is what I got to work:
Node $AllNodes.Where{$_.Role -contains 'MongoDBServer'}.NodeName {
Script SetTLS {
GetScript = { #{ Result = $true } }
SetScript = { [Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls" }
TestScript = { $false } #Always run
}
package MongoDB {
Ensure = 'Present'
Name = 'MongoDB 3.6.11 2008R2Plus SSL (64 bit)'
Path = 'https://fastdl.mongodb.org/win32/mongodb-win32-x86_64-2008plus-ssl-3.6.11-signed.msi'
ProductId = ''
Arguments = 'ADDLOCAL="all" SHOULD_INSTALL_COMPASS="0" INSTALLLOCATION="C:\MongoDB\Server\3.6"'
DependsOn = '[Script]SetTLS'
}
...

Resources