This is the code that I'm having trouble with... Adding domains
works, checking for availablility works. Inventory queries work.
Adding and/or deleting mailboxes does not work.
'major_text' => 'Unsupported action: query for object: manualprovision',
deleting domains does not work.
'response_text' => 'Authorization failed for user
[baremetal]. There are no actions to perform.',
Copyright... AFAIK, the starting point was public domain and sent
to me by Jason Slaughter at Tucows, assuming it was, I release my
enhancements to the public domain.
Note that you will need to change the RSP specific constants:
use constant USER_ID => 70571;
use constant CONTACT_ID => 350349;
-Tom
#! /usr/bin/perl
#
# This is a trivially simple example of some functions that might
# be used to provision Tucows Email Defense services. This should
# only be used as a reference until official Tucows client code
# is made available.
#
# It is suggested that unless you want to link these services to
# existing non-domain Tucows products (Certs, Tucows Email, DNS),
# then all Email Defense services should be created under the same
# user account in the Tucows system. Create one user account in
# the Tucows RWI (http://resellers2.opensrs.net/resellers)
# and hard-code the values of $user_id and $contact_id in the
# create/order API command, or, hard-code $user_id and add a new
# contact for each domain added.
#
# End-users will have their own separate usernames that are the same
# as their email username (defined here in the @users array).
use strict;
use Getopt::Std;
use vars qw($opt_a $opt_t $opt_i $opt_u $opt_d $opt_q $opt_D $opt_P $opt_A $opt_R);
die "no arguments!?"
unless (@ARGV);
getopts('dqatiuDPAR') or die "no commands?";
# -i = details for this inventory item number
# -u = contacts for the userid
# -a = service available for this domain?
# -t = test something...
# -d = debug mode... extra diagnostic displays
# -q = query inventory... just gets a list of item numbers..
# -D = DELETE inventory items
# -P domain mx_host user [user user ...] PROVISION service
# -A (add) inventory user [user user ...] - add mailboxes
# -R (remove) inventory user [user user ...] - remove mailboxes
BEGIN {
do "/home/opensrs-client-2.77/OpenSRS.conf";
}
use constant USER_ID => 70571;
use constant CONTACT_ID => 350349;
use Data::Dumper;
use strict;
use lib $PATH_LIB;
use OpenSRS::TPP_Client;
use OpenSRS::ResponseConverter;
use OpenSRS::Util::Common qw(send_email build_select_menu build_select_menu3
build_country_list CODE_2_Country);
my $TPP_Client = new OpenSRS::TPP_Client(
%OPENSRS,
response_converter => new OpenSRS::ResponseConverter(),
);
$TPP_Client->login;
sub purchase_email_defense {
my ($domain, $mx_server, @users) = @_;
# why pass these as parameters if they are supposed to be hard coded?
my $user_id = USER_ID; # antispam
my $contact_id = CONTACT_ID;
my $mx_preference = 1; # another, duh, why pass this. (if it was a list...)
my $mx_port = 25;
my $xcp_request = {
version => 1.4.0,
action => "create",
object => "order",
requestor => {
username => $OPENSRS{'username'}
},
attributes => {
service => 'emaildefense',
user_id => $user_id,
client_reference => 'bulk_procurement-baremetal',
handling => 'process',
contacts => [
{
contact_id => $contact_id
}
],
create_items => [
{
service => 'emaildefense',
object_type => 'manualprovision',
order_item_type => 'new',
product_data => {
domain => $domain,
feature_set => [ "AntiSpam" ],
mtas => [
{
preference => $mx_preference ,
port => $mx_port,
host => $mx_server ,
},
],
accounts => [
# {
# name => $username,
# role => 'end_user'
# }
],
},
contact_set => {
owner => 0,
}
}
],
}
};
# tweaks. The first user gets a password of antispam and the domain_admin
# role. No one else gets passwords, which means they can't login directly.
for (my $i = 0; $i < scalar(@users); $i++) {
$xcp_request->{'attributes'}{'create_items'}[0]{'product_data'}{'accounts'}[$i]{'name'}
= $users[$i];
$xcp_request->{'attributes'}{'create_items'}[0]{'product_data'}{'accounts'}[$i]{'role'}
= $i ? 'end_user' : 'domain_admin';
$xcp_request->{'attributes'}{'create_items'}[0]{'product_data'}{'accounts'}[$i]{'password'}
= '6yBLKe' if ($i == 0); # first user
}
my $response = $TPP_Client->send_cmd($xcp_request);
print Dumper($response);
if (1 == $response->{'is_success'}) {
return 1;
} else {
error_log($response->{'response_text'});
return 0;
}
}
sub check_email_defense_availability {
my $domain = shift;
my $xcp_request = {
version => 1.3,
action => 'check',
object => 'emaildefense.domain',
requestor => {
username => $OPENSRS{'username'}
},
attributes => {
service => 'emaildefense',
product_data => {
domain => $domain
}
}
};
my $response = $TPP_Client->send_cmd($xcp_request);
print Dumper(\$response),"\n";
if (1 == $response->{'is_success'}) {
if (1 == $response->{'attributes'}->{'product_data'}->{'is_available'}) {
return 1;
}
} else {
error_log($response->{'response_text'});
}
return 0;
}
sub cancel_email_defense {
my $domain = shift;
my $xcp_request = {
'protocol' => 'TPP',
'object' => 'inventory_item.emaildefense',
'version' => '1.4.0',
'action' => 'delete',
'requestor' => { 'username' => $OPENSRS{'username'} },
'attributes' => {
'inventory_items' => [ { 'inventory_item_id' => '13565' } ]
}
};
}
#
# Do something useful here that calls the functions above
#
if ( 0 ) {
} elsif($opt_P) {
my ($domain, $mx, @users) = @ARGV;
die "$domain doesn't look like a domain name!"
unless ($domain =~ m/\.[a-z0-9\-]{2,4}$/i );
die "$mx doesn't look like a mailhost name!"
unless ($mx =~ m/\.[a-z0-9\-]{2,4}$/i );
die "you must specify at least one mailbox"
unless @users;
purchase_email_defense( $domain, $mx, @users);
} elsif($opt_A) {
my ($inv, @users) = @ARGV;
die "first parameter doesn't look like an inventory number"
unless ($inv =~ m/^\d+$/);
die "can't add zero mailboxes!?" unless @users;
add_mailboxes($inv,@users);
} elsif($opt_R) {
my ($inv, @users) = @ARGV;
die "first parameter doesn't look like an inventory number"
unless ($inv =~ m/^\d+$/);
die "can't remove zero mailboxes!?" unless @users;
remove_mailboxes($inv,@users);
} elsif($opt_q) {
inventory( ) if ($opt_q);
} else {
foreach my $arg (@ARGV) {
if ($opt_a) {
my $avail = check_email_defense_availability($arg);
print "availability for $arg = $avail\n";
}
if ($opt_t) {
mytest();
exit;
}
inventory( item_id => $arg ) if ($opt_i);
inventory( contact_id => $arg ) if $opt_u;
delete_domain( $arg ) if ($opt_D);
print "done arg: $arg\n";
}
}
print "Done.\n";
exit;
sub inventory {
my %params = @_;
my $att = {
query_name => 'inventory_items.created.by_user_id',
conditions => [
{
type => 'simple',
field => 'user_id',
operand => {
eq => USER_ID
},
} ],
};
$att = {
query_name => 'inventory_item.by_id',
conditions => [ {
type => 'simple',
field => 'inventory_item_id',
operand => {
eq => $params{item_id}
},
}],
} if ($params{item_id});
$att = {
query_name => 'contacts.by_user_id',
conditions => [ {
type => 'simple',
field => 'user_id',
operand => {
eq => $params{contact_id}
},
} ]
} if ($params{contact_id});
my $xcp_request = {
'protocol' => 'TPP',
'object' => 'query',
'version' => '1.4.0',
'action' => 'execute',
'requestor' => { 'username' => $OPENSRS{'username'} },
attributes => $att,
};
my $response = $TPP_Client->send_cmd($xcp_request);
use Data::Dumper;
if ($opt_d or !$response->{is_success} ) {
print "inventory response= ", Dumper(\$response),"\n";
print "inventory request= ", Dumper(\$xcp_request),"\n"
}
my $ref = $response->{attributes}->{result};
if (!$ref) {
print "No inventory, have you provisioned anything?\n";
} else {
if (! %params) { # just get the item numbers..
foreach my $hr (@$ref) {
printf "%d %s (%s)\n",
$hr->{inventory_item_id},
$hr->{description},
$hr->{service};
}
} elsif ($params{item_id}) {
foreach my $hr (@$ref) {
printf "inventory: %d\n", $hr->{inventory_item_id};
printf "description: %s\n", $hr->{description};
foreach my $mta (@{$hr->{product_data}->{mtas}}) {
printf "mx: %s:%d\n", $mta->{host}, $mta->{port};
}
foreach my $account (@{$hr->{product_data}->{accounts}}) {
my $feat = join(' ', @{$account->{feature_set}});
printf " %s/%s (%s) %s\n",
$account->{name},
$account->{password},
$account->{role},
$feat;
}
}
} elsif ($params{contact_id}) {
# print "inventory response= ", Dumper(\$response),"\n";
foreach my $contact (@$ref) {
printf "----\n";
printf "user_id: %d\n", $contact->{user_id};
printf "contact_id: %d\n", $contact->{contact_id};
printf "parent_id: %d\n", $contact->{parent_id};
printf "name: %s %s\n", $contact->{first_name},
$contact->{last_name};
printf "email: %s\n", $contact->{email};
}
} else {
print "ugh, what parameter got specified!?\n";
}
}
}
sub delete_domain {
my ($inv_no) = @_;
my $xcp_request = {
'protocol' => 'TPP',
'object' => 'inventory_item.emaildefense',
'version' => '1.4.0',
'action' => 'delete',
'requestor' => { 'username' => $OPENSRS{'username'} },
'attributes' => {
'inventory_items' => [ { 'inventory_item_id' => $inv_no } ]
}
};
my $response = $TPP_Client->send_cmd($xcp_request);
print "delete request= ", Dumper(\$xcp_request),"\n"
unless ($response->{is_success});
print "delete response= ", Dumper(\$response),"\n";
}
sub add_mailboxes {
my ($inventory, @boxes) = @_;
my $xcp_request = {
'protocol' => 'TPP',
'object' => 'order',
'version' => '1.4.0',
'action' => 'create',
'requestor' => { 'username' => $OPENSRS{'username'} },
'attributes' => {
'contacts' => [ { 'contact_id' => CONTACT_ID } ],
'create_items' => [ {
'product_data' => {
'update_feature_set' => {},
'add_accounts' => {
# 'feature_set' => [ 'AntiSpam' ],
'accounts' => [ ]
}
},
'object_type' => 'manualprovision',
'contact_set' => { 'owner' => '0' }, # ref to
contacts above
'orderitem_type' => 'upgrade', #
new/upgrade/downgrade
'service' => 'emaildefense',
'inventory_item_id' => $inventory }
],
'user_id' => USER_ID,
'service' => 'emaildefense',
'handling' => 'process'
}
};
foreach my $mbox (@boxes) {
my $ref =
$xcp_request->{attributes}->{create_items}->[0]->{product_data}->{add_accounts}->{accounts};
die "reference extraction failed" unless $ref;
push (@$ref, { name => $mbox, role => 'end_user' } );
}
my $response = $TPP_Client->send_cmd($xcp_request);
print "delete request= ", Dumper(\$xcp_request),"\n"
unless ($response->{is_success});
print "delete response= ", Dumper(\$response),"\n";
}
sub remove_mailboxes {
my ($inv, @boxes) = @_;
my $xcp_request = {
'protocol' => 'TPP',
'object' => 'order',
'version' => '1.4.0',
'action' => 'create',
'requestor' => { 'username' => $OPENSRS{'username'} },
'attributes' => {
'user_id' => USER_ID,
'service' => 'emaildefense',
'handling' => 'process',
'contacts' => [ { 'contact_id' => CONTACT_ID } ],
'data' => 'full',
'create_items' => [ {
'object_type' => 'manualprovision',
'orderitem_type' => 'downgrade',
'service' => 'emaildefense',
'inventory_item_id' => $inv,
'contact_set' => { 'owner' => '0' },
'product_data' => {
'delete_accounts' => { 'accounts' => [] }, #
fill in later
'update_feature_set' => {}
},
} ],
}
};
foreach my $mbox (@boxes) {
my $ref =
$xcp_request->{attributes}->{create_items}->[0]->{product_data}->{delete_accounts}->{accounts};
die "reference extraction failed" unless $ref;
push (@$ref, { name => $mbox } );
}
my $response = $TPP_Client->send_cmd($xcp_request);
print "delete request= ", Dumper(\$xcp_request),"\n"
unless ($response->{is_success});
print "delete response= ", Dumper(\$response),"\n";
}