From 0dd19d2e32726ddc59de3e8eafb9cec5dc48fce3 Mon Sep 17 00:00:00 2001 From: Nicolas Boisselier Date: Sat, 25 Feb 2017 19:16:51 +0000 Subject: [PATCH] bin/ovh-api --- bin/ovh-api | 153 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 109 insertions(+), 44 deletions(-) diff --git a/bin/ovh-api b/bin/ovh-api index dec3b950..1f5bc001 100755 --- a/bin/ovh-api +++ b/bin/ovh-api @@ -29,10 +29,6 @@ my %Opt = ( 'method' => 'GET', ); get_options(\%Opt); -# NB 04.02.17 # Auth -# NB 04.02.17 exec qq|curl -s -XPOST -H"X-Ovh-Application: $_" -H "Content-type: application/json" --data '{"accessRules":[{"method":"GET","path":"/*"},{"method":"POST","path":"/*"},{"method":"PUT","path":"/*"},{"method":"DELETE","path":"/*"}]}' https://api.ovh.com/1.0/auth/credential|; -# NB 04.02.17 exit 0; -# NB 04.02.17 } $main::_DATA_ = ''; ################################################################################# @@ -43,16 +39,15 @@ $main::_DATA_ = ''; use JSON; use LWP::UserAgent; use OvhApi; -#use Data::Dumper; -my $config = "$ENV{HOME}/.$NAME"; +my $config = $ENV{'OVH_API_CFG'} ? $ENV{'OVH_API_CFG'} : "$ENV{HOME}/.$NAME"; my @KEY = (); if (@ARGV and $ARGV[0] =~ /^(\w+):(\w+)(?::(\w+))?$/) { @KEY = split(":",$ARGV[0]); shift @ARGV; -} elsif ($ENV{$NAME.'_KEY'}) { - @KEY = split(':',$ENV{$NAME.'_KEY'}); +} elsif ($ENV{'OVH_API_KEY'}) { + @KEY = split(':',$ENV{'OVH_API_KEY'}); } elsif (-e $config) { open(CONFIG,"$config") or die "$NAME: can't read $config"; @@ -65,11 +60,16 @@ if (@ARGV and $ARGV[0] =~ /^(\w+):(\w+)(?::(\w+))?$/) { open STDOUT,'| (which jq > /dev/null && jq . || cat)' if $Opt{jq}; my $Api = OvhApi->new(type => OvhApi::OVH_API_EU, applicationKey => $KEY[0], applicationSecret => $KEY[1], consumerKey => $KEY[2]); +use Data::Dumper; +#@_=_query('/domain');die Dumper(\@_); +#$_=_query('/domain');die Dumper($_); + # Auth auth() if @KEY < 3; -# Sql +# Options sql() if $Opt{sql}; +ip2local($Opt{ip2local}) if $Opt{ip2local}; # Query query(); @@ -82,21 +82,70 @@ exit 0; # Functions # ################################################################################# -sub auth { - my $Answer = $Api->requestCredentials(accessRules => [ { - method => 'ALL', path => '/*', - }]); +sub ips() { + return grep defined map { + /^\s*inet (?:addr:)?([\d\.]+)/ and $1 ne "127.0.0.1" + ? $1 + : undef + } `ifconfig`; +} - die "Error" unless $Answer; - if ($Answer) { - my ($consumerKey, $validationUrl) = @{ $Answer->content}{qw{ consumerKey validationUrl }}; - # $validationUrl contains a link to OVH website in order to login an OVH account and link it to the credential - push @KEY, $consumerKey; - print "Go to $validationUrl\n"; - print "Your consumerKey is $consumerKey\n"; - print "Create ~/.ovh.api with permission 600 with\n".join(':',@KEY)."\n"; +sub ip2local { + require Sys::Hostname; + my ($ip) = @_; + + my $localhost = Sys::Hostname::hostname(); + + my $rec = _query("/ip/$ip") or exit 1; + + my $type = $rec->{type}; + $type eq 'failover' or die "$ip $type is not an ip failover!\n"; + + my $routed = $rec->{routedTo}{serviceName}; + $localhost ne $routed or die "$ip is already routed to $localhost!\n"; + + grep {$ip eq $_} ips() or die "$ip is is not installed on $localhost!\n"; + use Data::Dumper; + die Dumper([$localhost,$routed,$rec]); + local $_ = _query("/ip/$ip/move",'POST',{'to' => $localhost}); + print JSON::encode_json($_); + exit; +} + +sub _query { + + my ($url,$method,$body) = @_; + my %aliases = ( + '/server' => '/dedicated/server', + '/dns' => '/domain/zone', + ); + exists $aliases{$url} and $url = $aliases{$url}; + + my $response = $Api->rawCall(path=>$url,method=>($method||'GET'),body=>$body); + die "$NAME: ERR: ".$response->error() if $response->isFailure(); + + my $content = $response->content; + return unless defined $content; + unless (wantarray) { + #$content = check_row($url,$content); + return $content; } - exit + + my @rows; + for my $id (@$content) { + $id = check_row($url,$id); + next unless defined $id; + + $id =~ s,/.*$,,; + $response = $Api->rawCall(path=>$url.'/'.$id,method=>($method||'GET'),body=>{}); + die "$NAME: ERR: ".$response->error() if $response->isFailure(); + + + push @rows, $response->content; + } + #warn Dumper([$url,\@rows]); + + return @rows; } sub query { @@ -117,7 +166,7 @@ sub query { } my $response = $Api->rawCall(path=>$URL,method=>$Opt{method},body=>$BODY); - die "$NAME: ERR: ".$response->error()."\n" if $response->isFailure(); + die "$NAME: ERR: ".$response->error() if $response->isFailure(); my $content = $response->content; return unless defined $content; @@ -131,7 +180,7 @@ sub query { $id =~ s,/.*$,,; $response = $Api->rawCall(path=>$URL.'/'.$id,method=>$Opt{method},body=>{}); - die "$NAME: ERR: ".$response->error()."\n" if $response->isFailure(); + die "$NAME: ERR: ".$response->error() if $response->isFailure(); print ',' if $count > 0; @@ -198,17 +247,17 @@ my @tbs = ( }, ); + # + # Tables + # print "-- sqlite3: PRAGMA foreign_keys=OFF;\n"; print "BEGIN TRANSACTION;\n"; for my $tb (@tbs) { #warn $tb->{name}; - my $response = $Api->rawCall(path=>$tb->{path},method=>'GET',body=>{}); - die "$NAME: ERR: ".$response->error()."\n" if $response->isFailure(); + my $name =$preff.$tb->{name}; - print "--\n"; - print "-- > $name\n"; - #print "--\n"; + print "\n-- > $name\n"; print "CREATE TABLE IF NOT EXISTS $name (\n" .join(",\n",map {" $_->{sql}"} @{$tb->{fields}}) @@ -218,20 +267,17 @@ my @tbs = ( print 'CREATE INDEX IF NOT EXISTS '.$preff.$iname.' ON '.$preff.'server('.$tb->{indexes}{$iname}.");\n"; } - # Search rows - for my $id (@{ $response->content }) { - $id = check_row($tb->{path},$id); - next unless defined $id; - - my $response = $Api->rawCall(path=>$tb->{path}.'/'.$id,method=>'GET',body=>{}); - die "$NAME: ERR: ".$response->error()."\n" if $response->isFailure(); - - my %row = %{ $response->content }; - next unless %row; + # + # Rows + # + for ((_query($tb->{path}))) { + my %row = %$_; my @vals; - # Search fields + # + # Row Fields + # for my $fd (@{$tb->{fields}}) { my $val = $row{ $fd->{name} }; @@ -270,17 +316,34 @@ my @tbs = ( print "-- < $name\n"; } - print "COMMIT;\n"; + print "\nCOMMIT;\n"; exit; } sub check_row { - my ($URL,$id) = @_; - return undef if $URL eq '/ip' and $id !~ /\d+\./; + my ($url,$id) = @_; + return undef if $url eq '/ip' and $id !~ /\d+\./; $id =~ s,/.*$,,; return $id; } +sub auth { + my $Answer = $Api->requestCredentials(accessRules => [ { + method => 'ALL', path => '/*', + }]); + + die "Error" unless $Answer; + if ($Answer) { + my ($consumerKey, $validationUrl) = @{ $Answer->content}{qw{ consumerKey validationUrl }}; + # $validationUrl contains a link to OVH website in order to login an OVH account and link it to the credential + push @KEY, $consumerKey; + print "Go to $validationUrl\n"; + print "Your consumerKey is $consumerKey\n"; + print "Create ~/.ovh.api with permission 600 with\n".join(':',@KEY)."\n"; + } + exit +} + sub help { #------------------------------------------------------------------------------ # Print help and exit @@ -385,10 +448,12 @@ $NAME - Script to query ovh's api =head1 OPTIONS option[jq] Pipe stdout to | jq . - option[sql] Produce sql to update a database option[rows|r] Print each rows of a table (eg /ip, /server, ...) option[method|m=s] Method (default: GET) + option[sql] Produce sql to update a database + option[ip2local=s] Move IP to local + option[verbose|v+] Verbose mode: increase the verbosity level. option[debug+] Debug mode: increase the verbosity level. option[version|V] Print version (default: $VERSION) -- 2.47.3