User groups got empty array - inspec

Wrote an inspec-test for groups. The groups are asigned to the user pi on bash but I got an empty array from inspec-test.
Here the bash output:
id
uid=1000(pi) gid=1000(pi) Gruppen=1000(pi),4(adm),20(dialout),27(sudo),33(www-data),44(video),100(users),998(docker),999(gpio)
When I run my inspec I got this:
× users-1.0: Ensure users are known (1 failed)
✔ User pi should exist
✔ User pi group should eq "pi"
× User pi groups should eq ["pi", "sudo"]
expected: ["pi", "sudo"]
got: []
(compared using ==)
✔ User pi home should eq "/home/pi"
In my rb-file I wrote this:
users = {
:pi => {
:uname => 'pi',
:gname => 'pi',
:groups => [
'adm',
'dialout',
'sudo',
'www-data',
'video',
'users',
'docker',
'gpio'
],
:home => '/home/pi'
}
}
...
control 'users-1.0' do
impact 1.0
title 'Ensure users are known'
users.each do |key, value|
describe user(value[:uname]) do
it { should exist }
its('group') { should eq "#{value[:gname]}" }
its('groups') { should eq [ 'pi', 'sudo' ] }
its('home') { should eq "#{value[:home]}" }
#its('shell') { should eq '/bin/bash' }
#its('mindays') { should eq 0 }
#its('maxdays') { should eq 90 }
#its('warndays') { should eq 8 }
end
end
end
I expected to see an array of groups from user pi.
I don't know how to start searching. I'm a inspec newbee.
Thanks

It is a known InSpec bug. InSpect expects id (and any other command) output with LC_MESSAGES=C or any other US locale.

Related

MongoDB/Perl: find_one doesn't return data after unrelated code

mongodb is v4.0.5
Perl is 5.26.3
MongoDB Perl driver is 2.0.3
This Data::Dumper output shows what's driving me crazy
INFO - $VAR1 = [
'275369249826930689 1',
{
'conf' => {
'param' => 'argument'
},
'id' => '275369249826930689',
'lastmsg' => '604195211232139552',
'_id' => bless( {
'oid' => ']:\',&�h�GeR'
}, 'BSON::OID' )
}
];
352832438449209345 275369249826930689
INFO - $VAR1 = [
'275369249826930689 2'
];
The second INFO - $VAR1 should show the same content as the first one. This is the original code, which I have (see below) broken down to find the culprit.
ddump(["$userid 1",
$c_identities->find_one({
channel => 'chan1',
id => $userid,
})
]);
my #filtered = reverse
grep { $_->{author}->{id} == $userid } #{$answers};
ddump(["$userid 2",
$c_identities->find_one({
channel => 'chan1',
id => $userid,
})
]);
ddump is just a wrapper for Data::Dumper. If I remove the "my #filtered" line, the second find one again returns the expected result (a MongoDB document). $answers is just a listref of hashes - no objects - from some API, completely unrelated to MongoDB.
So I broke the "reverse grep" code down to see where the culprit is. The say are the two numbers you see between the dumpers above. This is what I can do, to get answer from the second find_one:
for my $answer (#{$answers}) {
say $answer->{author}->{id}, ' ', $userid;
push #filtered, $answer;
}
As long as I do just this, the second find_one delivers a result. If, however, I do this:
for my $answer (#{$answers}) {
say $answer->{author}->{id}, ' ', $userid;
if ($answer->{author}->{id} == $userid) {
}
push #filtered, $answer;
}
I get the output from above (where the second dumper yields no return from the find_one. It's insane - the if-clause containing the numeric eq causes the second find_one to fail! This is also the grep body in the intended code.
What's going on here? How can this have possibly any effect on the MongoDB methods?
Using the numeric comparison operator == numifies the value, but it's probably too large to fit into an integer and becomes a float. It can also just become an integer and lose double quotes when serialized to JSON or similar format. Using eq instead of == keeps the value unchanged.

How to delete pattern which matches with the next new pattern which is calling in the next line by using /bin/sed command in dc_shell

Below is the example of my file,
signal {
{
ab
cd
}
"m_1_clk" {
P {
'0ns' D;
'25ns' U;
'65ns' D;
}
}
"m_0_clk" {
P {
'0ns' D;
'25ns' U;
'65ns' D;
}
}
"o_[9]" {
Data S Mk {
Active Up;
}
}
"m_0_clk" {
Data S Mk {
Active Up;
}
}
"m_1_clk" {
Data S Mk {
Active Up;
}
}
}
I am expecting the output from above file to be:
signal {
{
ab
cd
}
"o_[9]" {
Data S Mk {
Active Up;
}
}
}
Hi,
Above is the example of my file
I would like to delete pattern which matches the next pattern which is calling in the next line.
Trying to search the specific pattern for deleting the lines which it should not be present in my file.
Need to search the specific pattern with new pattern in the next line. because first line is calling in multiple loops. so should grep specific pattern of all the content.
I tried using the below command in tcl its not working. could anyone help me on this,
below is the sed command used in tcl
exec /bin/sed -e {s/\m\(.*\)clk" {\.*\n\.*Data\.*//} -i file
exec /bin/sed -e {s/\m\(.*\)clk" {\.*\n\.*P {\.*//} -i file
Could you please try following and let me know if this helps you.(Considering that your actual Input_file is same as shown sample file)
awk -v line_number=$(cat Input_file | wc -l) '/signal {/ || /"o_\[9\]" {/ || FNR==line_number{flag=1}; /^$/{flag=""} flag' Input_file
Explanation: Adding explanation for code too now as follows:
awk -v line_number=$(cat Input_file | wc -l) ' ##Creating variable named line_number in awk script whose value is number of lines of Input_file.
/signal {/ || /"o_\[9\]" {/ || FNR==line_number{ ##checking condition here if a line contains strings either signal { OR "o_\[9\]" { then do following:
flag=1} ##Setting variable named flag here and setting its value to 1 here.
/^$/{ ##Checking condition here if a line is NULL or BLANK then do following:
flag=""} ##Nullifying the variable flag here.
flag ##awk works on method of condition then actions, so checking if variable flag value is NOT NULL here and not mentioning any action here so by default peint of current line will happen here.
' Input_file ##Metioning the Input_file name here.
Solution with a context-sensitive parser:
use Marpa::R2 qw();
my $input = <<'INPUT';
signal {
{
ab
cd
}
"m_1_clk" {
P {
'0ns' D;
'25ns' U;
'65ns' D;
}
}
"m_0_clk" {
P {
'0ns' D;
'25ns' U;
'65ns' D;
}
}
"o_[9]" {
Data S Mk {
Active Up;
}
}
"m_0_clk" {
Data S Mk {
Active Up;
}
}
"m_1_clk" {
Data S Mk {
Active Up;
}
}
}
INPUT
my $grammar = Marpa::R2::Scanless::G->new({
bless_package => 'Foo',
source => \<<'GRAMMAR',
:default ::= action => [values] bless => ::lhs
lexeme default = action => [ value ] bless => ::name latm => 1
:start ::= blocks
blocks ::= block+
block ::= optionalname [{] contentblocks [}] optionalws
optionalname ::= name | epsilon
contentblocks ::= contentorblock+
contentorblock ::= content | block
name ~ [a-zA-Z0-9_"\x{5b}\x{5d} ]+
content ~ [a-zA-Z0-9;'\s]*
optionalws ~ [\s]*
epsilon ::=
GRAMMAR
});
my $parser = Marpa::R2::Scanless::R->new({grammar => $grammar});
$parser->read(\$input);
my $output;
deleteblocks($parser->value->$*);
print $output;
sub deleteblocks {
my ($v) = #_;
return if ref $v eq 'Foo::block' and $v->[0][0]
and $v->[0][0][0] !~ /signal|"o_\[9\]"/;
if (ref $v) {
deleteblocks($_) for $v->#*;
} else {
$output .= $v || '';
}
}
Output is:
signal {
{
ab
cd
}
"o_[9]" {
Data S Mk {
Active Up;
}
}
}

incorporating local variables in a global hash in perl

I need to incorporate a generic hash (macro) in multiple user hashes. In actuality these are all specifications written as HoH/HoL in perl.
I would like the 'user' specs to adopt the macro specs with their own modifications. In example below, the variable '$v_Y' needs to have different values in user1 and user2.
What I have below is not exactly code, but an attempt to illustrate the problem. I am unable to have multiple values of $v_Y since macro_spec is already created.
## this is in a package
my $MACRO_SPEC = {
mkeyX => "value_X",
mkeyY => $v_Y,
};
#this is USER1 package,
$v_Y = "U1_VALUE_X";
# use MACRO_SPEC
my $USER1 = (
u1key1 => "u1value1", u1macrokey => $MACRO_SPEC, # need macro to interpolate 'local' $v_Y
);
#this is USER2 package,
$v_Y = "U2_VALUE_X";
# use MACRO_SPEC
my $USER2 = (
u2key1 => "u2value1",
u2macrokey => $MACRO_SPEC, # need macro to interpolate 'local' $v_Y
);
#this is how USER1 should look after the interpolation
my $USER1 = (
u1key1 => "u1value1",
u1macrokey => {
mkeyX => "value_X",
mkeyY => "U1_VALUE_X"
},
);
#this is how USER2 should look after the interpolation
my $USER2 = (
u2key1 => "u2value1",
u1macrokey => {
mkeyX => "value_X",
mkeyY => "U2_VALUE_X"
},
);
Like melpomene suggested, you want $MACRO_SPEC to be a function that can generate something different each time it is called.
package One;
our $v_Y;
my $MACRO_SPEC = sub { +{ mkeyX => "value_X", mkeyY => $v_Y } };
...
package USER1;
$One::v_Y = "U1_VALUE_X";
my $user1 = { # { }, not ( ), to define a hash reference
u1key1 => "u1value1",
u1macrokey => $MACRO_SPEC->(), # $f->() to exec code defined in $f
...
};

How to loop through subarrays of a SOAP::Lite response in Perl?

I have a Perl script that is successfully getting a response from my ShoreTel Phone server. The server provides information on what calls are currently connected for the extension entered. However I am having issues looping through the sub arrays to get more than one response when there are multiple items. In this case I want to get each of the caller IDs that is currently connected.
My SOAP:LITE request is successfully pulling data from the server using the following code:
use strict;
use warnings;
use SOAP::Lite;
use CGI;
use Data::Dumper;
my $myWebService = SOAP::Lite
-> uri('http://www.ShoreTel.com/ProServices/SDK/Web')
-> proxy('http://10.1.##.##:8070/ShoreTelWebSDK/WebService')
-> on_action(sub {sprintf '%s/ShoreTelWebService/%s', $_[0], $_[1]});
my $query = new CGI;
my $ip = $query->remote_host; # IP address of remote party...use later as unique identifier
my $myClientID = $query->param('MyClientID'); # Possible client ID from previous script passed into us.
my $extnNr = $query->param('MyExtn'); # Has to be at least an extension number so we know who to status.
my $url = CGI::url(-path_info=>1); # What is my URL?
# There should be an extension number given, else what would we status.
if (defined($refreshNr) && defined($extnNr) && ($extnNr ne '') && ($refreshNr ne ''))
{
# If there is a client ID defined, use it...otherwise registering and getting a client ID
# is the first thing we need to do when using our web service.
unless (defined($myClientID))
{
# To use our service, we need to register ourselves as a client...use remote IP address
# as a unique name for association to this session.
my $regClientResult = $myWebService->RegisterClient(SOAP::Data->name('clientName' => $ip));
if ($regClientResult->fault)
{
print '<p>FAULT', $myClientID->faultcode, ', ', $myClientID->faultstring;
}
else
{
# Retrieve client ID which we will be using for subsequent communication.
$myClientID = $regClientResult->valueof('//RegisterClientResponse/RegisterClientResult/');
}
}
if (defined($myClientID))
{
# Use our web service to open the line. This is necessary to get a line ID.
# print '<br>Client ID ', $myClientID, ' has been registered.<br>';
my $openResult = $myWebService->OpenLine(SOAP::Data->name('clientHandle' => $myClientID), SOAP::Data->name('lineAddress' => $extnNr));
my $lineID = $openResult->valueof('//OpenLineResponse/OpenLineResult/lineID/');
my $lineType = $openResult->valueof('//OpenLineResponse/OpenLineResult/lineType/');
my $lineName = $openResult->valueof('//OpenLineResponse/OpenLineResult/lineName/');
my $lineState = $openResult->valueof('//OpenLineResponse/OpenLineResult/lineState/');
# Call GetActiveCalls to see if anything is going on with this line.
my $result = $myWebService->GetActiveCalls(SOAP::Data->name('clientHandle' => $myClientID), SOAP::Data->name('lineID' => $lineID));
my $callID = $result->valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/callID/');
if ($callID ne '')
{
# print '<br>Call ID is ', $callID;
my $isExternal = $result->valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/isExternal/');
my $isInbound = $result->valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/isInbound/');
my $callReason = $result->valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/callReason/');
my $connectedID = $result->valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/connectedID/');
my $connectedIDName = $result->valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/connectedIDName/');
my $callerID = $result->valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/callerID/');
my $callerIDName = $result->valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/callerIDName/');
my $calledID = $result->valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/calledID/');
my $calledIDName = $result->valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/calledIDName/');
my $callState = $result->valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callState/');
my $callStateDetail = $result->valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callStateDetail/');
# Print call information.
print <<EndOfCallInfo;
HTML CODE
EndOfCallInfo
}
else
{
print <<EndOfCallInfo2;
HTML CODE
EndOfCallInfo2
}
}
}
But I am only able to access the first result in the multidimensional array.
I have tried looping through the results using
for my $t ($result->result({ShoreTelCallStateInfo}{callInfo}')) {
print $t->{callerID} . "\n";}
But I am getting absolutely no results. It appears that the the loop is not even entered.
The following code I have works fine, but only pulls the first caller ID, in this case 1955.
my $callerID = $result->valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/callerID/');
What can I do to make my loop work?
So that you can see what I am receiving from the server I have included the response from the SOAP Server using DUMP :
$VAR1 = { 'ShoreTelCallStateInfo' => [
{ 'callStateDetail' => 'Active',
'callState' => 'OnHold',
'callInfo' =>
{ 'callerIDName' => 'Joel LASTNAME',
'callID' => '69105', 'lineID' => '3947',
'connectedIDName' => 'VM-Forward',
'calledID' => '2105',
'callerID' => '1955',
'isInbound' => 'false',
'calledIDName' => 'VM-Forward',
'callReason' => 'None',
'callUniqueID' => '1369702515',
'connectedID' => '2105',
'isExternal' => 'false',
'callGUID' => '{00030000-66C2-537E-3FD8-0010492377D9}'
}
},
{ 'callStateDetail' => 'Active',
'callState' => 'Connected',
'callInfo' =>
{ 'callerIDName' => 'LASTNAME Joel ',
'callID' => '71649',
'lineID' => '3947',
'connectedIDName' => 'LASTNAME Joel ',
'calledID' => '1955',
'callerID' => '+1385#######',
'isInbound' => 'true',
'calledIDName' => 'Joel LASTNAME',
'callReason' => 'None',
'callUniqueID' => '1117287558',
'connectedID' => '+1385#######',
'isExternal' => 'true',
'callGUID' => '{00030000-66C5-537E-3FD8-0010492377D9}'
}
}
]
};
Just a guess...
The following code I have works fine, but only pulls the first caller
ID, in this case 1955.
my $callerID = $result->valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/callerID/');
What can I do to make my loop work?
SOAP::Lite docs say:
valueof()
Returns the value of a (previously) matched node. It accepts a node
path. In this case, it returns the value of matched node, but does not
change the current node. Suitable when you want to match a node and
then navigate through node children:
$som->match('/Envelope/Body/[1]'); # match method
$som->valueof('[1]'); # result
$som->valueof('[2]'); # first out parameter (if present)
The returned value depends on the context. In a scalar context it will
return the first element from matched nodeset. In an array context it
will return all matched elements.
Does this give the behavior you expect? It imposes list context on the valueof method.
for my $callerID ($result->valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/callerID/')) {
...
# do something with each callerID
}
or
my #callerIDs = $result->valueof('//GetActiveCallsResponse/GetActiveCallsResult/ShoreTelCallStateInfo/callInfo/callerID/');

how to query eXist using XPath?

I decided to use eXist as a database for an application that I am writing in Perl and
I am experimenting with it. The problem is that I have stored a .xml document with the following structure
<foo-bar00>
<perfdata datum="GigabitEthernet3_0_18">
<cli cmd="whatsup" detail="GigabitEthernet3/0/18" find="" given="">
<input_rate>3</input_rate>
<output_rate>3</output_rate>
</cli>
</perfdata>
<timeline>2011-5-23T11:15:33</timeline>
</foo-bar00>
and it is located in the "/db/LAB/foo-bar00/2011/5/23/11_15_33.xml" collection.
I can successfully query it, like
my $xquery = 'doc("/db/LAB/foo-bar00/2011/5/23/11_15_33.xml")' ;
or $xquery can be equal to
= doc("/db/LAB/foo-bar00/2011/5/23/11_15_33.xml")/foo-bar00/perfdata/cli/data(output_rate)
or
= doc("/db/LAB/foo-bar00/2011/5/23/11_15_33.xml")/foo-bar00/data(timeline)
my ($rc1, $set) = $eXist->executeQuery($xquery) ;
my ($rc2, $count) = $eXist->numberOfResults($set) ;
my ($rc3, #data) = $eXist->retrieveResults($set) ;
$eXist->releaseResultSet($set) ;
print Dumper(#data) ;
And the result is :
$VAR1 = {
'hitCount' => 1,
'foo-bar00' => {
'perfdata' => {
'cli' => {
'given' => '',
'detail' => 'GigabitEthernet3/0/18',
'input_rate' => '3',
'cmd' => 'whatsup',
'output_rate' => '3',
'find' => ''
},
'datum' => 'GigabitEthernet3_0_18'
},
'timeline' => '2011-5-23T11:15:33'
}
};
---> Given that I know the xml document that I want to retrieve info from.
---> Given that I want to retrieve the timeline information.
When I am writing :
my $db_xml_doc = "/db/LAB/foo-bar00/2011/5/23/11_15_33.xml" ;
my ($db_rc, $db_datum) = $eXist->queryXPath("/foo-bar00/timeline", $db_xml_doc, "") ;
print Dumper($db_datum) ;
The result is :
$VAR1 = {
'hash' => 1717362942,
'id' => 3,
'results' => [
{
'node_id' => '1.2',
'document' => '/db/LAB/foo-bar00/2011/5/23/11_15_33.xml'
}
]
};
The question is : How can I retrieve the "timeline" info ? Seems that the "node_id" variable (=1.2) can points to the "timeline" info, but how can I use it ?
Thank you.
use XML::LibXML qw( );
my $parser = XML::LibXML->new();
my $doc = $parser->parse_file('a.xml');
my $root = $doc->documentElement();
my ($timeline) = $root->findnodes('timeline');
if ($timeline) {
print("Exists: ", $timeline->textContent(), "\n");
}
or
my ($timeline) = $root->findnodes('timeline/text()');
if ($timeline) {
print("Exists: ", $timeline->getValue(), "\n");
}
I could have used /foo-bar00/timeline instead of timeline, but I didn't see the need.
Don't know if you're still interested, but you could either retrieve the doc as DOM and apply an xquery to the DOM, or, probably better, only pull out the info you want in the query that you submit to the server.
Something like this:
for $p in doc("/db/LAB/foo-bar00/2011/5/23/11_15_33.xml")//output_rate
return
<vlaue>$p</value>