Concatenating variable and regexp expression in Puppet - regex

Is it possible at all? My use case is setting wildcard domain's docroot. I have a variable
$docroot = "/var/www"
and, inside apache::vhost {} I'm trying to set
virtual_docroot' => "{$docroot}/%-2+",
That however throws an error saying:
Error: Could not parse for environment production: Syntax error at ' => "$docroot/%-2+",
docroot => $docroot,
serveraliases => ['; expected '}' at /tmp/vagrant-puppet-1/manifests/init.pp:22 on node localhost
My guess is that the whole expression is treated as a regexp, and $ treated as a part of the whole expression. Hence my doubts whether that's possible at all.

The answer turns out to be an orphaned apostrophe, misplaced after virtual_docroot, and copied from puppetlabs-apache documentation, where the faulty code is:
apache::vhost { 'subdomain.loc':
vhost_name => '*',
port => '80',
virtual_docroot' => '/var/www/%-2+',
docroot => '/var/www',
serveraliases => ['*.loc',],
}
Removing the apostrophe fixed the problem. Answer to my question is to set that particular configuration line as:
virtual_docroot => "$docroot/%-2+",
Notice the omitted {} characters.

Related

Laravel - regex route match everything but not exactly one or more word

I make a route like
Route::get('/{url1}', function ($url1) {
return ' url1: '.$url1;
})
->where('url1', '^(?!(string1|string2)$)');
and access url like:
- domain/abc not found => incorrect ??
- domain/string1 not found => correct
and more, when i do with
Route::get('/{url1}/{url2}', function ($url1) {
return ' url1: '.$url1;
})
->where('url1', '^(?!(string1|string2)$)');
and access url like:
- domain/abc/abc not found => incorrect ???
- domain/string1/abc not found => correct
How to fix that thank
Please try with this
for 1st scenario:
Route::get('/{url1}', function ($url1) {
return ' url1: '.$url1;
})->where('url1', '^!(string1|string2)$');
for 2nd scenario:
Route::get('/{url1}/{url2}', function ($url1, $url2) {
return ' url1: '.$url1 . ' url2: '.$url2;
})->where('url1', '^!(string1|string2)$');
i hope this help :)
Try this
Route::get('{url1}', function ($url1) {
return ' url1: '.$url1;
})->where('url1','^(?!string1$|string2$)([a-zA-Z0-9-]+)');
Unclean way to achieve this
Route::get('{url1}/{url2?}', function ($url1,$url2 = null) {
if ($url2 == "string1" || $url2 == "string2" || $url1 == "string1" || $url1 == "string2") {
return "false";
} else {
return "true";
}
});
One more way I have tried in by using RouteServiceProvider.php
Change your boot() like this.
public function boot()
{
//
Route::pattern('url1', '^(?!string1$|string2$)([a-zA-Z0-9-]+)');
Route::pattern('url2', '^(?!string1$|string2$)([a-zA-Z0-9-]+)');
parent::boot();
}
After tests I think it's impossible to achieve exactly what you want. It seems when you want to exclude string1 and string2 you need to agree that also strings starting with string1 and string2 will be excluded (so for example string1aaa).
When using such routes:
Route::get('/{url1}', function ($url1) {
return ' url1: '.$url1;
})->where('url1', '(?!string1|string2)[^\/]+');
Route::get('/{url1}/{url2}', function ($url1, $url2) {
return ' url1: '.$url1. ' # '.$url2;
})->where('url1', '(?!string1|string2)[^\/]+');
result will be:
domain/abc - found, correct
domain/string1 - not found, correct
domain/abc/abc - found, correct
domain/string1/abc - not found, correct
domain/string1aaa - not found, I believe you need to accept this
domain/string1aaa/abc - not found, I believe you need to accept this
I believe such limitation comes from Laravel and not from regex. If you need to accept also parameters starting with string1 and string2 I believe you need to do it in manual way like so:
Route::get('/{url1}', function ($url1) {
if (!preg_match('#^(?!string1$|string2$)[^\/]*$#', $url1)) {
abort(404);
}
return ' url1: '.$url1;
});
Route::get('/{url1}/{url2}', function ($url1, $url2) {
if (!preg_match('#^(?!string1$|string2$)[^\/]*$#', $url1)) {
abort(404);
}
return ' url1: '.$url1. ' # '.$url2;
});
Try this regex:
Route::get('/{url1}', function ($url1) {
return 'url: '.url1;
})->where('url1', '^(?!(string1|string2)$)(\S+)');
Rather than writing a route to match anything other than certain static strings, I find it clearer to write two routes: one route to match certain static strings, and another route to match everything else.
// route that matches forbidden static strings, optionally with a postfix slug
$router->get('/{forbidden}/{optional_path?}', function () {
return response('Not found', 404);
})->where([ 'forbidden' => '(?:string1|string2)', 'optional_path' => '.*' ]);
// route that matches anything else (order of definition matters, must be last)
// might also consider using Route::fallback(), but I prefer to leave that
// alone in case my future self changes this below and opens up a hole
$router->get('/{anything?}', function () {
return response('Found', 200);
})->where([ 'anything' => '.*' ]);
Which results in*:
domain => 200 Found
domain/ => 200 Found
domain/abc => 200 Found
domain/string1 => 404 Not found
domain/string1/ => 404 Not found
domain/string1/abc => 404 Not found
domain/string10 => 200 Found
domain/string10/ => 200 Found
domain/string10/abc => 200 Found
domain/string2 => 404 Not found
domain/string2/ => 404 Not found
domain/string2/abc => 404 Not found
domain/string20 => 200 Found
domain/string20/ => 200 Found
domain/string20/abc => 200 Found
I find this more clear, because I don't have to think in terms of exclusions. Rather, I can think of matching exactly what I want to forbid, then letting Laravel react to everything else (fail open policy). This may not meet your design criteria, but I do believe it results in clearer code.
Also, the code is more performant. ?! has to backtrack, which is by definition more expensive than forward matching.
I don't have a Laravel environment to hand, but I'll hazard a guess as to why your attempts didn't work. Laravel uses Symfony Router, which does not support lookarounds on slugs. IIRC, when a lookaround's detected, Symfony applies the lookaround to the entire URL, not the slug you've bound the pattern to. This messes with the developer's idea of how anchors (^, $) and greedy (*) meta characters work. This can lead to a bad experience in trying to get it to work, since the developer's operating under one assumption but the underlying libraries operating on another.
* Full disclosure, I wrote this for Lumen then mentally converted it to Laravel format. It's possible there are some translation errors. Here's the original Lumen:
$router->get('/{forbidden:(?:string1|string2)}[/{optional_path:.*}]', function () {
return response('Not found', 404);
});
$router->get('{anything:.*}', function () {
return response('Found', 200);
});

Concatenate strings in file_line resource

I'm trying to concatenate a string in a puppet manifest like so:
file_line {'Append to /etc/hosts':
ensure => present,
line => "${networking['ip'] + '\t'}${networking['fqdn'] + '\t'}${networking['hostname']}",
match => "${'^#?'+ networking['ip'] + '\s+' + networking['fqdn'] + '\s+' + networking['hostname']}",
path => '/etc/hosts'
}
I either get syntax errors or in the case above:
The value '' cannot be converted to Numeric
Which I'm guessing means that it doesn't like the plus operator.
So how do I interpolate the strings in the match and line attributes?
The problem here is that the operator + is restricted to only Numeric types (documentation). It cannot be used with String types. However, the spacing and regular expressions can still be used as normal without attempting a string concatenate. These merely need to be placed outside the variable interpolation. Therefore:
file_line { 'Append to /etc/hosts':
ensure => present,
line => "${networking['ip']}\t${networking['fqdn']}\t${networking['hostname']}",
match => "^#?${networking['ip']}\s+${networking['fqdn']}\s+${networking['hostname']}",
path => '/etc/hosts'
}
should resolve your issues with the type mismatch and the + operator.
i know you already got your answer, but you can make life easier using host to manage /etc/hosts:
host {
"localhost": ip => "127.0.0.1";
"$::puppet_server":
ip => "1.2.3.4",
host_aliases => [ "puppetserver" ],
;
"dns-01.tld":
ip => "1.2.3.5",
host_aliases => [ "dns-01" ],
;
"dns-02.tld":
ip => "1.2.3.6",
host_aliases => [ "dns-02" ],
;
}

Logstash config-file don't catch my logs, but debugger did

So, I'm a little bit new at the elk-stack, and I’m having an issue with further experiment with the tools. I'm using a linux machine.
First of all, here's my config-file :
input {
file {
type => "openerp"
path => "/home/jvc/Documents/log/openerp-cron.log.2014-11-20.txt"
start_position => "beginning"
codec => multiline{
pattern => "^%{TIMESTAMP_ISO8601} "
negate => true
what => previous
}
}
}
filter{
if [type]=="openerp"{
date{
match => ["timestamp","yyyy-MM-dd HH:mm:ss,SSS"]
}
grok{
patterns_dir => "./patterns"
match => { "message" => "%{ODOOLOG}" }
}
}
}
output{
file{
path => "/home/jvc/Bureau/testretour.txt"
}
}
I have some patterns too :
REQUESTTIMESTAMP %{MONTHDAY}/%{MONTH}/%{YEAR} %{TIME}
REQUEST %{IPORHOST:client} %{USER:ident} %{USER:auth} [%{REQUESTTIMESTAMP:request_timestamp}] "%{WORD:request_type} %{URIPATHPARAM:request} HTTP/%{NUMBER:httpversion}" %{NUMBER:response} -
ODOOMISC %{GREEDYDATA}
ODOOLOG %{TIMESTAMP_ISO8601:timestamp} %{POSINT:pid} %{LOGLEVEL:level} (?:%{USERNAME:user}|\?) %{PROG:module}: (?:%{REQUEST}|%{ODOOMISC:misc})
Some examples of the logs :
2014-11-21 08:00:16,715 17798 DEBUG noe openerp.addons.base.ir.ir_cron: cron.object.execute('noe', 1, '*', u'crossovered.budget.lines', u'computeblank')
2014-11-21 08:00:17,172 17798 WARNING noe openerp.osv.orm.browse_record.noe_utils.synchro_date: Field 'conform' does not exist in object 'browse_record(noe_utils.synchro_date, 13)'
2014-11-21 08:00:17,172 17798 ERROR noe openerp.sql_db: Programming error: can't adapt type 'browse_record', in query SELECT id
FROM crossovered_budget_lines
WHERE is_blank='t'
AND general_budget_id in %s
AND date_from <= %s AND date_to >= %s
2014-11-21 08:00:17,173 17798 ERROR noe openerp.addons.base.ir.ir_cron: Call of self.pool.get('crossovered.budget.lines').computeblank(cr, uid, *()) failed in Job 10
I'm having trouble with this config. For some reason that I can't find, this produces nothing.
What I have tried - done :
-First of all, I tested my grok, and multiline pattern in some grok debugger I have find on the web. All of them matches my logs.
-Before using the codec for multiline, i used the multiline filter. This one worked, but seems to be deprecated. So it's not a solution.
-I know that logstash keep in mind what he had read or not with the "sincedb" files : I delete these before every test, but you know what happens.
-I tried to run logstash with the -verbose, but nothing wrong is displayed.
-I don't really know if I must write the ".txt" at the end of my paths. But anyway, none of them works.
Have I missed something ? Thank you in advance for helping hands.
So, with more test i succeeded. I copied the content of one of my logs file and pasted it in another file : It works.
But, there is now another question : if deleting the "sincedb" file doesn't work, how can i "empty" the cache of logstash ?

Logstash can not handle multiple heterogeneous inputs

Let's say you have 2 very different types of logs such as FORTINET and NetASQ logs and you want:
grok FORTINET using a regex, ang grok NETASQ using an other regex.
I know that with "type"in the input file and "condition" in the filter we can resolve this problem.
So I used this confing file to do it :
input {
file {
type => "FORTINET"
path => "/fortinet/*.log"
sincedb_path=>"/logstash-autre_version/var/.sincedb"
start_position => 'beginning'
}
file {
type => "NETASQ"
path => "/home/netasq/*.log"
}
}
filter {
if [type] == "FORTINET" {
grok {
patterns_dir => "/logstash-autre_version/patterns"
match => [
"message" , "%{FORTINET}"
]
tag_on_failure => [ "failure_grok_exemple" ]
break_on_match => false
}
}
if [type] == "NETASQ" {
# .......
}
}
output {
elasticsearch {
cluster => "logstash"
}
}
And i'm getting this error :
Got error to send bulk of actions: no method 'type' for arguments(org.jruby.RubyArray) on Java::OrgElasticsearchActionIndex::IndexRequest {:level=>:error}
But if don't use "type" and i grok only FORTINET logs it wroks.
What should i do ?
I'm not sure about this but maybe it helps:
I have the same error and I think that it is caused by the use of these if statements:
if [type] == "FORTINET"
your type field is compared to "FORTINET" but this is maybe not possible because "FORTINET" is a string and type isn't. Some times by setting a type to an input, if there is already a type, the type isn't replaced, but the new type is added to a list with the old type. You should have a look to your data in kibana (or wherever) and try to find something like this:
\"type\":[\"FORTINET\",\"some-other-type\"]
maybe also without all those \" .
If you find something like this try not to set the type of your input explicitly and compare the type in your if-statement to the some-other-type you have found.
Hope this works (I'm working with more complex inputs/forwarders and for me it doesn't, but it is worth a try)

rails/VCR gem, same URI different method clash

My VCR configure block is:
VCR.configure do |c|
c.cassette_library_dir = 'spec/fixtures/vcr_cassettes'
c.hook_into :webmock
c.around_http_request(lambda { |req| req.uri =~ /google.com/ }) do |request|
VCR.use_cassette(request.uri, :decode_compressed_response => true, &request)
end
end
My tests work fine for post/get/put methods but when I try to DELETE, there is a clash in VCR because it matches with a previous PUT request. This is because the URI for that request is the same as the one needed for the DELETE request.
How do I change my use_cassette method so that it uses a combination of URI + method? (or any other suggestion also welcome!)
Thanks!
Solved it, this might help others, so leaving it here:
VCR.use_cassette([request.uri,request.method].join.to_s, :match_requests_on => [:method, :uri], :decode_compressed_response => true, &request)