Effective December 3, NetApp adopts Microsoft’s Business-to-Customer (B2C) identity management to simplify and provide secure access to NetApp resources.
For accounts that did not pre-register (prior to Dec 3), access to your NetApp data may take up to 1 hour as your legacy NSS ID is synchronized to the new B2C identity.
To learn more, read the FAQ and watch the video.
Need assistance? Complete this form and select “Registration Issue” as the Feedback Category.

Software Development Kit (SDK) and API Discussions

Perl API file-write-file "Missing: offset"?

j_kleijer

Hi all,

I'm trying to create a script that creates users on our filers when necessary and create the appropriate /vol/vol0/etc/sshd/<user>/.ssh/authorized_keys file and so far, I've been able to create the user and create the directories when necessary.

I'm now in the process of trying to create the file authorized_keys using the API call file-write-file* and basically use this function call to create the file and inject / write the keys in to them.

I've been able to figure out that I need to pack the data that I'm trying to write but no matter what I try, I keep getting the error message

file-write-file: Missing input: offset

even though the offset is explicitly given during the following command:

$dst_file = "/vol/vol0/etc/sshd/jmk3/.ssh/authorized_keys";

$packed_string = pack( "H*",  $lines[0] );

$offset = -1;

$api_output = $connection->invoke( $api_call, "path", $dst_file, "data", $packed_string, "offset", $offset );

Using this I get the "Missing input: offset" error.

Does anyone know what's going on here?

Kind regards,

Jeroen Kleijer

*) The reason I want to use the API-call file-write-file is that some of our filers have been installed with vol0 being on a NTFS filesystem meaning that I cannot mount them that easily under Linux and write the authorized_keys file. (yes, I can export it using NFS but then I would have to create a mapping where root = Administrator and that was something that I'd hope to avoid. If I can use the API I'd prefer to do that)

6 REPLIES 6

j_kleijer

Ok, should've tried some more combinations before posing the question.

Apparently order is important when using the file-write-file API-call:

Using

$api_output = $connection->invoke( $api_call, "offset", $offset, "path", $dst_file, "data", $packed_string );

seems to work (though I'm still trying to figure out how to pack the string to something that the API likes)

Kind regards,

Jeroen Kleijer

rle
NetApp Alumni

The API documentation states that the data should be in this form:

Data to be written. The format of the data is ASCII hex characters, two characters representing one byte. Whitespace characters, for convenience in formatting, can be present in the value and are ignored.

The data needs to be converted to ASCII hex.  This was done so that binary values could be easily transferred.  I have included some Perl code to do the conversion.

sub str_to_hex($) {
        my $s = shift;
        my $r = "";
        my $leng = length($s);
        for ( my $n=0; $n < $leng; $n++ ) {
                my $c = substr($s,$n,1);
                my $hx = sprintf "%02x", ord("$c");
                $r = $r . $hx;
        }
        return($r);
}
sub hex_to_str($) {
        my $s = shift;
        my $r = "";
        my $leng = length($s);
        for ( my $n=0; $n < $leng; $n+=2 ) {
                my $hx = substr($s,$n,2);
                my $hn = hex("$hx");
                $r = $r . chr($hn);
        }
        return($r);
}

Before the string is written, use string to str_to_hex(). 

Also note the the offset is integer, and therefore you must covert the integer to a string.  Your call could look like this:

$offset = "-1";

$api_output = $connection->invoke( $api_call, "offset", $offset, "path", $dst_file, "data", $packed_string );

Regards,

   - Rick -

kevingraham

Rick -- pack and unpack are your friends:

$elem->child_add(NaElement->new('data', unpack('H*', $filedata));

...and:

$filedata = pack('H*', $elem->child_get_string('data'));

chris_algar

Or use 'ord':

     (my $hex = $args{conent} ) =~ s/(.|\n)/sprintf("%02lx", ord $1)/eg;

      my $output     = $serv->invoke( "file-write-file",

                                                    "data", $hex,

                                                    "offset", $args{offset},

                                                    "overwrite", $args{overwrite},

                                                    "path", $args{path} );

and from back from hex when reading:

     $content     =~ s/([a-fA-F0-9]{2})/chr(hex $1)/eg;

chris_algar

Or use 'ord':

     (my $hex = $args{conent} ) =~ s/(.|\n)/sprintf("%02lx", ord $1)/eg;

      my $output     = $serv->invoke( "file-write-file",

                                                    "data", $hex,

                                                    "offset", $args{offset},

                                                    "overwrite", $args{overwrite},

                                                    "path", $args{path} );

and from back from hex when reading:

     $content     =~ s/([a-fA-F0-9]{2})/chr(hex $1)/eg;

chris_algar

Or use 'ord':

     (my $hex = $args{conent} ) =~ s/(.|\n)/sprintf("%02lx", ord $1)/eg;

      my $output     = $serv->invoke( "file-write-file",

                                                    "data", $hex,

                                                    "offset", $args{offset},

                                                    "overwrite", $args{overwrite},

                                                    "path", $args{path} );

and from back from hex when reading:

     $content     =~ s/([a-fA-F0-9]{2})/chr(hex $1)/eg;

Announcements
NetApp on Discord Image

We're on Discord, are you?

Live Chat, Watch Parties, and More!

Explore Banner

Meet Explore, NetApp’s digital sales platform

Engage digitally throughout the sales process, from product discovery to configuration, and handle all your post-purchase needs.

NetApp Insights to Action
I2A Banner
Public