Bash - access oc node properties - bash

The problem is pretty simple, but I am struggling to understand where to even look for a solution. I want to iterate over a list of pods I retrieve from openshift and then output some of its properties.
In other words, what I want to do is this:
for node in $(oc get nodes);
do
echo ${node.name}
echo ${node.role}
done
Unfortunately that leads to the error "line 67: ${node.name}: bad substitution".
Just iterating over the nodes with echo node works fine, but it just lists all the properties with one line per property value.
the output of just oc get nodes is:
NAME STATUS ROLES AGE VERSION
avaloq-abcde-master-0-xyz Ready master 38d v1.xx
avaloq-abcde-master-1-dfs Ready master 38d v1.xx
avaloq-abcde-master-2-gsd Ready master 38d v1.xx
the output of
for node in $(oc get nodes -o name);
do
echo ${node}
done
is
node/avaloq-abcde-master-0-xyz
node/avaloq-abcde-master-1-dfs
node/avaloq-abcde-master-2-gsd
If I try to add another property via -o (the output format?), it throws the following error:
error: unable to match a printer suitable for the output format "roles", allowed formats are: custom-columns,custom-columns-file,go-template,go-template-file,json,jsonpath,jsonpath-as-json,jsonpath-file,name,template,templatefile,wide,yaml
What I expect is the following output
node/avaloq-abcde-master-0-xyz
master
node/avaloq-abcde-master-1-dfs
master
node/avaloq-abcde-master-2-gsd
master
I assume that is where my understanding is lacking. Is the "array of objects/ table" returned via "oc get nodes" not an array of objects but rather just a text list separated by tabs and return characters?

You can use something like this if you only need specific columns from oc get node command
oc get nodes | awk '{print $1, $3}'
which will print output like
avaloq-abcde-master-0-xyz master
avaloq-abcde-master-1-dfs master
avaloq-abcde-master-2-gsd master

Related

Extract the lines using sed or awk and save them in file

Dear Stackoverflow Community,
I am trying to grab the value or the part of the string or lines.
The Kubernetes init gives 2 kubeadm join commands.
I want to extract the first one and save it in a file and similarly extract the 2nd one and save it in a file.
Below is the text that I am trying to extract from the file:
You can now join any number of the control-plane node running the following command on each as root:
kubeadm join 10.0.0.0:6443 --token jh88qi.uch1l58ri160bve1 \
--discovery-token-ca-cert-hash sha256:f9c9ab441d913fec7d157c20f1c5e93c496123456ac4ec14ca8e02ab7f916d7fb \
--control-plane --certificate-key 179e288571e33d3d68f5691b6d8e7cefa4657550fc0886856a52e2431hjkl7155
Please note that the certificate-key gives access to cluster sensitive data, keep it secret!
As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use
"kubeadm init phase upload-certs --upload-certs" to reload certs afterward.
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 10.0.0.0:6443 --token jh88qi.uch1l58ri160bve1 \
--discovery-token-ca-cert-hash sha256:f9c9ab441d913fec7d157c20f1c5e93c496123456ac4ec14ca8e02ab7f916d7fb
Goal -
Extract both kubeadm join commands and save them in different files for automation.
Commands Used till now -
sed -ne '/--control-plane --certificate-key/p' token
With the above command, I want to extract value if I can and save it in a file.
The other command -
awk '/kubeadm join/{x=NR+2}(NR<=x){print}' token
token is the filename
You didn't show the expected output so it's a bit of a guess but this:
awk -v RS= '/^ *kubeadm join/{print > ("out"NR); close("out"NR)}' file
should do what I think you want given the input you provided.

Ansible playbook to compare 2 register output

I have created 2 tasks to fetch the 2 below outputs:
first output:
NAME STATUS ROLES AGE VERSION
control1.eee-dev.dd.k8s.c0.ms.com Ready master 146d v1.18
control2.eee-dev.dd.k8s.c0.ms.com Ready master 146d v1.18
control3.eee-dev.dd.k8s.c0.ms.com Ready master 146d v1.18
dd900xc15xx.nodes.c0.ms.com Ready worker 146d v1.18
dd900xc16xx.nodes.c0.ms.com Ready worker 146d v1.18
second output:
Transaction ID: xxxx-xxxx-xxxxx-xxxxxx
bootstrap.eee-dev.dd.k8s.c0.ms.com
control1.eee-dev.dd.k8s.c0.ms.com
control2.eee-dev.dd.k8s.c0.ms.com
control3.eee-dev.dd.k8s.c0.ms.com
dd900xc15xx.nodes.c0.ms.com
dd900xc16xx.nodes.c0.ms.com
Now, how do I compare the above 2 outputs stored in register and print PASSED, if NAME(from first output, meaning only the nodes from the first column) matches with the second output? if not FAILED. Note: we need to ignore the first 2 lines from the second output
I'm thinking to do it by logic(filter the node names and do comparison), but unsure about how do I convert this into an ansible playbook. Highly appreciate your suggestions and comments to achieve this.

gcloud dns managed-zones list along with record-sets count format

In the output of gcloud dns managed-zones list ,I want to show the name of dnsName, creationTime, name, networkName, visibility and the count of recrod-sets in each hosted-zone.
I used below command to get two output in two commands
#get hosted-zone and other values
gcloud dns managed-zones list --format='table(dnsName, creationTime:sort=1, name, privateVisibilityConfig.networks.networkUrl.basename(), visibility)'
#get record-sets for a hostedzone
gcloud dns record-sets list --zone=$zoneName |awk 'NR>1{print}'|wc -l
I think I can get this in a shell script by getting a list of hosted zone and then printing two output together.
But is there a better way to do in a single gcloud command ?
IIRC (!?), you'll need to issue both gcloud commands as each provides distinct data.
To your point, you should be able to easily combine the combine the commands using a shell script and iterating over each zone from managed-zones list, to issue record-sets list --zone=${i}.
If you'd like help, please include dummy data from the 2 commands and I'll draft something for you.

openshift commands to catch POD name programmatically/scripting

I have pods in my open shift and want to work on multiple open shift applications. Lets say like below
sh-4.2$ oc get pods
NAME READY STATUS RESTARTS AGE
jenkins-7fb689fc66-fs2xb 1/1 Running 0 4d
jenkins-disk-check-1587834000 0/1 Completed 0 21h
NAME READY STATUS RESTARTS AGE
jenkins-7fb689fc66-gsz9j 0/1 Running 735 9d
jenkins-disk-check-1587834000
NAME READY STATUS RESTARTS AGE
jenkins-9euygc66-gsz9j 0/1 Running 735 9d
I have tried with below command
oc get pods
export POD=$(oc get pods | awk '{print $1}' | grep jenkins*)
I want to find the pods starting with numbers "jenkins-7fb689fc66-fs2xb",jenkins-9euygc66-gsz9j, etc... using scripting and need to ignore disk check pods. If i catch the above pods and need to execute the terminal and run some shell commands via programmatically. Can someone help me on this?
kubectl get (and by extension oc get) is a very versatile tool. Unfortunately, after looking around online for awhile, you will definitely not be able to do Regex without relying on an external tool like awk or grep. (I know this wasn't exactly what you were asking, but I figured I'd at least try to see if it's possible.
With that said, there are a couple of tricks you can rely on to filter your oc get output before you even have to pull in external tools (bonus points because this filtering occurs on the server before it even hits your local tools).
I first recommend running oc get pods --show-labels, because if the pods you need are appropriately labeled, you can use a label selector to get just the pods you want, e.g.:
oc get pods --selector name=jenkins
oc get pods --selector <label_key>=<label_value>
Second, if you only care about the Running pods (since the disk-check pods look like they're already Completed), you can use a field selector, e.g.:
oc get pods --field-selector status.phase=Running
oc get pods --field-selector <json_path>=<json_value>
Finally, if there's a specific value that you're after, you can pull that value into the CLI by specifying custom columns, and then greping on the value you care about, e.g.:
oc get pods -o custom-columns=NAME:.metadata.name,TYPES:.status.conditions[*].type | grep "Ready"
The best thing is, if you rely on the label selector and/or field selector, the filtering occurs server side to cut down on the data that ends up making it to your final custom columns, making everything that much more efficient.
For your specific use case, it appears that simply using the --field-selector would be enough, since the disk-check pods are already Completed. So, without further information on exactly how the Jenkins pod's JSON is constructed, this should be good enough for you:
oc get pods --field-selector status.phase=Running
Assuming that you need to print jenkins id in first field, could you please try following.
awk 'match($0,/jenkins[^ ]*/){print substr($0,RSTART,RLENGTH)}' Input_file
Explanation: Adding explanation for above code.
awk ' ##Starting awk program from here.
match($0,/jenkins[^ ]*/){ ##Using match function in which mentioning regex jenkins till spacein current line.
print substr($0,RSTART,RLENGTH) ##Printing sub-string in current line where starting point is RSTART till RLENGTH value.
}
' Input_file ##Mentioning Input_file name here.
Adding this answer for others reference.
You could use in this way.
export POD=$(oc get pods | awk '{print $1}' | grep jenkins* | grep -v jenkins-disk-check)

Filter Column in CSV and get the unique value

I am having three columns in a CSV: Client Name, save Set Name and Status. For some clients, we have two Status as Failed and Success both. So, I want to filter those clients only which have status as only Failed. Clients who are having two entries such as Failed and success also, I want to omit.
When I am using the listed command, it's giving me values whose status was successful also might be later on. I want values which are only Failed. Not successful even once
cat "$pwd"/Daily-Failed.csv|egrep -i 'failed|Interrupted'|awk -F',' '{print $2,$3,$9}'|sort -u > "$pwd"/Final-Failed/Failed.csv
(edit) Or with newlines:
cat "$pwd"/Daily-Failed.csv|
egrep -i 'failed|Interrupted'|
awk -F',' '{print $2,$3,$9}'|
sort -u > "$pwd"/Final-Failed/Failed.csv
enter image description here
Please find the input and desired output. Input Client Name, Save Set, Status
Star,D:/,Failed
Star,C:/,Failed
Moon,C:/,Failed
Galaxy,D:/,Failed
Sun,D:/,Failed
Star,C:/,Success
Sun,D:/,Success
Output "Client Name","Save Set",Status
Galaxy,D:/,Failed
Moon,C:/,Failed
Star,D:/,Failed
I want to filter those clients only which have status as only Failed. Clients who are having two entries such as Failed and success also, I want to omit.
I'm going to assume, looking at your sample input (Which really needs to be text in your question, not an image), that both the Client Name and Save Set columns matter - you have (Star, C:/) with both success and failure rows, and (Star, D:/) with just failure, and the latter shows up in your output, and that's the only way that would make sense given your stated goal. On the other hand you also have two (Sun, D:/) rows, one success, one failure, and that shows up in your output even though it doesn't meet your criteria any way you look at it...
Anyways, this sort of grouping and filtering of tabular data screams database, and I like to script sqlite to make it do all the work in such cases:
#!/bin/sh
filename=Daily-Failed.csv
sqlite3 -batch -csv -header <<EOF
.import '${filename}' tbl
SELECT *
FROM tbl
GROUP BY "Client Name", "Save Set"
HAVING count(*) = 1 AND Status = 'Failed'
EOF
after taking the data in your image and turning it into a CSV file Daily-Failed.csv looking like
Client Name,Save Set,Status
Star,D:/,Failed
Star,C:/,Failed
Moon,C:/,Failed
Galaxy,D:/,Failed
Sun,D:/,Failed
Star,C:/,Success
Sun,D:/,Success
that script will output
"Client Name","Save Set",Status
Galaxy,D:/,Failed
Moon,C:/,Failed
Star,D:/,Failed

Resources