I'm currently adding filebeat support for services we provide;
For every service we have several log files I would like to track;
I have 1 common filebeat recipe and I'm distinguishing between the different services' logs in different attributes .rb files;
In those I have a separate definition per log;
All definitions have the same "fileds" configuration;
Can I add it to someplace to be used by all configurations?
My structure:
cookbooks
common
recipes
filebeat.rb
services
attributes
service1.rb
service2.rb
The content of servicesX.rb has the following definitions:
access_log = {
'paths' => ['TBD'],
'input_type' => 'log',
'fields' => {
'hostname' => node["opsworks"]["instance"]["hostname"],
'customer' => node["opsworks"]["instance"]["layers"][0],
'internal_ip' => node["opsworks"]["instance"]["private_ip"],
'ec2id' => node["opsworks"]["instance"]["aws_instance_id"],
'os' => node["opsworks"]["instance"]["os"],
'instance_type' => node["opsworks"]["instance"]["instance_type"] },
'fields_under_root' => true
}
audit_log = {
'paths' => ['TBD'],
'input_type' => 'log',
'fields' => {
'hostname' => node["opsworks"]["instance"]["hostname"],
'customer' => node["opsworks"]["instance"]["layers"][0],
'internal_ip' => node["opsworks"]["instance"]["private_ip"],
'ec2id' => node["opsworks"]["instance"]["aws_instance_id"],
'os' => node["opsworks"]["instance"]["os"],
'instance_type' => node["opsworks"]["instance"]["instance_type"]
},
'fields_under_root' => true
}
How can I extract
'fields' => {
'hostname' => node["opsworks"]["instance"]["hostname"],
'customer' => node["opsworks"]["instance"]["layers"][0],
'internal_ip' => node["opsworks"]["instance"]["private_ip"],
'ec2id' => node["opsworks"]["instance"]["aws_instance_id"],
'os' => node["opsworks"]["instance"]["os"],
'instance_type' => node["opsworks"]["instance"]["instance_type"]
Someplace in the same file (servicesX.rb) so to be used by all log files definitions?
Note: I'm a ruby novice :/
Thank you!!
After feedback and clarification in comments below, OP seems to want to DRY the code and re-use a fields definition.
Simplest is to store it in a variable and then use that:
fields = {
'hostname' => node["opsworks"]["instance"]["hostname"],
'customer' => node["opsworks"]["instance"]["layers"][0],
'internal_ip' => node["opsworks"]["instance"]["private_ip"],
'ec2id' => node["opsworks"]["instance"]["aws_instance_id"],
'os' => node["opsworks"]["instance"]["os"],
'instance_type' => node["opsworks"]["instance"]["instance_type"]
}
audit_log = {
'paths' => ['TBD'],
'input_type' => 'log',
'fields' => fields
}
This, however, may cause issues with how node is set. It really depends on the flow of the rest of your script. In chef (assuming this is about chef) a node is the context on which the script runs, so setting the fields too early might give issues when that node is used much later:
fields = { hostname: node["opsworks"]["instance"]["hostname"] }
# ... do lots of stuff, like fetching, preparing, connecting and whatnot.
fields # now contains the `node` values as set before connecting etc.
If this is an issue, a better option would be to define a method that returns the fields from a passed-in node:
def fields(node)
{
'hostname' => node["opsworks"]["instance"]["hostname"],
'customer' => node["opsworks"]["instance"]["layers"][0],
'internal_ip' => node["opsworks"]["instance"]["private_ip"],
'ec2id' => node["opsworks"]["instance"]["aws_instance_id"],
'os' => node["opsworks"]["instance"]["os"],
'instance_type' => node["opsworks"]["instance"]["instance_type"]
}
end
Or, cleaned up:
def fields(node)
instance = node["opsworks"]["instance"]
{
hostname: instance["hostname"],
customer: instance["layers"][0],
internal_ip: instance["private_ip"],
ec2id: instance["aws_instance_id"],
os: instance["os"],
instance_type: instance["instance_type"]
}
end
Then use that function:
audit_log = {
'paths' => ['TBD'],
'input_type' => 'log',
'fields' => fields(node)
}
After my research: The benefits of the implementation does not justify the time invested;
Leaving it;
Related
I have an incoming post data from js like this
[form] => Array (
[name] => 'a form'
[type] => 'form'
...
[children] => Array (
[0] =>
[1] =>
[2] => Array(
[title] => 'first'
[order] => '1'
...
}
[3] => Array(
[title] => 'second'
[order] => '2'
...
)
...
)
...
)
and rules like
[
'form.name' => 'required|string',
'form.type' => 'required|string',
...
'form.children.*.title' => 'requered|string'
'form.children.*.order' => 'requered|integer'
...
]
What is the best way to completely exclude/skip the form.children arrays that are empty and process the ones with data?
Try this:
[
'form.name' => 'required|string',
'form.type' => 'required|string',
...
'form.children.*.title' => 'sometimes|string'
'form.children.*.order' => 'sometimes|integer'
...
]
Sometimes means, if there is something, follow the next rule(s).
https://laravel.com/docs/8.x/validation#validating-when-present
Addition:
For more complex situations, f.ex. you are not interested in an order value if there is no title, makes sense right? Try this:
[
'form.name' => 'required|string',
'form.type' => 'required|string',
...
'form.children.*.title' => 'sometimes|string'
'form.children.*.order' => 'exclude_if:form.children.*.title,null|integer'
...
]
I have never tested/used this on arrays though.
I managed to completely remove the empty arrays just by filtering them out of the request with laravel's prepareForValidation() method and array_filter(). Worked great for me.
protected function prepareForValidation()
{
$this->merge([
"form" => [
"children" => array_filter($this->form["children"])
]
]);
}
#DimitriMostrey's answer worked as well. His answer is a shorter solution without an additional method. Will accept his answer so anyone facing a similar situation can pick the one that suits the most.
I'm pretty new at Ruby and I've been asked to help out on a program. For some reason for the life of me I can't get my syntax right. If the agent relationship is none?, I want to unshift both the 'series_system_agent_record_creation_by_agent_relationship' and 'series_system_agent_record_ownership_relationship'. I'm using the && in my code but it's not doing what I need it to do so any help would be much appreciated!
if whitelisted['agent_relationships'].none? {|r| r['jsonmodel_type'] == 'series_system_agent_record_creation_by_agent_relationship'}
whitelisted['agent_relationships'].unshift({
'jsonmodel_type' => 'series_system_agent_record_creation_by_agent_relationship',
'relationship_target_record_type' => 'agent_corporate_entity',
'ref' => json.creating_agency[0]['ref'],
'relator' => 'created_by',
'start_date' => json.creating_agency[0]['start_date'],
})
end
if whitelisted['agent_relationships'].none? {|r| r['jsonmodel_type'] == 'series_system_agent_record_ownership_relationship'}
whitelisted['agent_relationships'].unshift({
'jsonmodel_type' => 'series_system_agent_record_ownership_relationship',
'relationship_target_record_type' => 'agent_corporate_entity',
'ref' => json.responsible_agency['ref'],
'relator' => 'is_controlled_by',
'start_date' => json.responsible_agency['start_date'],
})
end
whitelisted['responsible_agency'] = json.responsible_agency
whitelisted['creating_agency'] = json.creating_agency
Sorry just a quick edit. To make sense of this the .none? is because I'm using an outdated version of Ruby for an older program. Not something I can change because it isn't my choice. To add I want to refactor this code. I know it already works. I've already tried a few ways and my head can't wrap my head around how to do it. Eg. I tried
if whitelisted['agent_relationships'].none? {|r| r['jsonmodel_type'] == 'series_system_agent_record_creation_by_agent_relationship' && 'series_system_agent_record_creation_by_agent_relationship'}
whitelisted['agent_relationships'].unshift({
'jsonmodel_type' => 'series_system_agent_record_creation_by_agent_relationship',
'relationship_target_record_type' => 'agent_corporate_entity',
'ref' => json.creating_agency[0]['ref'],
'relator' => 'created_by',
'start_date' => json.creating_agency[0]['start_date'],
} && {
'jsonmodel_type' => 'series_system_agent_record_creation_by_agent_relationship',
'relationship_target_record_type' => 'agent_corporate_entity',
'ref' => json.creating_agency[0]['ref'],
'relator' => 'created_by',
'start_date' => json.creating_agency[0]['start_date'],
}
)
end
whitelisted['responsible_agency'] = json.responsible_agency
whitelisted['creating_agency'] = json.creating_agency
Hello again! I've now also tried another method as well and I am not running into any errors however something seems to be wrong as this program is whitelisting relationships that can be passed to a react front end. Now none of the relationships are appearing on the react front end using the code below and although I am not running into any errors, it is still not working.
if whitelisted['agent_relationships'].none? {|r| r['jsonmodel_type'] == 'series_system_agent_record_ownership_relationship' && 'series_system_agent_record_creation_by_agent_relationship'}
[{
'jsonmodel_type' => 'series_system_agent_record_ownership_relationship',
'relationship_target_record_type' => 'agent_corporate_entity',
'ref' => json.responsible_agency['ref'],
'relator' => 'is_controlled_by',
'start_date' => json.responsible_agency['start_date'],
},{
'jsonmodel_type' => 'series_system_agent_record_creation_by_agent_relationship',
'relationship_target_record_type' => 'agent_corporate_entity',
'ref' => json.creating_agency[0]['ref'],
'relator' => 'created_by',
'start_date' => json.creating_agency[0]['start_date'],
},].each { |hsh| ['agent_relationships'].unshift(hsh) }
end
whitelisted['responsible_agency'] = json.responsible_agency
whitelisted['creating_agency'] = json.creating_agency
From what I understand from initial code you want to add series_system_agent_record_creation_by_agent_relationship default only if it's missing in whitelist. Same with series_system_agent_record_ownership_relationship - add only when it's missing.
However your refactoring tries to add both at a time.
Refactoring is usually a process when you refactor little bit and then it gives you idea what else can be refactored.
I would start with replacing long names.
One of the initial versions could be.
def whatever_the_name
# ...
unless has_agent_relationship_of_type?(whitelisted, 'series_system_agent_record_creation_by_agent_relationship')
creating_agency = json.creating_agency[0]
default_agent_relationship = {
'jsonmodel_type' => 'series_system_agent_record_creation_by_agent_relationship',
'relationship_target_record_type' => 'agent_corporate_entity',
'ref' => creating_agency['ref'],
'relator' => 'created_by',
'start_date' => creating_agency['start_date'],
}
whitelisted['agent_relationships'].unshift(default_agent_relationship)
end
unless has_agent_relationship_of_type?(whitelisted, 'series_system_agent_record_ownership_relationship')
responsible_agency = json.responsible_agency
default_agent_relationship = {
'jsonmodel_type' => 'series_system_agent_record_ownership_relationship',
'relationship_target_record_type' => 'agent_corporate_entity',
'ref' => responsible_agency['ref'],
'relator' => 'is_controlled_by',
'start_date' => responsible_agency['start_date'],
}
whitelisted['agent_relationships'].unshift(default_agent_relationship)
end
# ...
end
def has_agent_relationship_of_type?(whitelisted, type)
whitelisted['agent_relationships'].any? {|r| r['jsonmodel_type'] == type }
end
Of course, this shouldn't be considered the final refactored code. It all depends how far you want to get. But hopefully it helps.
I seem to be having a problem with 302 redirects using curb (Ruby's curl programs)
Here's the code snippet that is ** NOT working** (it's NOT doing the 302 redirect)
easy_options = {:follow_location => true, :enable_cookies => true, :useragent => 'curb', :cookiefile => 'cookie.txt'}
multi_options = {:pipeline => true}
url_fields = [
{
:url => 'https://x.y.z/webapps/login/',
:method => :post,
:follow_location => true,
:enable_cookies => true,
:useragent => 'curb',
:post_fields => {
'user_id' => 'xxxx',
'password' => 'xxxx',
'action' => 'login',
'encoded_pw' => Base64.strict_encode64('xxxx')},
}
]
Curl::Multi.http(url_fields,{:pipeline => true}) do |easy, code, method|
puts easy.header_str
end
Here's the code snippet that appears to be working (it's doing the 302 redirect)
easy_options = {:follow_location => true, :enable_cookies => true, :useragent => 'curb', :cookiefile => 'cookie.txt'}
multi_options = {:pipeline => true}
url_fields = [
{ :url => 'https://x.y.z/webapps/login/',
:post_fields => {
'user_id' => 'xxxx',
'password' => 'yyyy',
'action' => 'login',
'encoded_pw' => Base64.strict_encode64('yyyy')}}
]
Curl::Multi.post(url_fields, easy_options, multi_options) do|easy|
# do something interesting with the easy response
puts easy.last_effective_url
end
Question: Why is the first block not doing the 302 redirect as expected? :follow_location is set to true?
Thanks in advance!
Let me know if you need more information
Im using the gibbon 0.4.6 with ruby 1.9.3p392, and I tried to add the address of my contacts but I couldn't find the correct format of the parameters.
respuesta = gb.listSubscribe({
:id => lista_id, :email_address => email,
:merge_vars => {'FNAME' => nombre, 'LNAME' => apellido,
'MMERGE3' => ['addr1' => 'aqui', 'addr2' => 'Alla', 'city' => 'Mexico DF',
'zip' => '06700', 'country' => 'MX']
}
})
Update
As Amro suggested, now Im using Gibbon 1.0, but I have the same problem:
I used this
respuesta = gb.lists.subscribe({
:id => lista_id, :email => {:email => email},
:merge_vars => {'FNAME' => nombre, 'LNAME' => apellido,
'MMERGE3' => {'addr1' => 'aqui', 'addr2' => 'Alla', 'city' => 'Mexico DF', 'zip' => '06700', 'country' => 'MX'},
'MMERGE4' => 'Mi nota '
}
})
But the address(MMERGE3) wasn't registered at MailChimp.
Any idea is welcome.
Your current code looks reasonable to me. Have you tried also passing "update_existing" with a value of true? If that address is already subscribed then it won't work otherwise since "update_existing" defaults to false.
Old Answer for API 1.3
I'm Gibbon's maintainer. In this case, MailChimp's docs say the type is an "array," but they mean an associative array (i.e. a Ruby hash). So try something like this:
respuesta = gb.listSubscribe({
:id => lista_id, :email_address => email,
:merge_vars => {'FNAME' => nombre, 'LNAME' => apellido,
'MMERGE3' => {'addr1' => 'aqui', 'addr2' => 'Alla', 'city' => 'Mexico DF',
'zip' => '06700', 'country' => 'MX'}
}
})
Also, API 1.3 has been deprecated. I suggest upgrading to Gibbon 1.0, which hits MailChimp API 2.0. The syntax is a little different so be sure to check out the 2.0 docs and Gibbon's updated README here.
I get hash that contains user role, controller name and list of the controller actions this role can access to.
access = {
'admin' => [ 'users' => ['edit','delete'],
'messages' => ['show','update']
],
'user' => [ 'index' => ['index','sign-out'],
'messages' => ['show','index']
]
}
How can i check what access['admin']['users']['edit'] exists?
access['admin']['users'].include? 'edit'
However, this may be a problem: you're using ... => ['users'=>['edit','delete'],...]
This will create an array with a hash inside. Example:
{'a'=>'b'} #=> {"a"=>"b"}
['a'=>'b'] #=> [{"a"=>"b"}]
So consider using this:
access = {
'admin' => { 'users' => ['edit','delete'],
'messages' => ['show','update']
},
'user' => { 'index' => ['index','sign-out'],
'messages' => ['show','index']
}
}