How to compare strings in go templates? - go

I'd like to show entries that have .metadata.labels.app set to "myapp"value.
Command:
kubectl get pods -o go-template --template="{{range .items}}{{if eq .metadata.labels.app "myapp"}}{{.metadata.name}} {{end}}{{end}}"
It gives an error:
output:1: function "myapp" not defined
The structures look like this:
- apiVersion: v1
kind: Pod
metadata:
creationTimestamp: 2017-09-15T08:18:26Z
generateName: myapp-2830765207-
labels:
app: myapp
pod-template-hash: "2830765207"
name: myapp-2830765207-dh359
namespace: default

I haven't used kubetcl before, but I am familiar with shell commands in general, from which I can tell you one thing that's going wrong, and maybe that's all you need. (I'm also somewhat familiar with Go templates, and your string comparison looks fine to me.) By using double quotes around your template and within your template, you're actually closing the string you're passing in as the template at the first double quote in "myapp". Using single quotes around the template should help:
kubectl get pods -o go-template --template='{{range .items}}{{if eq .metadata.labels.app "myapp"}}{{.metadata.name}} {{end}}{{end}}'

Related

how to change a value of element on kustomize.yaml using github actions

if i having this kustomize.yaml file :
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
patches:
- patch: |-
- op: replace
path: /spec/rules/0/host
value: the.new.domain.com
target:
kind: Ingress
name: the_name_of_ingress
and i want to replace this value:the.new.domain.com with a new domain name using kustomize command with github actions like this : kustomize edit set
any idea how to make it ? even if u have another idea can letting me implement it inside the github actions its ok
tnx anyway.
You can make use of some yaml processor like yq for this.
Example:
yq -i '.patches[0].patch = "- op: replace
path: /spec/rules/0/host
value: chetantalwar.com"' tes.yaml
I used this using CLI and it updated the file, and similarly you can put it in Github Action as well like give below.
- name: Set foobar to cool
uses: mikefarah/yq#master
with:
cmd: yq -i '.patches[0].patch = "Your Value"' 'kustomize.yml'
Links:
YQ
YQ Github Action
There is one more option which you can try is, templating your kustomize.yaml and in Github Action you can update the respective value using sed.
I had same usecase as #stack-acc and heavily inspired by response from #Chetan, found this
kustomization.yaml
patches:
- patch: |-
- op: replace
path: "/metadata/name"
value: proc-cls-s2e2-tcp
yq command to replace just the value
yq -i '.patches.[0].patch |= sub("value: .*?$", "value: publ-cls-s2e2-udp")' kustomization.yaml
Don't have to repeat whole op: replace section in the script and just replace the value.

How to specify a condition for a loop in yaml pipelines

I'm trying to download multiple artifacts into different servers(like web, db) using environments. Currently i have added the task DownloadPipelineArtifact#2 in a file and using template to add that task in azure-pipelines.yml. As i'm having multiple artifacts, im trying to use for loop where i'm getting issues.
#azure-pipelines.yml
- template: artifacts-download.yml
parameters:
pipeline:
- pipeline1
- pipeline2
- pipeline3
path:
- path1
- path2
- path3
I need to write loop in yaml so that it should download the pipeline1 artifacts to path1 and so on. Can someone please help??
Object-type parameters are your friend. They are incredibly powerful. As qBasicBoy answered, you'll want to make sure that you group the multiple properties together. If you're finding that you have a high number of properties per object, though, you can do a multi-line equivalent.
The following is an equivalent parameter structure to what qBasicBoy posted:
parameters:
- name: pipelines
type: object
default:
- Name: pipeline1
Path: path1
- Name: pipeline2
Path: path2
- Name: pipeline3
Path: path3
An example where you can stack many properties to a single object is as follows:
parameters:
- name: big_honkin_object
type: object
default:
config:
- appA: this
appB: is
appC: a
appD: really
appE: long
appF: set
appG: of
appH: properties
- appA: and
appB: here
appC: we
appD: go
appE: again
appF: making
appG: more
appH: properties
settings:
startuptype: service
recovery: no
You can, in essence, create an entire dumping ground for everything that you want to do by sticking it in one single object structure and properly segmenting everything. Sure, you could have had "startuptype" and "recovery" as separate string parameters with defaults of "service" and "no" respectively, but this way, we can pass a single large parameter from a high level pipeline to a called template, rather than passing a huge list of parameters AND defining said parameters in the template yaml scripts (remember, that's necessary!).
If you then want to access JUST a single setting, you can do something along the lines of:
- task: PowerShell#2
inputs:
targetType: 'inline'
script: |
# Write your PowerShell commands here.
Write-Host "Apps start as a "${{ parameters.settings.startuptype }}
Write-Host "Do the applications recover? "${{ parameters.settings.recovery }}
This will give you the following output:
Apps start as a service
Do the applications recover? no
YAML and Azure Pipelines are incredibly powerful tools. I can't recommend enough going through the entire contents of learn.microsoft.com on the subject. You'll spend a couple hours there, but you'll come out the other end with an incredibly knowledge of how these pipelines can be tailored to do everything you could ever NOT want to do yourself!
Notable links that helped me a TON (only learned this a couple months ago):
How to work with the YAML language in Pipelines
https://learn.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema%2Cparameter-schema
How to compose expressions (also contains useful functions like convertToJSON for your object parameters!)
https://learn.microsoft.com/en-us/azure/devops/pipelines/process/expressions?view=azure-devops
How to create variables (separate from parameters, still useful)
https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml
SLEEPER ALERT!!! Templates are HUGELY helpful!!!
https://learn.microsoft.com/en-us/azure/devops/pipelines/process/templates?view=azure-devops
You could use an object with multiple properties
parameters:
- name: pipelines
type: object
default:
- { Name: pipeline1, Path: path1 }
- { Name: pipeline2, Path: path2 }
- { Name: pipeline3, Path: path3 }
steps:
- ${{each pipeline in parameters.pipelines}}:
# use pipeline.Name or pipeline.Path

YAML helm chart how to escape & sign

I have a helm chart in yaml like this:
env:
- name: EmailHeader
value: {{ .Values.npsweb.email.support.header | quote }}
and in my Values file, I have like this:
npsweb:
email:
support:
header: <html><body><img src='https://nps.dev.nuancepowershare.com/smr/images/weblogo.png' alt='SMR LOGO' /><hr />
But it says that Anchor lt;html><body><img is never used. I tried putting double quote around it, but it still didn't get picked up.
What is the problem here and how can I fix this?
You need to explicitly quote the string. There are a couple of ways to do this, so pick whichever makes sense:
header-with-single-quotes: '<.../>'
header-with-double-quotes: "<.../>"
header-as-block-scalar: |-
<html>...</html>
header-as-block-scalar-with-whitespace: |-
<html>
<body>
...
</body>
</html>
All of these forms are the same, except that the last one will include embedded newlines and spaces. (Since your value includes single quotes, the single-quoted form will be a little less convenient.) You could also consider storing the HTML content in a file and reading it in with .Files.Get (though Helm doesn't include a template function for escaping HTML).
What's wrong with your existing values.yaml file? YAML has the notion of an anchor; you can give a part of a document a label like this, and reference it from elsewhere in the document. The '&' character at the beginning of the value marks an anchor, and the text up to the first space is the name of the anchor.
Not so much in Kubernetes, but in Docker Compose you'll somewhat routinely see this for reusable blocks of environment variables:
# (This is a Docker Compose file, not Kubernetes, as a YAML example)
version: '3.8'
x-environment: &environment # <-- anchor
DB_HOST: db
services:
db: { image: postgres }
application:
build: .
environment: *environment # <-- reference to anchor
worker:
build: .
command: ./worker
environment: *environment # <-- same reference to anchor

YAML error : end of the stream or a document separator is expected

I'm getting the following error in a yaml file
Error : end of the stream or a document separator is expected at line 2, column 11:
apiVersion: v1
^
Line : undefined undefined
This is the entire contents of the file
<<EOT
apiVersion: v1
clusters:
- cluster:
server: https://3F46DDD9022BD149B88DA7ED4AFB2B30.gr7.eu-west-1.eks.amazonaws.com
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN5RENDQWJDZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjR> name: kubernetes
contexts:
- context:
cluster: kubernetes
user: aws
name: aws
current-context: aws
kind: Config
preferences: {}
users:
- name: aws
user:
exec:
apiVersion: client.authentication.k8s.io/v1alpha1
command: aws-iam-authenticator
args:
- "token"
- "-i"
- "terraform-eks-demo"
EOT
I've been googling this for hours but I'm getting nowhere tried . I've tried every YAML linter I can find, can anybody point me in the right direction? I am new to this, if that wasn't obvious
You need to remove <<EOT and EOT. You probably copied them from some code that injected YAML into a command line utility via a heredoc but they should not part of the YAML content.
What happens is that when the YAML processor sees <<EOT (which parses as part of a YAML scalar because < is not a special character) and then a new line. A multiline scalar at root level must be the single root node of a document. When the second line is read, the YAML processor sees a : which is not allowed here. At this point, both lines have been read as multiline scalar, and a multiline scalar cannot be used as mapping key. Therefore, the processor complains that after the single root node of the YAML document, the document must end, but instead you try to start a mapping.
I think you should keep a space before 'v1' at line2.

google deployment manager access nested properties with --properties argument

If Im using a jinja template I can override properties via command line like this:
--properties zone:us-central1-a,machineType:n1-standard-1,image:debian-9
But I see no documentation or examples for doing this with nested properties like labels or environmentVariables for example:
resources:
- name: resource-name
type: 'gcp-types/cloudfunctions-v1:projects.locations.functions'
properties:
labels:
testlabel1: testlabel1value
testlabel2: testlabel2value
environmentVariables:
TEST: 'zzzzzzzzz'
How do set properties like these? this does not work: --properties labels:testlabel1:newvalue
The short answer here is that the --properties flag is not meant to pass property values to the template. A template cannot run without a configuration file, the --properties flag is meant to replace the config file. Each parameter you pass is the same as listing them in a config file.
Essentially using --template my-template.py --properties zone:us-central1-f is the equivalent of running --config myConfig.yaml where the YAML is defined as such:
imports:
- path: my-template.py
resources:
- name: some-resource
type: my-temaplte.py
properties:
zone: us-central1-f
The --properties flag is not meant to pass raw data to replace non-variables.
Although this does not directly answer your question, you shouldn't normally need to define nested values in the flag. Your template will generally call on direct variables taken from the object properties.
despite this, I did try some tests, and as far as I can tell, you can't do this.
After some trial and error I managed to pass an object via command line like this:
--properties ^~^labels:{'testlabel1: testlabel1value','testlabel2: testlabel2value'}~environmentVariables:{'TEST: zzzzzzzzz'}
This sequence of symbols ^~^ is how you can change delimiter. You have to put it at the beginning of your properties. More info about escaping you can find here.
I put single apostrophe over single key value pair because we need that space between key and value. Otherwise it's interpereted as key with null value.
If you're using Bash shell you should also escape {,} symbols.

Resources