package FS::part_export::saisei;
use strict;
-use base qw( FS::part_export );
use vars qw( @ISA %info );
+use base qw( FS::part_export );
use Date::Format 'time2str';
use Cpanel::JSON::XS;
-use Net::HTTPS::Any qw(https_post);
use MIME::Base64;
use REST::Client;
use Data::Dumper;
-
use FS::Conf;
-#@ISA = qw( FS::part_export::http );
-
=pod
=head1 NAME
This export offers basic svc_broadband provisioning for Saisei.
+This is a customer integration with Saisei. This will setup a rate plan and tie
+the rate plan to a host via the Saisei API when the broadband service is provisioned.
+It will also untie the rate plan via the API upon unprovisioning of the broadband service.
+
+This export will use the broadband service descriptive label for the Saisei rate plan name and
+will use the email from the first contact for the Saisei username that will be
+attached to this rate plan. It will use the Saisei default Access Point.
+
+Hostname or IP - Host name to Saisei API
+Port - <I>Port number to Saisei API
+User Name - <I>Saisei API user name
+Password - <I>Saisei API password
+
This module also provides generic methods for working through the L</Saisei API>.
=cut
tie my %options, 'Tie::IxHash',
+ 'port' => { label => 'Port',
+ default => 5000 },
'username' => { label => 'User Name',
default => '' },
'password' => { label => 'Password',
default => '' },
- 'host' => { label => 'Host',
- default => 'STM IP ADDRESS' },
- 'port' => { label => 'Port',
- default => 5000 },
- 'customer_name' => { label => 'Customer Name',
- default => 'FREESIDE CUST $custnum' },
- 'account_id' => { label => 'Account ID',
- default => 'SVC$svcnum' },
- 'product_id' => { label => 'Account Product ID' },
'debug' => { type => 'checkbox',
label => 'Enable debug warnings' },
;
'desc' => 'Export broadband service/account to Saisei',
'options' => \%options,
'notes' => <<'END',
-This is customer integration with Saisei.
+This is a customer integration with Saisei. This will setup a rate plan and tie
+the rate plan to a host via the Saisei API when the broadband service is provisioned.
+It will also untie the rate plan via the API upon unprovisioning of the broadband service.
+<P>This export will use the broadband service descriptive label for the Saisei rate plan name and
+will use the email from the first contact for the Saisei username that will be
+attached to this rate plan. It will use the Saisei default Access Point.
+<P>
+Required Fields:
+<UL>
+<LI>Hostname or IP - <I>Host name to Saisei API</I></LI>
+<LI>Port - <I>Port number to Saisei API</I></LI>
+<LI>User Name - <I>Saisei API user name</I></LI>
+<LI>Password - <I>Saisei API password</I></LI>
+</UL>
END
);
-#"/STM_IP:5000/rest/top/configurations/running/" is for http 5029 for https
-
-#Creating User Names
-#Users are tracked by their name which gives access to the internal slice data which in turn allows the viewing of Applications and Geo-Locations.
-#Creating a user name requires a command of the following format: -
-#'put', 'users/USER_NAME', {'description':description}
-#When creating a user name it is usual to add a description and since a user attribute set does not normally contain the users plan name it is best to encode it into the description field.
-
sub _export_insert {
my ($self, $svc_broadband) = @_;
my $rateplan_name = $svc_broadband->{Hash}->{description};
my $username = $email[0];
my $description = $cust_main->{Hash}->{first}." ".$cust_main->{Hash}->{last};
- # check for existing user.
- my $existing_user;
- $existing_user = $self->api_get_user($username) unless ( $self->{'__saisei_error'} || !$username);
+ if (!$username) {
+ $self->{'__saisei_error'} = 'no username - can not export';
+ warn "No email found $username\n" if $self->option('debug');
+ return;
+ }
+ else {
+ # check for existing user.
+ my $existing_user;
+ $existing_user = $self->api_get_user($username) unless $self->{'__saisei_error'};
- # if no existing user create one.
- $self->api_create_user($username, $description) unless $existing_user;
+ # if no existing user create one.
+ $self->api_create_user($username, $description) unless $existing_user;
- # set user to existing one or newly created one.
- my $user = $existing_user ? $existing_user : $self->api_get_user($username);
+ # set user to existing one or newly created one.
+ my $user = $existing_user ? $existing_user : $self->api_get_user($username);
- ## add access point ?
+ ## add access point ?
- ## tie host to user
- $self->api_add_host_to_user($user->{collection}->[0]->{name}, $rateplan->{collection}->[0]->{name}, $svc_broadband->{Hash}->{ip_addr}) unless $self->{'__saisei_error'};
+ ## tie host to user
+ $self->api_add_host_to_user($user->{collection}->[0]->{name}, $rateplan->{collection}->[0]->{name}, $svc_broadband->{Hash}->{ip_addr}) unless $self->{'__saisei_error'};
+ }
- #die('ending for testing');
return '';
}
=head2 api_call
-Accepts I<$service>, I<$method>, I<$params> hashref and optional
-I<$returnfield>. Places an api call to the specified service
-and method with the specified params. Returns the decoded json
-object returned by the api call. If I<$returnfield> is specified,
-returns only that field of the decoded object, and errors out if
-that field does not exist. Returns empty on failure; retrieve
-error messages using L</api_error>.
-
-Must run L</api_login> first.
+Accepts I<$method>, I<$path>, I<$params> hashref and optional.
+Places an api call to the specified path and method with the specified params.
+Returns the decoded json object returned by the api call.
+Returns empty on failure; retrieve error messages using L</api_error>.
=cut
my $auth_info = $self->option('username') . ':' . $self->option('password');
$params ||= {};
- print "Calling /$method\n" if $self->option('debug');
+ warn "Calling $method on http://"
+ .$self->{Hash}->{machine}.':'.$self->option('port')
+ ."/rest/stm/configurations/running/$path\n" if $self->option('debug');
my $data = encode_json($params) if keys %{ $params };
my $client = REST::Client->new();
$client->addHeader("Authorization", "Basic ".encode_base64($auth_info));
- $client->setHost('http://'.$self->option('host').':'.$self->option('port'));
- $client->$method('/rest/stm/configurations/running/'.$path, $data, { "Content-type" => 'application/json'});
+ $client->setHost('http://'.$self->{Hash}->{machine}.':'.$self->option('port'));
+ $client->$method('/rest/stm/configurations/running'.$path, $data, { "Content-type" => 'application/json'});
+
+ warn "Response Code is ".$client->responseCode()."\n" if $self->option('debug');
my $result;
}
else {
$self->{'__saisei_error'} = "Bad response from server during $method: " . $client->responseContent();
- print "My response content fo /$method\n". Dumper($client->responseContent) if $self->option('debug');
+ warn "Response Content is\n".$client->responseContent."\n" if $self->option('debug');
return;
}
sub api_get_policies {
my $self = shift;
- my $get_policies = $self->api_call("GET", 'policies/?token=1&order=name&start=0&limit=20&select=name%2Cpercent_rate%2Cassured%2C');
+ my $get_policies = $self->api_call("GET", '/policies/?token=1&order=name&start=0&limit=20&select=name%2Cpercent_rate%2Cassured%2C');
return if $self->api_error;
$self->{'__saisei_error'} = "Did not receive any global policies"
unless $get_policies;
my $self = shift;
my $rateplan = shift;
- my $get_rateplan = $self->api_call("GET", "rate_plans/$rateplan");
+ my $get_rateplan = $self->api_call("GET", "/rate_plans/$rateplan");
return if $self->api_error;
$self->{'__saisei_error'} = "Did not receive any rateplan info"
unless $get_rateplan;
my $self = shift;
my $user = shift;
- my $get_user = $self->api_call("GET", "users/$user");
+ my $get_user = $self->api_call("GET", "/users/$user");
return if $self->api_error;
$self->{'__saisei_error'} = "Did not receive any user info"
unless $get_user;
my $self = shift;
my $accesspoint;
- my $get_accesspoint = $self->api_call("GET", "access_points/$accesspoint");
+ my $get_accesspoint = $self->api_call("GET", "/access_points/$accesspoint");
return if $self->api_error;
$self->{'__saisei_error'} = "Did not receive any user info"
unless $get_accesspoint;
my $new_rateplan = $self->api_call(
"PUT",
- "rate_plans/$rateplan",
+ "/rate_plans/$rateplan",
{
'downstream_rate' => $svc->{Hash}->{speed_down},
'upstream_rate' => $svc->{Hash}->{speed_up},
if ($policy->{background}) { $rate_multiplier = ".01"; }
my $modified_rateplan = $self->api_call(
"PUT",
- "rate_plans/$rateplan_name/partitions/$policyname",
+ "/rate_plans/$rateplan_name/partitions/$policyname",
{
'restricted' => $policy->{assured}, # policy_assured_flag
'rate_multiplier' => $rate_multiplier, # policy_background 0.1
=head2 api_create_user
-Creates a rateplan.
+Creates a user.
=cut
my $new_user = $self->api_call(
"PUT",
- "users/$user",
+ "/users/$user",
{
'description' => $description,
},
sub api_create_accesspoint {
my ($self,$accesspoint) = @_;
- my $new_accesspoint = $self->api_call(
- "PUT",
- "access_points/$accesspoint",
- {
- 'description' => 'my description',
- },
- );
-
- $self->{'__saisei_error'} = "Access point not created"
- unless $new_accesspoint; # should never happen
+ # this has not been tested, but should work, if needed.
+ #my $new_accesspoint = $self->api_call(
+ # "PUT",
+ # "/access_points/$accesspoint",
+ # {
+ # 'description' => 'my description',
+ # },
+ #);
+
+ #$self->{'__saisei_error'} = "Access point not created"
+ # unless $new_accesspoint; # should never happen
return;
}
=head2 api_add_host_to_user
-ties host to user and rateplan.
+ties host to user, rateplan and default access point.
=cut
my $new_host = $self->api_call(
"PUT",
- "hosts/$ip",
+ "/hosts/$ip",
{
'user' => $user,
'rate_plan' => $rateplan,
}
-=head2 api_add_host_to_user
+=head2 api_delete_host_to_user
-ties host to user and rateplan.
+unties host to user and rateplan.
=cut
sub api_delete_host_to_user {
my ($self,$user, $rateplan, $ip) = @_;
- my $delete_host = $self->api_call("DELETE", "hosts/$ip");
+ my $default_rate_plan = $self->api_call("GET", '?token=1&select=default_rate_plan');
+ return if $self->api_error;
+ $self->{'__saisei_error'} = "Did not receive a default rate plan"
+ unless $default_rate_plan;
+
+ my $default_rateplan_name = $default_rate_plan->{collection}->[0]->{default_rate_plan}->{link}->{name};
+
+ my $delete_host = $self->api_call(
+ "PUT",
+ "/hosts/$ip",
+ {
+ 'user' => '<none>',
+ 'access_point' => '<none>',
+ 'rate_plan' => $default_rateplan_name,
+ },
+ );
$self->{'__saisei_error'} = "Host not created"
unless $delete_host; # should never happen