Years ago I used to use a script to do just that. I no longer use it and I'm not sure it will work with the current versions. But few free to have a look and try to adapt it to your needs. It assumes the containers are organized like Universe:Country:State:City:SITEID, where siteid is a 6 letters code.
use strict;
use warnings;
use autodie;
use REST::Client;
use JSON;
use Data::Dumper;
use URI::Escape;
use XML::LibXML;
our $VERSION = 0.2;
my $hostspectrum = 'http:
my $hostcapc = 'http:
my $xml = <<"EOF";
<?xml version="1.0" encoding="UTF-8"?>
<rs:model-request throttlesize="9999"
xmlns:rs="http:
xmlns:xsi="http:
xsi:schemaLocation="http:
<rs:target-models>
<rs:models-search>
<rs:search-criteria xmlns="http://www.ca.com/spectrum/restful/schema/filter">
<filtered-models>
<and>
<is-derived-from>
<model-type>0x1004b</model-type>
</is-derived-from>
<has-pcre>
<attribute id="0x129e7">
<value>^Universe:.*?:.*?:.*?:......-.*</value>
</attribute>
</has-pcre>
</and>
</filtered-models>
</rs:search-criteria>
</rs:models-search>
</rs:target-models>
<rs:requested-attribute id="0x1006e"/>
<rs:requested-attribute id="0x129e7"/>
<rs:requested-attribute id="0x12d7f"/>
</rs:model-request>
EOF
my $url = '/spectrum/restful/models';
my $client = REST::Client->new();
$client->setHost($hostspectrum);
$client->addHeader( 'Accept', 'application/xml' );
$client->addHeader( 'Content-Type', 'application/xml; charset=UTF-8' );
$client->POST( $url, $xml );
if ( $client->responseCode() ne '200' ) {
print $client->responseCode() . "\n" . $client->responseContent() . "\n";
exit 1;
}
my $doc = XML::LibXML->load_xml( string => $client->responseContent() );
my $root = $doc->documentElement();
my %devices;
my %groups;
my %cagroups;
my %sites;
my %siteexists;
my %sitename;
$sitename{SITEA} = "Site A";
$sitename{SITEB} = "Site B";
for my $model ( $root->findnodes('
next if ( !$model->findnodes('.
next if ( !$model->findnodes('.
next if ( !$model->findnodes('.
my $name = $model->findnodes('.
my $ip = $model->findnodes('.
my $topo = $model->findnodes('.
$topo =~ /^Universe:(.*?):(.*?):(.*?):((......)-.*)/;
my ( $co, $st, $ci, $site, $siteid ) = ( $1, $2, $3, $4, $5 );
my $group = "/All Groups/Universe/$co/$st/$ci/$siteid";
$devices{$ip}{sname} = $name;
$devices{$ip}{group} = $group;
$devices{$ip}{site} = $site;
$groups{$co}{$st}{$ci}{$siteid} = $site;
}
$xml = <<"EOF";
<?xml version="1.0" encoding="UTF-8"?>
<rs:model-request throttlesize="9999"
xmlns:rs="http:
xmlns:xsi="http:
xsi:schemaLocation="http:
<rs:target-models>
<rs:models-search>
<rs:search-criteria
xmlns="http:
<filtered-models>
<and>
<has-pcre>
<model-name>^......-</model-name>
</has-pcre>
<or>
<equals>
<model-type>0x1002e</model-type>
</equals>
<equals>
<model-type>0x1002f</model-type>
</equals>
</or>
<has-pcre>
<attribute id="0x129e7">
<value>^Universe:.*?:.*?:[^:]*</value>
</attribute>
</has-pcre>
</and>
</filtered-models>
</rs:search-criteria>
</rs:models-search>
</rs:target-models>
<rs:requested-attribute id="0x1006e" />
<rs:requested-attribute id="0x129e7" />
</rs:model-request>
EOF
$client->POST( $url, $xml );
if ( $client->responseCode() ne '200' ) {
print $client->responseCode() . "\n" . $client->responseContent() . "\n";
exit 1;
}
my $content = $client->responseContent();
$content =~ s/[^\x{0009}\x{000a}\x{000d}\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}]+
$doc = XML::LibXML->load_xml( string => $content );
$root = $doc->documentElement();
for my $model ( $root->findnodes('
my $name = $model->findnodes('.
my $tree = $model->findnodes('.
$tree =~ s!:!/!g;
$tree = '/All Groups/' . $tree;
$name =~ /(......)-(.*)/;
my ( $siteid, $desc ) = ( $1, $2 );
$sites{$siteid}{desc} = $desc;
$sites{$siteid}{tree} = $tree;
$tree =~ m{/All Groups/Universe/(.*?)/(.*?)/(.*)};
$sites{$siteid}{location} = "$1:$2:$3";
}
"/pc/center/webservice/groups/groupPath/All Groups%2FUniverse/";
$url = "/pc/center/webservice/groups/groupItemId/3460685";
$client = REST::Client->new();
$client->setHost($hostcapc);
$client->addHeader( 'Accept', 'application/xml' );
$client->GET($url);
if ( $client->responseCode() ne '200' ) {
print $client->responseCode() . "\n" . $client->responseContent() . "\n";
exit 1;
}
$doc = XML::LibXML->load_xml( string => $client->responseContent() );
$root = $doc->documentElement();
for my $conode ( $root->findnodes('/GroupTree/Group') ) {
my $co = $conode->getAttribute('name');
$siteexists{ '/All Groups/Universe/' . $co } = 1;
for my $stnode ( $conode->findnodes('./Group') ) {
my $st = $stnode->getAttribute('name');
$siteexists{ '/All Groups/Universe/' . $co . '/' . $st } = 1;
for my $cinode ( $stnode->findnodes('./Group') ) {
my $ci = $cinode->getAttribute('name');
$siteexists{ '/All Groups/Universe/' . $co . '/' . $st . '/' . $ci } = 1;
}
}
}
$url = "/pc/center/webservice/devices";
$client = REST::Client->new();
$client->setHost($hostcapc);
$client->addHeader( 'Accept', 'application/xml' );
$client->GET($url);
if ( $client->responseCode() ne '200' ) {
print $client->responseCode() . "\n" . $client->responseContent() . "\n";
exit 1;
}
$doc = XML::LibXML->load_xml( string => $client->responseContent() );
$root = $doc->documentElement();
for my $dev ( $root->findnodes('/devices/device') ) {
my ($name) = $dev->findnodes('./name/text()');
my ($id) = $dev->findnodes('./itemId/text()');
my ($ip) = $dev->findnodes('./address/text()');
next if !defined $devices{ $ip->nodeValue }{group};
push( @{ $cagroups{ $devices{ $ip->nodeValue }{group} } }, $name->nodeValue );
}
foreach my $site ( keys %cagroups ) {
if ( $site =~ m{(/All Groups/Universe/(.*?)/(.*?)/(.*?)/)(......)} ) {
my ( $tree, $co, $st, $ci, $siteid ) = ( $1, $2, $3, $4, $5 );
my @devices = @{ $cagroups{$site} };
next if ( !@devices );
my $cotree = '/All Groups/Universe/';
my $sttree = $cotree . $co . '/';
my $citree = $sttree . $st . '/';
createpcgroup( $client, $cotree, $co ) if ( !$siteexists{ $cotree . $co } );
createpcgroup( $client, $sttree, $st ) if ( !$siteexists{ $sttree . $st } );
createpcgroup( $client, $citree, $ci ) if ( !$siteexists{ $citree . $ci } );
createpcgroup( $client, $tree, $siteid, 1, $sites{$siteid}{location}, $sites{$siteid}{desc}, @devices );
}
}
sub createpcgroup {
my ( $client, $tree, $group, $site, $location, $desc, @devices ) = @_;
$url = '/pc/center/webservice/groups/false/false';
my $xml = '<GroupTree path="' . $tree . '">';
if ($site) {
if ( $sitename{$group} ) {
$desc = $sitename{$group};
}
if ( !defined($desc) or !defined($location) ) {
print "ERRO: " . $tree . "\n";
}
$xml .= '<Group name="' . $group . '" inherit="true" desc="' . $desc . '" type="site" timeZoneID="UTC" location="' . $location . '">';
$xml .= '<Rules allowDeletes="false" saveRules="false">';
$xml .= '<Rule add="device" itemSubTypeName="" itemTypeLabel="Device" itemTypeLabels="Devices" name="Add Devices">';
$xml .= '<Match><Compare readOnly="true" using="MEMBER_OF">';
$xml .= '<Property label="Item" name="ItemID" subType="" type="device" typeLabel="Device" typeLabels="Devices"/>';
$xml .= '<Value displayValue="/All Groups">1</Value></Compare>';
$xml .= '<Compare readOnly="false" using="EQUALS">';
$xml .= '<Property label="Name" name="ItemName" subType="" type="device" typeLabel="Device" typeLabels="Devices"/>';
$xml .= '<ValueList>';
foreach my $dev (@devices) {
$xml .= "<Value>$dev</Value>";
}
$xml .= '</ValueList></Compare></Match></Rule></Rules>';
$xml .= '</Group>';
} else {
$xml .= '<Group name="' . $group . '" inherit="true" desc="' . $group . '"></Group>';
$siteexists{ $tree . $group } = 1;
}
$xml .= '</GroupTree>';
$client->POST( $url, $xml );
print $group . ": " . $client->responseCode() . " " . scalar(@devices) . "\n";
"\n";
}