Puppet - remove ini_setting completely - puppet

I am using puppet 4.5.3 and ini_setting module version 1.4.2. I need to be able to remove a stanza in an ini file. For example:
[header]
ip = '1.1.1.1'
hostname = 'myserver'
port = 80
I am able to remove each section of the ini file using the ensure => absent parameter but I cannot find a way to remove the stanza header, or preferably the whole thing in one command.
What I have left is
[header]
Does anyone know how this can be done? Unfortunately there are other stanzas in the same file that I need to keep so I cannot simply delete the file.
thanks,

Using the Augeas type:
augeas { 'remove_ini_header':
incl => '/etc/example.ini',
lens => 'IniFile.lns_loose',
changes => 'rm section[. = "header"]',
}
To break this down a bit, first I used the built-in IniFile.lns_loose lens (i.e. a "generic" loose parsing of INI files) and augtool to see the current state of the tree:
$ augtool -t "IniFile.lns_loose incl /etc/example.ini"
augtool> print /files/etc/example.ini
/files/etc/example.ini
/files/etc/example.ini/section = "header"
/files/etc/example.ini/section/ip = "'1.1.1.1'"
/files/etc/example.ini/section/hostname = "'myserver'"
/files/etc/example.ini/section/port = "80"
The entire section is in one part of the tree, so calling rm for that section will delete the entire subtree.
To match the header section, you need to search for nodes called section where the value (the right hand side) is header. The [. = "header"] part of the command is a path expression that filters for nodes with the value header.

Related

Values in a .ini file

I have a pyramid app and am looking at the .ini file. What is the difference between using paypal.client_id -v- paypal_client_id Does the . signify something specific, for example that reload is a part of pyramid?
If I have a lot of configurations regarding vehicles for example should I use vehicles.limit or vehicles_limit?
[app:main]
use = egg:vehiclesvc
pyramid.reload_templates = true
pyramid.debug_notfound = false
pyramid.debug_routematch = false
pyramid.default_locale_name = en
paypal.client_id = 1412431231
paypal.secret_key = asdasdasdasd
or
[app:main]
use = egg:vehiclesvc
pyramid.reload_templates = true
pyramid.debug_notfound = false
pyramid.debug_routematch = false
pyramid.default_locale_name = en
paypal_client_id = 1412431231
paypal_secret_key = asdasdasdasd
I do not see an instance of either pyramid.reload -v- pyramid_reload in your .ini file. Nonetheless, there are certain setting names that are reserved for Pyramid use, as documented in Environment Variables and .ini File Settings.
For those setting names reserved by Pyramid, pyramid.<setting_name> and <setting_name> are equivalent.
All other setting names, including those you define, may be used elsewhere in configuring your application. Again see the referenced linked documentation for details.
See also ConfigParser's documentation on Supported INI File Structure.
A configuration file consists of sections, each led by a [section] header, followed by key/value entries separated by a specific string (= or : by default).
Finally to answer you explicit question, pyramid.reload -v- pyramid_reload would be both distinct and not reserved by Pyramid. Similarly vehicles.limit and vehicles_limit would be both distinct key names and not reserved by Pyramid. By convention it is helpful to use <python_package>. to designate a Python package where the key name is used.

How to get non standard tags in rpm query

I wanted to add things such as Size, BuildHost, BuildDate etc in rpm query but adding this thing in spec file results in unknown tag?? How can I do this so that these things are reflected when i give the rpm query command?
These tags are determined when the package is built; they cannot be forced to specific values.
For example BuildHost is hardcoded in rpmbuild and cannot be changed. There is RFE https://bugzilla.redhat.com/show_bug.cgi?id=1309367 to allow it modify from command line. But right now you cannot change it by any tag in spec file nor by passing some option on command line to rpmbuild.
I assume it will be very similar to other values you specified.
RPM5 permits arbitrary unique tag names to be added to header metadata.
The tag names are configured in a colon separated list in a macro. Then the new tags can be used in spec files and can be extracted using --queryformat.
All arbitrary tags are string (or string array) valued.

How to edit a file and pass values into it through Puppet

I want to pass limit values in /etc/security/limits.conf in all servers available in environment through puppet. Need to be automated this process whenever i create new instance, this limit values directly append to new boxes
There's an official puppet module for modifying limits.
You could also use file_line for this.
file_line { 'append_limits_conf':
path => '/etc/security/limits.conf',
match => 'variable_name',
line => 'vriable_name = foobar',
}
The match will be used to determine if the variable is already declared within the file. If yes - it will change the value to whatever you define at line. If it's not in there it will just append the line.
More sophisticated file editing can be done with augeas - but might be overkill for you case right now.

Puppet: Can $hostname be checked against a master file before running manifest head?

I've seen someone doing a check on whether an agent's MAC address is on a specific regular expression before it runs the specified stuff below. The example is something like this:
if $is_virtual == "true" and $kernel == "Linux" and $macaddress =~ /^02:00:0A/ {
include nmonitor
include rootsh
include checkmk-agent
include backuppcacc
include onecontext
include sysstatpkg
include ensurekvmsudo
include cronntpdate
}
That's just it in that particular manifest file. Similarly another manifest example but via regular expression below:
node /^mi-cloud-(dev|stg|prd)-host/ {
if $is_virtual == 'false' {
include etchosts
include checkmk-agent
include nmonitor
include rootsh
include sysstatpkg
include cronntpdate
include fstab-ds-dev
}
}
I've been asked of whether can that similar concept be applied upon checking the agent's hostname with a master file of hostnames allowed to be run or otherwise.
I am not sure whether it can be done, but the rough idea goes around something like:
file { 'hostmasterfile.ini'
ensure => present,
source => puppet:///test/hostmaster.ini,
content => $hostname
}
$coname = content
#Usually the start / head of the manifest
if $hostname == $coname {
include <a>
include <b>
}
Note: $fqdn is out of the question.
To my knowledge, I have not seen any such sample manifest that matches the request. Whats more, it goes against a standard practice of keeping things easier to manage and not putting all eggs in a basket.
An ex-colleague of mine claims that idea above is about self-provisioning. However that concept is non-existent in Puppet (he posed that question at a workshop a few months back). I am not sure how true is that though.
If that thing above can be done, any suggestion of how can it be done? Or is it best to go back to the standard one manifest per node for easy maintenance?
Thanks very much.
M
Well, you can replace your node blocks with if constructs.
if $hostname == 'host1' {
# manifest for host1 here
}
You can combine this with some sort of inifile (e.g., using the generate) function. If the <a> and <b> for the include statements are then fetched from your ini file as well, you have constructed a crude ENC.
Note that this has security implications - any agent can claim to have any host name. It's even very simple to do:
FACTER_hostname=kerberos01 puppet agent --test
Any node can receive the catalog for kerberos01 this way. (node blocks rely on $certname instead, which cannot be forged.)
I could not decipher your precise intent from your question, but I suspect that you really want an ENC or a Hiera based approach.
Edit after feedback from your first comment:
To make the master read contents from local files, you should
get rid of the file { 'hostmasterfile.ini': } - it only allows you to set contents, not retrieve them
initialize the variable content using the file function (this will make all nodes fail if the file is not readable)
The code could look like this (assuming that there can be multiple host names in the ini file).
$ini_data = file('/etc/puppet/files/test/hostmaster.ini')
Next step would be a regex lookup like this:
if $ini_data =~ /name=$hostname/ {
Unfortunately, this does not work! Puppet will not expand variable values in regular expressions, apparently.
You can use this (kind of silly) workaround:
$ini_lookup = regsubst($ini_data, "name=$hostname", '__FOUND__')
if $ini_lookup =~ /__FOUND__/ {
...
}
Final remark about security: If your team is adamant about not using $certname for this lookup (although it should be easy to map host names to cert names), you should consider adding the host name to your trusted facts.

How to edit multiple file names at once?

I have directory full of .txt files (2000 files). they have very long name. I want to edit their name and just keep certain letter from inside of their name as file name.
like this :
UNCID_279113.TCGA-A6-2683-01A-01R-0821-07.100902_UNC7-RDR3001641_00025_FC_62EPOAAXX.1.trimmed.annotated.gene.quantification.txt
I want eliminate this long names and just keep the name starting from TCGA and ending after three - ; for example, my new file name would be : TCGA-A6-2683-01A
does anybody knows how can I do this for whole files in one directory?
Assuming the files are in the current directory:
library(gsubfn)
pat <- "TCGA-[^-]*-[^-]*-[^-]*"
file.names <- dir(pattern = pat)
new.names <- strapplyc(file.names, pat, simplify = TRUE)
file.rename(file.names, new.names)
Create a shell/batch script Here is a variation. It produces a UNIX shell file or a Windows batch file. You can then review the file and run it:
# UNIX
writeLines(paste("mv", file.names, new.names), con = "tcga_rename.sh")
shell("tcga_rename.sh")
or on Windows:
# Windows
writeLines(paste("rename", file.names, new.names), con = "tcga_rename.bat")
shell("tcga_rename.bat")
REVISED: Factored out pat, simplified and added variations.
Assuming your files are in the current working directory, try
library(stringr)
files <- list.files(".", pattern=".txt")
file.rename(files, str_extract(files, "TCGA(-\\w+){3}"))
You can do something like this:
pattern <- ".*(TCGA-[^-]+-[^-]+-[^-]*).*"
file.rename(
list.files("."),
sub(pattern, "\\1", list.files("."))
)
But be super careful that the sub command does what you think it will do before you run the full thing (i.e. just run the sub piece). Hard to be sure this won't cause a problem without knowing what patterns you have in your file names.
Also, in this case replace list.files(".") with your directory. Note you don't need to filter our the files that match the pattern in the first place since sub will only modify the file names that do match the pattern (not super efficient if you have a lot of files that don't match the pattern, but easier to write, if a concern, you can use the pattern argument as Greg Snow does).
You cane use list.files() to get a list of the filenames in the directory, then use substitute with regular expressions to edit the names, then file.rename to actually do the renaming.
Something like (untested):
curfiles <- list.files(pattern='TCGA') # only grab files with TCGA in them
newfiles <- sub("^.*(TCGA-[a-zA-z0-9]+-[a-zA-Z0-9]+-[a-zA-Z0-9]+).*$", "\\1", curfiles)
file.rename(curfiles,newfiles)

Resources