I wanna assign the json results if it get successful is 0 and failed is 1.
The results is success as below:
[root#jenkins qemu-server]# aws elb describe-instance-health --profile test --load-balancer-name classic-balance-test
{
"InstanceStates": [
{
"InstanceId": "i-05414ddade7f312ff",
"ReasonCode": "Instance",
"State": "OutOfService",
"Description": "Instance is in stopped state."
},
{
"InstanceId": "i-0ccf638d2cd59bc73",
"ReasonCode": "Instance",
"State": "OutOfService",
"Description": "Instance is in stopped state."
}
]
}
The results is failed as below:
[root#jenkins qemu-server]# aws elb describe-instance-health --profile test --load-balancer-name classic-balance-test1
An error occurred (LoadBalancerNotFound) when calling the DescribeInstanceHealth operation: There is no ACTIVE Load Balancer named 'classic-balance-test1'
You might want to try running echo $? which will print out the status code of the last thing executed.
So you could assign a variable to that command like so results=$(echo $?)
and when you echo $results you'll get the status code of the command ran
From the official documentation:
These are the following return codes returned at the end of execution
of a CLI command:
0 -- Command was successful. [...]
[...]
To determine the return code of a command, run the following right
after running a CLI command. Note that this will work only on POSIX
systems:
$ echo $?
Related
Objective: Trying to check if resource exist on azure with bash script
Code that I use :
status=$(az group list --query "[?name.contains(#,'test')]")
if [[ "$status" == null ]];
then
echo "not exist"
else
echo "exist"
fi
I have this resource in azure i.e it should return as "exist" however its says not exist
If I change to a non existant resource group name then time also its gives not exist.
do you see any syntax issue here ?
Instead of script if I execute at commmand line to check , below are results
user#ablab:~$ status=$(az group list --query "[?name.contains(#,'abcd')]")
user#ablab:~$ echo $status
[]
user#ablab:~$ status=$(az group list --query "[?name.contains(#,'test')]")
user#ablab:~$ echo $status
[ { "id": "/subscriptions/xxxx-xxxx-xxx--xxxxx3/resourceGroups/test1", "location": "westeurope", "managedBy": null, "name": "test1", "properties": { "provisioningState": "Succeeded" }, "tags": null, "type": "Microsoft.Resources/resourceGroups" } ]
Now I wanna use if condition, so that if its exist it should process set of flow else set of code..
Please let me know what wrong with my if statement.
The syntax is fine. However, I don't see from your example, that az would write the string null to stdout. In the first case, it prints, according to what you posted, the string []. To catch this case, you would have to test
if [[ $status == '[]' ]]
then
...
The quotes around the string tell bash to not interpret it as a glob pattern.
I'm trying to check that all instances attached to an AWS ELB are in a state of "InService",
For that, I created an AWS CLI command to check the status of the instances.
problem is that the JSON output returns the status of both instances.
So it is not that trivial to examine the output as I wish.
When I run the command:
aws elb describe-instance-health --load-balancer-name ELB-NAME | jq -r '.[] | .[] | .State'
The output is:
InService
InService
The complete JSON is:
{
"InstanceStates": [
{
"InstanceId": "i-0cc1e6d50ccbXXXXX",
"State": "InService",
"ReasonCode": "N/A",
"Description": "N/A"
},
{
"InstanceId": "i-0fc21ddf457eXXXXX",
"State": "InService",
"ReasonCode": "N/A",
"Description": "N/A"
}
]
}
What I've done so far is creating that one liner shell command:
export STR=$'InService\nInService'
if aws elb describe-instance-health --load-balancer-name ELB-NAME | jq -r '.[] | .[] | .State' | grep -q "$STR"; then echo 'yes'; fi
But I get "yes" as long as there is "InService" at the first command output
Is there a way I can get TRUE/YES only if I get twice "InService" as an output?
or any other way to determine that this is indeed what I got in return?
Without seeing an informative sample of the JSON it's not clear what the best solution would be, but the following meets the functional requirements as I understand them, without requiring any further post-processing:
jq -r '
def count(stream): reduce stream as $s (0; .+1);
if count(.[][] | select(.State == "InService")) > 1 then "yes" else empty end
'
I am writing a Jenkins Pipeline job for setting up AWS infrastructure using API calls to our in-house AWS CLI wrapper library. Running the raw bash scripts on a CentOS box or as a Jenkins Freestyle job runs fine. However, it fails in the context of a Pipeline job. I think that the quotes may need to be different for the Pipeline job but I am not sure how.
After further investigation, I found that the curl command returns the wrong response from the service when running the scripts within a Jenkins Pipeline job.
pipeline {
agent any
stages {
stage('Checkout code from Git'){
steps {
echo "Checkout code from a GitHub repository"
// Checkout code from a GitHub repository
checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'SubmoduleOption', disableSubmodules: false, parentCredentials: false, recursiveSubmodules: true, reference: '', trackingSubmodules: false]], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'xxxx', url: 'git#github.com:bbc/repo.git']]])
}
}
stage('Call our internal AWS CLI Wrapper System API to perform an ACTION on a specified ENVIRONMENT') {
steps {
script {
if("${params.ENVIRONMENT}" == 'int' && "${params.ACTION}" == 'create'){
echo "ENVIRONMENT=${params.ENVIRONMENT}, ACTION=${params.ACTION}"
echo ""
sh '''#!/bin/bash
# Create Neptune Cluster for the Int environment
cd blah-db
echo "Current working directory is $PWD"
CLOUD_FORMATION_FILE=$PWD/infrastructure/templates/neptune-cluster.json
echo "The CloudFormation file to operate on is $CLOUD_FORMATION_FILE"
echo "Running jq to transform the source CloudFormation file"
template=$(jq -M '.Parameters.Env.Default="int"' $CLOUD_FORMATION_FILE)
echo "Echoing the transformed CloudFormation file: \n$template"
echo "Running curl to make the http request to our internal AWS CLI Wrapper System"
curl -d "{\"aws_account\": \"1111111111\", \"region\": \"us-east-1\", \"name_suffix\": \"cluster\", \"template\": $template}" \
-H 'Content-Type: application/json' -H 'Accept: application/json' https://base.api.url/v1/services/blah-neptune/int/stacks \
--cert /path/to/client/certificate/client.crt --key /path/to/client/private-key/client.key
cd ..
pwd
# Set a timer to run for 300 seconds or 5 minutes to create a delay to allow for the Neptune Cluster to be fully provisioned first before adding instances to it.
'''
}
}
}
}
}
}
The actual result that I get from making the API call:
{"error": "Invalid JSON. Expecting property name: line 1 column 1 (char 1)"}
try change the curl as following:
curl -d '{"aws_account": "1111111111", "region": "us-east-1", "name_suffix": "cluster", "template": $template}'
Or assign the whole cmd to a variable and print it out to see it's as your wanted or not.
cmd = '''#!/bin/bash
cd blah-db
...
'''
echo cmd // compare the output string to the cmd of freestyle job.
sh cmd
I have kube service running with 2 named ports like this:
$ kubectl get service elasticsearch --output json
{
"apiVersion": "v1",
"kind": "Service",
"metadata": {
... stuff that really has nothing to do with my question ...
},
"spec": {
"clusterIP": "10.0.0.174",
"ports": [
{
"name": "http",
"nodePort": 31041,
"port": 9200,
"protocol": "TCP",
"targetPort": 9200
},
{
"name": "transport",
"nodePort": 31987,
"port": 9300,
"protocol": "TCP",
"targetPort": 9300
}
],
"selector": {
"component": "elasticsearch"
},
"sessionAffinity": "None",
"type": "NodePort"
},
"status": {
"loadBalancer": {}
}
}
I'm trying to get output containing just the 'http' port:
$ kubectl get service elasticsearch --output jsonpath={.spec.ports[*].nodePort}
31041 31987
Except when I add the test expression as hinted in the cheatsheet here http://kubernetes.io/docs/user-guide/kubectl-cheatsheet/ for the name I get an error
$ kubectl get service elasticsearch --output jsonpath={.spec.ports[?(#.name=="http")].nodePort}
-bash: syntax error near unexpected token `('
( and ) mean something in bash (see subshell), so your shell interpreter is doing that first and getting confused. Wrap the argument to jsonpath in single quotes, that will fix it:
$ kubectl get service elasticsearch --output jsonpath='{.spec.ports[?(#.name=="http")].nodePort}'
For example:
# This won't work:
$ kubectl get service kubernetes --output jsonpath={.spec.ports[?(#.name=="https")].targetPort}
-bash: syntax error near unexpected token `('
# ... but this will:
$ kubectl get service kubernetes --output jsonpath='{.spec.ports[?(#.name=="https")].targetPort}'
443
I had this issues on Windows in Powershell:
Error executing template: unrecognized identifier http2
When specifying a string value wrapped in double quotes in the jsonpath - to solve the error there are 2 ways:
Swap the single and double quotes:
kubectl -n istio-system get service istio-ingressgateway -o jsonpath="{.spec.ports[?(#.name=='http2')].port}"
Or escape the single quote encapsulated in the double quotes:
kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(#.name==\"http2\")].port}'
For me, it was giving the error on windows machine :
kubectl --namespace=app-test get svc proxy --output jsonpath='{.spec.ports[?(#.name=="web")].nodePort}'
> executing jsonpath "'{.spec.ports[?(#.name==web)].nodePort}'":
> unrecognized identifier web
Even though my json contains the name field in the ports array. Online it was working fine.
Instead of using the name field, then i have tried with the port field, which was of type integer and it works.
So, if any one is facing the same issue and if port field is predefined, then they can go with it.
kubectl --namespace=app-test get svc proxy --output jsonpath='{.spec.ports[?(#.port==9000)].nodePort}'
I have created bash scirpt that takes jstat metrics of my jvm instances!
Here is the output example :
demo.server1.sms.jstat.eden 24.34 0
demo.server1.lcms.jstat.eden 54.92 0
demo.server1.lms.jstat.eden 89.49 0
demo.server1.tms.jstat.eden 86.05 0
But when the Sensu-client runs this script it returns
Could not attach to 8584
Could not attach to 8588
Could not attach to 17141
Could not attach to 8628
demo.server1.sms.jstat.eden 0
demo.server1.lcms.jstat.eden 0
demo.server1.lms.jstat.eden 0
demo.server1.tms.jstat.eden 0
Here is the example of check_cron.json
{
"checks": {
"jstat_metrics": {
"type": "metric",
"handlers": ["graphite"],
"command": "/etc/sensu/plugins/jstat-metrics.sh",
"interval": 5,
"subscribers": [ "webservers" ]
}
}
}
And piece of my bash script
jvm_list=("sms:$sms" "lcms:$lcms" "lms:$lms" "tms:$tms" "ums:$ums")
for jvm_instance in ${jvm_list[#]}; do
project=${jvm_instance%%:*}
pid=${jvm_instance#*:}
if [ "$pid" ]; then
metric=`jstat -gc $pid|tail -n 1`
output=$output$'\n'"demo.server1.$project.jstat.eden"$'\t'`echo $metric |awk '{ print $3}'`$'\t0'
fi
done
echo "$output"
I find out that problem is with jstat and i tried to write full jstat path like /usr/lib/jvm/java-1.7.0-openjdk.x86_64/bin/jstat -gc $pid|tail -n 1 but it didn't help!
By the way if i will comment this row the output like "Could not attach to 8584" disappears!
I'm not a Java or Sensu user, but I can guess what happens.
Most likely, sensu-client runs your script as a user different from the one you use when testing manually, which doesn't have permissions to "attach" (whatever that means) to your jvm instances.
To verify this you can add invocation of "whoami" to your script, run it from sensu-client again, see what user it runs your script under and, if it is different, try to run your script as that user.
Yes you're right sensu runs all script as sensu user. To use jstat you have to add sensu to a sudoers.
just add file /etc/sudoers.d/sensu
Example:
Defaults:sensu !requiretty
Defaults:sensu secure_path =
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
sensu ALL = NOPASSWD: /etc/sensu/plugins/jsat-metrics.rb