#!/usr/bin/perl package main; use strict; use warnings; use v5.10; use Data::Dumper; use File::Basename; use HTTP::Cookies; use Try::Tiny; use XMLRPC::Lite; # +trace => 'all'; use JSON; # FIXME: put this in a config file my $addr = "https://api.domrobot.com/xmlrpc/"; #my $addr = "https://api.ote.domrobot.com/xmlrpc/"; my $usr = 'bluewind'; chomp(my $pwd = `getpw-single bluewind inwx.de`); if (@ARGV != 4) { say "usage: $0 "; exit 1; } my $domain = shift @ARGV; my $name = shift @ARGV; my $type = shift @ARGV; my $content = shift @ARGV; my $client = DomRobot->proxy($addr, cookie_jar => HTTP::Cookies->new(file => "$ENV{HOME}/.inwx-add-record.cookies", autosave => 1, ignore_discard => 1)); sub login { $client->call('account.login', { user => $usr, pass => $pwd }); my $TFAToken = getInput("Enter 2FA token (press enter if 2FA is not used)"); $TFAToken =~ s/ //g; $client->call('account.unlock', { tan => $TFAToken }) if $TFAToken ne ''; } #login(); #open(my $fh, '<', 'domains') or die "Failed to open: $!"; #while ($domain = <$fh>) { #chomp $domain; try { say "Processing $domain"; $client->setNameserverRecord($domain, $name, $type, $content); #$client->deleteNameserverRecord($domain, $name, $type); } catch { warn "ignoring error: $_"; }; #} #close $fh; #$client->logout; exit 0; sub getInput { my $question = shift; print STDERR $question.": "; chomp(my $input = ); return $input; } package DomRobot; # DomRobot is based on INWX' perl-client's DomRobot::Lite # Copyright (c) 2014 InterNetworX use strict; use warnings; use Data::Dumper; use HTTP::Cookies; use XMLRPC::Lite; BEGIN { @DomRobot::ISA = qw(XMLRPC::Lite); } sub new { my $class = shift; return $class if ref $class; my $self = $class->SUPER::new(@_); bless $self => $class; } sub call { my $self = shift; my ($method,$args) = @_; my $response = $self->SUPER::call($method,$args); if (ref($response->result) eq 'HASH' and $response->result->{code} != 1000) { # command failed die "Error: ".$response->result->{code}."\n".Dumper($method, $args, $response->result); } #print Dumper($response->result); return $response->result; } sub setNameserverRecord { my $self = shift; my $domain = shift; my $name = shift; my $type = shift; my $content = shift; my $existingID = $self->_findNameserverRecord($domain, $name, $type); if ($existingID) { $self->call('nameserver.updateRecord', { id => $existingID, content => $content, }); } else { $self->call('nameserver.createRecord', { domain => $domain, name => $name, type => $type, content => $content, }); } } sub deleteNameserverRecord { my $self = shift; my $domain = shift; my $name = shift; my $type = shift; my $existingID = $self->_findNameserverRecord($domain, $name, $type); if ($existingID) { $self->call('nameserver.deleteRecord', { id => $existingID, }); } } sub _findNameserverRecord { my $self = shift; my $domain = shift; my $name = shift; my $type = shift; my $r = $self->call('nameserver.info', {domain => $domain}); my $checkname = $domain; if ($name ne '') { $checkname = $name.".".$domain; } for my $record (@{$r->{resData}->{record}}) { if ($record->{name} eq $checkname and $record->{type} eq $type) { return $record->{id}; } } return undef; }