DBIx::Class base result class - mysql

I am trying to create a model for Catalyst by using DBIx::Class::Schema::Loader. I want the result classes to have a base class I can add methods to. So MyTable.pm inherits from Base.pm which inherits from DBIx::Class::core (default).
Somehow I cannot figure out how to do this. my create script is below, can anyone tell me what I am doing wrong? The script creates my model ok, but all resultset classes just directly inherit from DBIx::Class::core without my Base class in between.
#!/usr/bin/perl
use DBIx::Class::Schema::Loader qw/ make_schema_at /;
#specifically for the entities many-2-many relation
$ENV{DBIC_OVERWRITE_HELPER_METHODS_OK} = 1;
make_schema_at(
'MyApp::Schema',
{
dump_directory => '/tmp',
debug => 1,
overwrite_modifications => 1,
components => ['EncodedColumn'], #encoded password column
use_namespaces => 1,
default_resultset_class => 'Base'
},
[ 'DBI:mysql:database=mydb;host=localhost;port=3306','rob', '******' ],
);

Looks like you just want to add in result_base_class (and probably drop the default_resultset_class)–
env DBIC_OVERWRITE_HELPER_METHODS_OK=1 \
dbicdump \
-o result_base_class="FullNameOf::Base" \
-o debug=1 \
-o dump_directory=./tmp \
-o components='["EncodedColumn"]' \
-o use_namespaces=1 \
-o overwrite_modifications=1 \
"DBI:mysql:database=mydb;host=localhost;port=3306" \
rob "******"
Update, relevant doc: DBIx::Class::Schema::Loader::Base#result_base_class.

Related

Create Azure EventHub via CLI with Capture

Scenario: I am putting together a repeatable script that creates, among other things, an Azure EventHub. My code looks like:
az eventhubs eventhub create \
--name [name] \
--namespace-name [namespace] \
--resource-group [group] \
--status Active \
--enable-capture true \
--archive-name-format "{Namespace}/{EventHub}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}/{PartitionId}" \
--storage-account [account] \
--blob-container [blob] \
--capture-interval 300 \
--partition-count 10 \
--skip-empty-archives true
If I run the code as written, I get a "Required property 'name' not found in JSON. Path 'properties.captureDescription.destination', line 1, position 527."
However, if I remove the --enable-capture true parameter, the EventHub is created, albeit with Capture not enabled. If I enable Capture, none of the capture-related parameters other than the interval are set.
Is there a typo in there that I'm not seeing?
Try providing the --destination-name.
az eventhubs eventhub create --name
--namespace-name
--resource-group
[--archive-name-format]
[--blob-container]
[--capture-interval]
[--capture-size-limit]
[--destination-name]
[--enable-capture {false, true}]
[--message-retention]
[--partition-count]
[--skip-empty-archives {false, true}]
[--status {Active, Disabled, SendDisabled}]
[--storage-account]

Save tree view json to file using jq library

I have like this json data in my case:
sshpass -p $PASSWORD ssh -o StrictHostKeyChecking=no $LOGIN /bin/bash -s << EOT
echo "Saving to file.."
USER_DATA="{\"id\":"$USER_ID",\"sha\":"$USER_SHA"}"
echo "{\"id\":"$PRODUCT_ID",\"user\":"$USER_DATA"}" | jq -re > ~/user.json
EOT
When I tried save this json to file get error with message:
parse error: Unmatched '}' at line 1, column 21
How I can save correctly my json data to file?
You should use jq to create your json. Try something like this :
sshpass -p $PASSWORD ssh -o StrictHostKeyChecking=no $LOGIN /bin/bash -s << EOT
echo "Saving to file.."
jq --arg id "$PRODUCT_ID" -n '{$id}' | \
jq --arg id "$USER_ID" \
--arg sha "$USER_SHA" \
--arg user "user" \
'.[$user]={$id, $sha}' > ~/user.json
EOT
Explanations:
--arg id "$PRODUCT_ID" : create a variable for jq, called id which contains the value taken from $PRODUCT_ID
-n '{$id}' : create a new json template
This will take the variable name as well as its value
Here, this creates the json {id : $id}
jq ... | jq ... : we pass the output of the 1st jq command as the input of the 2nd command
'.[$user]={$id, $sha}' : we add new elements to the input
.[$user] : the element name from the $user variable
{$id, $sha} : will create an object from the variables, i.e. {id : $id, sha : $sha}
the whole command creates the element : user : {id : $id, sha : $sha}

arangoimp of graph from CSV file

I have a network scan in a TSV file that contains data in a form like the following sample
source IP target IP source port target port
192.168.84.3 192.189.42.52 5868 1214
192.168.42.52 192.189.42.19 1214 5968
192.168.4.3 192.189.42.52 60680 22
....
192.189.42.52 192.168.4.3 22 61969
Is there an easy way to import this using arangoimp into the (pre-created) edge collection networkdata?
You could combine the TSV importer, if it wouldn't fail converting the IPs (fixed in ArangoDB 3.0), so you need a bit more conversion logic to get valid CSV. One will use the ede attribute conversion option to convert the first two columns to valid _from and _to attributes during the import.
You shouldn't specify column subjects with blanks in them, and it should really be tabs or a constant number of columns. We need to specify a _from and a _to field in the subject line.
In order to make it work, you would pipe the above through sed to get valid CSV and proper column names like this:
cat /tmp/test.tsv | \
sed -e "s;source IP;_from;g;" \
-e "s;target IP;_to;" \
-e "s; port;Port;g" \
-e 's; *;",";g' \
-e 's;^;";' \
-e 's;$;";' | \
arangoimp --file - \
--type csv \
--from-collection-prefix sourceHosts \
--to-collection-prefix targetHosts \
--collection "ipEdges" \
--create-collection true \
--create-collection-type edge
Sed with these regular expressions will create an intermediate representation looking like that:
"_from","_to","sourcePort","targetPort"
"192.168.84.3","192.189.42.52","5868","1214"
The generated edges will look like that:
{
"_key" : "21056",
"_id" : "ipEdges/21056",
"_from" : "sourceHosts/192.168.84.3",
"_to" : "targetHosts/192.189.42.52",
"_rev" : "21056",
"sourcePort" : "5868",
"targetPort" : "1214"
}

Changing values in a JSON data file from shell

I have created a JSON file which in this case contains:
{"ipaddr":"10.1.1.2","hostname":"host2","role":"http","status":"active"},
{"ipaddr":"10.1.1.3","hostname":"host3","role":"sql","status":"active"},
{"ipaddr":"10.1.1.4","hostname":"host4","role":"quad","status":"active"},
On other side I have a variable with values for example:
arr="10.1.1.2 10.1.1.3"
which comes from a subsequent check of the server status for example. For those values I want to change the status field to "inactive". In other words to grep the host and change its "status" value.
Expected output:
{"ipaddr":"10.1.1.2","hostname":"host2","role":"http","status":"inactive"},
{"ipaddr":"10.1.1.3","hostname":"host3","role":"sql","status":"inactive"},
{"ipaddr":"10.1.1.4","hostname":"host4","role":"quad","status":"active"},
$ arr="10.1.1.2 10.1.1.3"
$ awk -v arr="$arr" -F, 'BEGIN { gsub(/\./,"\\.",arr); gsub(/ /,"|",arr) }
$1 ~ "\"(" arr ")\"" { sub(/active/,"in&") } 1' file
{"ipaddr":"10.1.1.2","hostname":"host2","role":"http","status":"inactive"},
{"ipaddr":"10.1.1.3","hostname":"host3","role":"sql","status":"inactive"},
{"ipaddr":"10.1.1.4","hostname":"host4","role":"quad","status":"active"},
Here is a quick perl "wrap-around one-liner": that uses the JSON module and slurps with the -0 switch:
perl -MJSON -n0E '$j = decode_json($_);
for (#{$j->{hosts}}){$_->{status}=inactive if $_->{ipaddr}=~/2|3/} ;
say to_json( $j->{hosts}, {pretty=>1} )' status_data.json
might be nicer or might violate PBP recommendations for map:
perl -MJSON -n0E '$j = decode_json($_);
map { $_->{status}=inactive if $_->{ipaddr}=~/2|3/ } #{ $j->{hosts} } ;
say to_json( $j->{hosts} )' status_data.json
A shell script that resets status using jq would also be possible. Here's a quick way to parse and output changes to JSON using jq:
cat status_data.json| jq -r '.hosts |.[] |
select(.ipaddr == "10.1.1.2"//.ipaddr == "10.1.1.3" )' |jq '.status = "inactive"'
EDIT In an earlier comment I was uncertain whether the OP was more interested in an application than a quick search and replace (something about the phrases "On other side..." and "check on the server status"). Here is a (still simple) perl approach in script form:
use v5.16; #strict, warnings, say
use JSON ;
use IO::All;
my $status_data < io 'status_data.json';
my $network = JSON->new->utf8->decode($status_data) ;
my #changed_hosts= qw/10.1.1.2 10.1.1.3/;
sub status_report {
foreach my $host ( #{ $network->{hosts} }) {
say "$host->{hostname} is $host->{status}";
}
}
sub change_status {
foreach my $host ( #{ $network->{hosts} }){
foreach (#changed_hosts) {
$host->{status} = "inactive" if $host->{ipaddr} eq $_ ;
}
}
status_report;
}
defined $ENV{CHANGE_HAPPENED} ? change_status : status_report ;
The script reads the JSON file status_data.json (using IO::All which is great fun) then decodes it with JSON into a hash. It is hard to tell if this us a complete a solution because if you are "monitoring" host status then we should check the JSON data file periodically and compare it to our hash and then run the main body of the script one when changes have occurred.
To simulate changes occurring you can define/undefine CHANGE_HAPPENED in your environment with export CHANGE_HAPPENED=1 (or setenv if in in tcsh) and unset CHANGE_HAPPENED and the script will then either update the messages and the hash or "report". For this to be complete the data in our hash should be updated to match the the data file either periodically or when an event occurs. The status_report() subroutine could be changed so that it builds arrays of #inactive_hosts and #active_hosts when update_status() told it to do so: if ( something_happened() ) { update_status() }, etc.
Hope that helps.
status_data.json
{
"hosts":[
{"ipaddr":"10.1.1.2","hostname":"host2","role":"http","status":"active"},
{"ipaddr":"10.1.1.3","hostname":"host3","role":"sql","status":"active"},
{"ipaddr":"10.1.1.4","hostname":"host4","role":"quad","status":"active"}
]
}
output:
~/ % perl network_status_json.pl
host2 is active
host3 is active
host4 is active
~/ % export CHANGE_HAPPENED=1
~/ % perl network_status_json.pl
host2 is inactive
host3 is inactive
host4 is active
Version 1:
Using a simple regex based transformation. This can be done in several ways. From the initial question, the list of ipaddr is in variable in arr. Example using a Bash env variable:
$ export var="... ..."
It would be a possible solution to provide this information by command line parameters.
#!/usr/bin/perl
my %inact; # ipaddr to inactivate
my $arr=$ENV{arr} ; # from external var (export arr=...)
## $arr=shift; # from command line arg
for( split(/\s+/, $arr)){ $inact{$_}=1 }
while(<>){ # one "json" line at the time
if(/"ipaddr":"(.*?)"/ and $inact{$1}){
s/"active"/"inactive"/}
print $_;
}
Version 2:
Using Json parser we can do more complex transformations; as the input is not real JSON we will process one line of "almost json" at the time:
use JSON;
use strict;
my ($line, %inact);
my $arr=$ENV{arr} ;
for( split(/\s+/, $arr)){ $inact{$_}=1 }
while(<>){ # one "json" line at the time
if(/^\{.*\},/){
s/,\n//;
$line = from_json( $_);
if($inact{$line->{ipaddr}}){
$line->{status} = "inactive" ;}
print to_json($line), ",\n"; }
else { print $_;}
}
#!/bin/ksh
# your "array" of IP
arr="10.1.1.2 10.1.1.3"
# create and prepare temporary file for sed action
SedAction=/tmp/Action.sed
# --- for/do generating SedAction --------
echo "#sed action" > ${SedAction}
#take each IP from the arr variable one by one
for IP in ${arr}
do
# prepare for a psearch pattern use
IP_RE="$( echo "${IP}" | sed 's/\./\\./g' )"
# generate sed action in temporary file.
# final action will be like:
# s/\("ipaddr":"10\.1\.1\.2".*\)"active"}/\1"inactive"}/;t
# escape(double) \ for in_file espace, escape(simple) " for this line interpretation
echo "s/\\\(\"ipaddr\":\"${IP_RE}\".*\\\)\"active\"}/\\\1\"inactive\"}/;t" >> ${SedAction}
done
# --- sed generating sed action ---------------
echo "${arr}" \
| tr " " "\n" \
| sed 's/\./\\./g
s#.*#s/\\("ipaddr":"&".*\\)"active"}/\\1"inactive"}/;t#
' \
> ${SedAction}
# core of the process (use -i for inline editing or "double" redirection for non GNU sed)
sed -f ${SedAction} YourFile
# clean temporary file
rm ${SedAction}
Self commented, tested in ksh/AIX.
2 way to generate the SedAction depending of action you want to do also (if any). You only need one to work, i prefer the second
This is very simple indeed in Perl, using the JSON module.
use strict;
use warnings;
use JSON qw/ from_json to_json /;
my $json = JSON->new;
my $data = from_json(do { local $/; <DATA> });
my $arr = "10.1.1.2 10.1.1.3";
my %arr = map { $_ => 1 } split ' ', $arr;
for my $item (#$data) {
$item->{status} = 'inactive' if $arr{$item->{ipaddr}};
}
print to_json($data, { pretty => 1 }), "\n";
__DATA__
[
{"ipaddr":"10.1.1.2","hostname":"host2","role":"http","status":"active"},
{"ipaddr":"10.1.1.3","hostname":"host3","role":"sql","status":"active"},
{"ipaddr":"10.1.1.4","hostname":"host4","role":"quad","status":"active"}
]
output
[
{
"role" : "http",
"hostname" : "host2",
"status" : "inactive",
"ipaddr" : "10.1.1.2"
},
{
"hostname" : "host3",
"role" : "sql",
"ipaddr" : "10.1.1.3",
"status" : "inactive"
},
{
"ipaddr" : "10.1.1.4",
"status" : "active",
"hostname" : "host4",
"role" : "quad"
}
]

Cant write to file with exec

I am working with a puppet class which write to my.cnf if specified line isn't there, and it's not working. Here is the code:
class mysql-server::configure {
exec { "enable_binlog":
path => "/usr/bin/:/usr/sbin/:/usr/local/bin:/bin/:/sbin",
command => "echo 'log_bin=/var/log/mysql/mysql-bin.log' >> /etc/mysql/my.cnf",
onlyif => "grep -c log_bin=/var/log/mysql/mysql-bin.log' /etc/mysql/my.cnf",
}
}
I believe that your onlyif query is wrong.
While grep -c prints a 0 if no matching line is found, it still returns 1.
How about
unless => 'grep -q log_bin=/var/log/mysql/mysql-bin.log /etc/mysql/my.cnf'
Note that you probably want to use the file_line type from the stlib module to do the same thing more efficiently.