[freeside-commits] branch master updated. 026a1022bd40dc18055e8bef97e7027051af083f

Ivan ivan at 420.am
Fri May 4 21:24:44 PDT 2012


The branch, master has been updated
       via  026a1022bd40dc18055e8bef97e7027051af083f (commit)
      from  7f2da0c0259bfde6ee3b0d26a62c9663e00a6e77 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 026a1022bd40dc18055e8bef97e7027051af083f
Author: Ivan Kohler <ivan at freeside.biz>
Date:   Fri May 4 21:24:43 2012 -0700

    add XML-RPC export, RT#17622

diff --git a/FS/FS/part_export/acct_xmlrpc.pm b/FS/FS/part_export/acct_xmlrpc.pm
new file mode 100644
index 0000000..d746f29
--- /dev/null
+++ b/FS/FS/part_export/acct_xmlrpc.pm
@@ -0,0 +1,268 @@
+package FS::part_export::acct_xmlrpc;
+use base qw( FS::part_export );
+
+use vars qw( %info ); # $DEBUG );
+#use Data::Dumper;
+use Tie::IxHash;
+use Frontier::Client; #to avoid adding a dependency on RPC::XML just now
+#use FS::Record qw( qsearch qsearchs );
+use FS::Schema qw( dbdef );
+
+#$DEBUG = 1;
+
+tie my %options, 'Tie::IxHash',
+  'xmlrpc_url'       => { label => 'XML-RPC URL', },
+  'param_style'      => { label   => 'Parameter style',
+                          type    => 'select',
+                          options => [ 'Individual values',
+                                       'Struct of name/value pairs',
+                                     ],
+                        },
+  'insert_method'    => { label => 'Insert method', },
+  'insert_params'    => { label => 'Insert parameters', type=>'textarea', },
+  'replace_method'   => { label => 'Replace method', },
+  'replace_params'   => { label => 'Replace parameters', type=>'textarea', },
+  'delete_method'    => { label => 'Delete method', },
+  'delete_params'    => { label => 'Delete parameters', type=>'textarea', },
+  'suspend_method'   => { label => 'Suspend method', },
+  'suspend_params'   => { label => 'Suspend parameters', type=>'textarea', },
+  'unsuspend_method' => { label => 'Unsuspend method', },
+  'unsuspend_params' => { label => 'Unsuspend parameters', type=>'textarea', },
+;
+
+%info = (
+  'svc'     => 'svc_acct',
+  'desc'    => 'Configurable provisioning of accounts via the XML-RPC protocol',
+  'options' => \%options,
+  'notes'   => <<'END',
+Configurable, real-time export of accounts via the XML-RPC protocol.<BR>
+<BR>
+If using "Individual values" parameter style, specfify one parameter per line.<BR>
+<BR>
+If using "Struct of name/value pairs" parameter style, specify one name and
+value on each line, separated by whitespace.<BR>
+<BR>
+The following variables are available for interpolation (prefixed with new_ or
+old_ for replace operations):
+<UL>
+  <LI><code>$username</code>
+  <LI><code>$_password</code>
+  <LI><code>$crypt_password</code> - encrypted password
+  <LI><code>$ldap_password</code> - Password in LDAP/RFC2307 format (for example, "{PLAIN}himom", "{CRYPT}94pAVyK/4oIBk" or "{MD5}5426824942db4253f87a1009fd5d2d4")
+  <LI><code>$uid</code>
+  <LI><code>$gid</code>
+  <LI><code>$finger</code> - Real name
+  <LI><code>$dir</code> - home directory
+  <LI><code>$shell</code>
+  <LI><code>$quota</code>
+  <LI><code>@radius_groups</code>
+<!--  <LI><code>$reasonnum (when suspending)</code>
+  <LI><code>$reasontext (when suspending)</code>
+  <LI><code>$reasontypenum (when suspending)</code>
+  <LI><code>$reasontypetext (when suspending)</code>
+-->
+<!--
+  <LI><code>$pkgnum</code>
+  <LI><code>$custnum</code>
+-->
+  <LI>All other fields in <b>svc_acct</b> are also available.
+<!--  <LI>The following fields from <b>cust_main</b> are also available (except during replace): company, address1, address2, city, state, zip, county, daytime, night, fax, otaker, agent_custid, locale. -->
+</UL>
+
+END
+);
+
+sub _export_insert    { shift->_export_command('insert',    @_) }
+sub _export_delete    { shift->_export_command('delete',    @_) }
+sub _export_suspend   { shift->_export_command('suspend',   @_) }
+sub _export_unsuspend { shift->_export_command('unsuspend', @_) }
+
+sub _export_command {
+  my ( $self, $action, $svc_acct) = (shift, shift, shift);
+  my $method = $self->option($action.'_method');
+  return '' if $method =~ /^\s*$/;
+
+  my @params = split("\n", $self->option($action.'_params') );
+
+  my( @x_param ) = ();
+  my( %x_struct ) = ();
+  foreach my $param (@params) {
+
+    my($name, $value) = ('', '');
+    if ($self->option('param_style') eq 'Struct of name/value pairs' ) {
+      ($name, $value) = split(/\s+/, $param);
+    } else { #'Individual values'
+      $value = $param;
+    }
+
+    if ( $value =~ /^\s*(\$|\@)(\w+)\s*$/ ) {
+      $value = $self->_export_value($2, $svc_acct);
+    }
+
+    if ($self->option('param_style') eq 'Struct of name/value pairs' ) {
+      $x_struct{$name} = $value;
+    } else { #'Individual values'
+      push @x_param, $value;
+    }
+
+  }
+
+  my @x = ();
+  if ($self->option('param_style') eq 'Struct of name/value pairs' ) {
+    @x = ( \%x_struct );
+  } else { #'Individual values'
+    @x = @x_param;
+  }
+
+  #option to queue (or not) ?
+
+  my $conn = Frontier::Client->new( url => $self->option('xmlrpc_url') );
+
+  my $result = $conn->call($method, @x);
+
+  #XXX error checking?  $result?  from the call?
+  '';
+}
+
+sub _export_replace {
+  my( $self, $new, $old ) = (shift, shift, shift);
+
+  my $method = $self->option($action.'_method');
+  return '' if $method =~ /^\s*$/;
+
+  my @params = split("\n", $self->option($action.'_params') );
+
+  my( @x_param ) = ();
+  my( %x_struct ) = ();
+  foreach my $param (@params) {
+
+    my($name, $value) = ('', '');
+    if ($self->option('param_style') eq 'Struct of name/value pairs' ) {
+      ($name, $value) = split(/\s+/, $param);
+    } else { #'Individual values'
+      $value = $param;
+    }
+
+    if ( $value =~ /^\s*(\$|\@)(old|new)_(\w+)\s*$/ ) {
+      if ($2 eq 'old' ) {
+        $value = $self->_export_value($3, $old);
+      } elsif ( $2 eq 'new' ) {
+        $value = $self->_export_value($3, $new);
+      } else {
+        die 'guru meditation stella blue';
+      }
+    }
+
+    if ($self->option('param_style') eq 'Struct of name/value pairs' ) {
+      $x_struct{$name} = $value;
+    } else { #'Individual values'
+      push @x_param, $value;
+    }
+
+  }
+
+  my @x = ();
+  if ($self->option('param_style') eq 'Struct of name/value pairs' ) {
+    @x = ( \%x_struct );
+  } else { #'Individual values'
+    @x = @x_param;
+  }
+
+  #option to queue (or not) ?
+
+  my $conn = Frontier::Client->new( url => $self->option('xmlrpc_url') );
+
+  my $result = $conn->call($method, @x);
+
+  #XXX error checking?  $result?  from the call?
+  '';
+
+}
+
+#comceptual false laziness w/shellcommands.pm
+sub _export_value {
+  my( $self, $value, $svc_acct) = (shift, shift, shift);
+
+  my %fields = map { $_=>1 } $svc_acct->fields;
+
+  if ( $fields{$value} ) {
+    my $type = dbdef->table('svc_acct')->column($value)->type;
+    if ( $type =~ /^(int|serial)/i ) {
+      return Frontier::Client->new->int( $svc_acct->$value() );
+    } elsif ( $value =~ /^last_log/ ) {
+      return Frontier::Client->new->date_time( $svc_acct->$value() ); #conversion?
+    } else {
+      return Frontier::Client->new->string( $svc_acct->$value() );
+    }
+  } elsif ( $value eq 'domain' ) {
+    return Frontier::Client->new->string( $svc_acct->domain );
+  } elsif ( $value eq 'crypt_password' ) {
+    return Frontier::Client->new->string( $svc_acct->crypt_password( $self->option('crypt') ) );
+  } elsif ( $value eq 'ldap_password' ) {
+    return Frontier::Client->new->string( $svc_acct->ldap_password($self->option('crypt') ) );
+  } elsif ( $value eq 'radius_groups' ) {
+    my @radius_groups = $svc_acct->radius_groups;
+    #XXX
+  }
+
+#  my $cust_pkg = $svc_acct->cust_svc->cust_pkg;
+#  if ( $cust_pkg ) {
+#    no strict 'vars';
+#    {
+#      no strict 'refs';
+#      foreach my $custf (qw( company address1 address2 city state zip country
+#                             daytime night fax otaker agent_custid locale
+#                        ))
+#      {
+#        ${$custf} = $cust_pkg->cust_main->$custf();
+#      }
+#    }
+#    $email = ( grep { $_ !~ /^(POST|FAX)$/ } $cust_pkg->cust_main->invoicing_list )[0];
+#  } else {
+#    $email = '';
+#  }
+
+#  my ($reasonnum, $reasontext, $reasontypenum, $reasontypetext);
+#  if ( $cust_pkg && $action eq 'suspend' &&
+#       (my $r = $cust_pkg->last_reason('susp')) )
+#  {
+#    $reasonnum = $r->reasonnum;
+#    $reasontext = $r->reason;
+#    $reasontypenum = $r->reason_type;
+#    $reasontypetext = $r->reasontype->type;
+#
+#    my %reasonmap = $self->_groups_susp_reason_map;
+#    my $userspec = '';
+#    $userspec = $reasonmap{$reasonnum}
+#      if exists($reasonmap{$reasonnum});
+#    $userspec = $reasonmap{$reasontext}
+#      if (!$userspec && exists($reasonmap{$reasontext}));
+#
+#    my $suspend_user;
+#    if ( $userspec =~ /^\d+$/ ) {
+#      $suspend_user = qsearchs( 'svc_acct', { 'svcnum' => $userspec } );
+#    } elsif ( $userspec =~ /^\S+\@\S+$/ ) {
+#      my ($username,$domain) = split(/\@/, $userspec);
+#      for my $user (qsearch( 'svc_acct', { 'username' => $username } )){
+#        $suspend_user = $user if $userspec eq $user->email;
+#      }
+#    } elsif ($userspec) {
+#      $suspend_user = qsearchs( 'svc_acct', { 'username' => $userspec } );
+#    }
+#  
+#  @radius_groups = $suspend_user->radius_groups
+#    if $suspend_user;  
+#  
+#  } else {
+#    $reasonnum = $reasontext = $reasontypenum = $reasontypetext = '';
+#  }
+
+#  $pkgnum = $cust_pkg ? $cust_pkg->pkgnum : '';
+#  $custnum = $cust_pkg ? $cust_pkg->custnum : '';
+
+  '';
+
+}
+
+1;
+

-----------------------------------------------------------------------

Summary of changes:
 FS/FS/part_export/acct_xmlrpc.pm |  268 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 268 insertions(+), 0 deletions(-)
 create mode 100644 FS/FS/part_export/acct_xmlrpc.pm




More information about the freeside-commits mailing list