I'm trying to modify the <config-profile> section of a ossc.conf file, including a grains content.
something like:
ossec-profiles:
- profile1
- profile2
and I want to modify the section <config-profile> from
<config-profile>centos, centos7</config-profile>
to
<config-profile>centos, centos7, profile1, profile2</config-profile>
in the ossec.conf file
Any idea?
This can be done by using file.replace module which makes you able to change a text in a file based on a pattern. So in your case you can do the following:
You need to select the pattern as regex group so you can use it later as shown below
configure_ossec:
file.replace:
- name: /path/to/ossec.conf
- pattern: '((<config-profile>.*?)[^<]*)'
- repl: {{ '\\1, ' + pillar['ossec-profiles'] | join(', ') }}
Or you might use this pattern to match only whatever inside config-profile tags then you will be able to call it again in the repl parameter:
(?<=<config-profile>)(.*)(?=<\/config-profile>)
Note: As pillar['ossec-profiles'] should return a list of profiles
then you have to use the join filter in order to separate the values
with comma as a delimiter
And finally the output expected to be something like this:
Changes:
----------
diff:
---
+++
## -1 +1 ##
-<config-profile>centos, centos7</config-profile>
+<config-profile>centos, centos7, profile1, profile2</config-profile>
Related
I have error with scan function, why?
https://jqplay.org/s/E-0qbbzRPS
I need do this without -r
There are two issues with your filter. Firstly, you need to separate parameters to a function with semicolon ;, not comma ,:
scan("([0-9A-Za-z_]+) == '([0-9A-Za-z_]+)"; "g")
Secondly, scan with two parameters is not implemented (in contradiction to the manual).
jq: error: scan/2 is not defined at <top-level>, line 1:
But as you are using scan, your regex will match multiple occurrences anyway, so you may as well just drop it :
.spec.selector | [scan("([0-9A-Za-z_]+) == '([0-9A-Za-z_]+)") | {(.[0]): .[1]}]
[
{
"app": "nginx"
}
]
Demo
Bash script find a a tags in ECR repo:
aws ecr describe-images --repository-name laplacelab-backend-repo
\ --query 'sort_by(imageDetails,& imagePushedAt)[*]'
\--output json | jq -r '.[].imageTags'
Output:
[
"v1",
"sometag",
...
]
How I can extract the version number? v<number> can contain the only version tag. I need to get a number and increment version for the set to var. If output of sort_by(imageDetails,& imagePushedAt)[*] is empty JSON arr instead
[
{
"registryId": "057296704062",
"repositoryName": "laplacelab-backend-repo",
"imageDigest": "sha256:c14685cf0be7bf7ab1b42f529ca13fe2e9ce00030427d8122928bf2d46063bb7",
"imageTags": [
"v1"
],
"imageSizeInBytes": 351676915,
"imagePushedAt": 1593514683.0
}
]
Set 2
No one repo sort_by(imageDetails,& imagePushedAt)[*] return [] set 1.
As a result, I try to get var VERSION with next version for an update or 1 if the repo is empty.
You could use the select() function on the imageTags array and get only the tag starting with v and increment it.
jq '( .[].imageTags[] | select(startswith("v")) | ltrimstr("v") | tonumber | .+1 ) // 1'
For other cases like the tags array being empty or containing null strings (error case), the value defaults to 1
For storing into the variable e.g. say version (avoid using uppercase variable names from a user scripts), use command substitution. See How do I set a variable to the output of a command in Bash?
version=$( <your-pipeline> )
Note: This does not work well with version strings following Semantic versioning RFC, e.g. as v1.2.1 as jq does not have a library to parse them.
Sorry if this is included somewhere, looked for a good 30-60 minutes for something along these lines. I am sure I just missed something! Total jq nub!
Basically I am trying to do a pick operation that is dynamic. My thought process was to do something like this:
pickJSON() {
getSomeJSON | jq -r --arg PICK "$1" '{ $PICK }'
}
pickJSON "foo, bar"
but this produces
{ "PICK": "foo, bar" }
Is there a way to essentially ask it to expand shell-style?
Desired Result:
pickJSON() {
getSomeJSON | jq -r --arg PICK "$1" '{ $PICK }'
# perhaps something like...
# getSomeJSON | jq -r --arg PICK "$1" '{ ...$PICK }'
}
pickJSON "foo, bar"
{ "foo": "foovalue", "bar": "barvalue" }
Note that I am new to jq and i just simplified what i am doing - if the syntax is broken that is why :-D my actual implementaiton has a few pipes in there and it does work if i dont try to pick the values out of it.
After a fairly long experimentation phase trying to make this work, I finally came up with what seems like a feasible and reliable solution without the extremely unsettling flaws that could come from utilizing eval.
To better highlight the overall final solution, I am providing a bit more of the handling that I am currently working with below:
Goal
Grab a secret from AWS Secrets Manager
Parse the returned JSON, which looks like this:
{
"ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3",
"Name": "MyTestDatabaseSecret",
"VersionId": "EXAMPLE1-90ab-cdef-fedc-ba987EXAMPLE",
"SecretString": "{\n \"username\":\"david\",\n \"password\":\"BnQw&XDWgaEeT9XGTT29\"\n}\n",
"VersionStages": [
"AWSPREVIOUS"
],
"CreatedDate": 1523477145.713
}
Run some modifications on the JSON string received and pick only the statically requested keys from the secret
Set and export those values as environment variables
Script
# Capture a AWS Secret from secretsmanager, parse the JSON and expand the given
# variables within it to pick them from the secret and return given portion of
# the secret requested.
# #note similar to _.pick(obj, ["foo", "bar"])
getKeysFromSecret() {
aws secretsmanager get-secret-value --secret-id "$1" \
| jq -r '.SecretString | fromjson' \
| jq -r "{ $2 }"
}
# Uses `getKeysFromSecret` to capture the requested keys from the secret
# then transforms the JSON into a string that we can read and loop through
# to set each resulting value as an exported environment variable.
#
## Transformation Flow:
# { "foo": "bar", "baz": "qux" }
# -->
# foo=bar
# baz=qux
# -->
# export foo=bar
# export baz=qux
exportVariablesInSecret() {
while IFS== read -r key value; do
if [ -n "$value" ]; then
export "${key}"="${value}";
fi
done < <(getKeysFromSecret "$1" "$2" | jq -r 'to_entries | .[] | .key + "=" + .value')
}
Example JSON
{
...othervalues
"SecretString": "{\"foo\": \"bar\", \"baz\": \"qux\"}"
}
Example Usage
exportVariablesInSecret MY_SECRET "foo, bar"
echo $foo
# bar
Some Notes / Context
This is meant to set a given set of values as variables so that we aren't just setting an entire arbitrary JSON object as variables that could possibly cause issues / shadowing if someone adds a value like "path" to a secret
A critical goal was to absolutely never use eval to prevent possible injection situations. Far too easy to inject things otherwise.
Happy to see if anyone has a nicer way of accomplishing this. I saw many people recommending the use of declare but that sets the var to the local function scope only so its essentially useless.
Thanks to #cas https://unix.stackexchange.com/a/413917/308550 for getting me on the right track!
I've run into an issue I havent been able to solve:
I have a file(/etc/osci) that I use on all of my servers as an name for our monitoring(zabbix)
I've created a state file that pushes a template configuration file to the server and and reads the content of /etc/osci to a variable. The next step would be to use that same variable with 'file.replace' function to search for a string and replace it with the variable.
uusnimi=$(cat /etc/osci):
cmd.run
/etc/zabbix_agentd.conf:
file.managed:
- source: salt://base/streamingconf/zabbix/zabbix_agentd.conf
- mode: 644
change_hostname_zabbix:
file.replace:
- name: /etc/zabbix_agentd.conf
- pattern: 'Hostname='
- repl: 'Hostname=$uusnimi'
Now when executing the state file echoing the variable in the target server it provides me the right output:
echo $uusnimi
Server1
but for the life of me I can't figure out how to escape the last line of the above code so it would insert the value not the '$uusnimi' string
Use uusnimi as a jinja variable.
{% set uusnimi = salt['cmd.shell']('cat /etc/osci') %}
/etc/zabbix_agentd.conf:
file.managed:
- source: salt://base/streamingconf/zabbix/zabbix_agentd.conf
- mode: 644
change_hostname_zabbix:
file.replace:
- name: /etc/zabbix_agentd.conf
- pattern: 'Hostname='
- repl: 'Hostname={{ uusnimi }}'
Doug McCune had created something that was exactly what I needed (http://dougmccune.com/blog/2007/05/10/analyze-your-actionscript-code-with-this-apollo-app/) but alas - it was for AIR beta 2. I just would like some tool that I can run that would provide some decent metrics...any idea's?
There is a Code Metrics Explorer in the Enterprise Flex Plug-in below:
http://www.deitte.com/archives/2008/09/flex_builder_pl.htm
Simple tool called LocMetrics can work for .as files too...
Or
find . -name '*.as' -or -name '*.mxml' | xargs wc -l
Or if you use zsh
wc -l **/*.{as,mxml}
It won't give you what fraction of those lines are comments, or blank lines, but if you're only interested in how one project differs from another and you've written them both, it's a useful metric.
Here's a small script I wrote for finding the total numbers of occurrence for different source code elements in ActionScript 3 code (this is written in Python simply because I'm familiar with it, while Perl would probably be better suited for a regex-heavy script like this):
#!/usr/bin/python
import sys, os, re
# might want to improve on the regexes used here
codeElements = {
'package':{
'regex':re.compile('^\s*[(private|public|static)\s]*package\s+([A-Za-z0-9_.]+)\s*', re.MULTILINE),
'numFound':0
},
'class':{
'regex':re.compile('^\s*[(private|public|static|dynamic|final|internal|(\[Bindable\]))\s]*class\s', re.MULTILINE),
'numFound':0
},
'interface':{
'regex':re.compile('^\s*[(private|public|static|dynamic|final|internal)\s]*interface\s', re.MULTILINE),
'numFound':0
},
'function':{
'regex':re.compile('^\s*[(private|public|static|protected|internal|final|override)\s]*function\s', re.MULTILINE),
'numFound':0
},
'member variable':{
'regex':re.compile('^\s*[(private|public|static|protected|internal|(\[Bindable\]))\s]*var\s+([A-Za-z0-9_]+)(\s*\\:\s*([A-Za-z0-9_]+))*\s*', re.MULTILINE),
'numFound':0
},
'todo note':{
'regex':re.compile('[*\s/][Tt][Oo]\s?[Dd][Oo][\s\-:_/]', re.MULTILINE),
'numFound':0
}
}
totalLinesOfCode = 0
filePaths = []
for i in range(1,len(sys.argv)):
if os.path.exists(sys.argv[i]):
filePaths.append(sys.argv[i])
for filePath in filePaths:
thisFile = open(filePath,'r')
thisFileContents = thisFile.read()
thisFile.close()
totalLinesOfCode = totalLinesOfCode + len(thisFileContents.splitlines())
for codeElementName in codeElements:
matchSubStrList = codeElements[codeElementName]['regex'].findall(thisFileContents)
codeElements[codeElementName]['numFound'] = codeElements[codeElementName]['numFound'] + len(matchSubStrList)
for codeElementName in codeElements:
print str(codeElements[codeElementName]['numFound']) + ' instances of element "'+codeElementName+'" found'
print '---'
print str(totalLinesOfCode) + ' total lines of code'
print ''
Pass paths to all of the source code files in your project as arguments for this script to get it to process all of them and report the totals.
A command like this:
find /path/to/project/root/ -name "*.as" -or -name "*.mxml" | xargs /path/to/script
Will output something like this:
1589 instances of element "function" found
147 instances of element "package" found
58 instances of element "todo note" found
13 instances of element "interface" found
2033 instances of element "member variable" found
156 instances of element "class" found
---
40822 total lines of code
CLOC - http://cloc.sourceforge.net/. Even though it is Windows commandline based, it works with AS3.0, has all the features you would want, and is well-documented. Here is the BAT file setup I am using:
REM =====================
echo off
cls
REM set variables
set ASDir=C:\root\directory\of\your\AS3\code\
REM run the program
REM See docs for different output formats.
cloc-1.09.exe --by-file-by-lang --force-lang="ActionScript",as --exclude_dir=.svn --ignored=ignoredFiles.txt --report-file=totalLOC.txt %ASDir%
REM show the output
totalLOC.txt
REM end
pause
REM =====================
To get a rough estimate, you could always run find . -type f -exec cat {} \; | wc -l in the project directory if you're using Mac OS X.