You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1653 lines
49 KiB
1653 lines
49 KiB
use strict;
|
|
use warnings;
|
|
{
|
|
package My::Serializer::Custom;
|
|
use Moo;
|
|
extends 'Role::REST::Client::Serializer';
|
|
|
|
sub _set_serializer {
|
|
my $s = Data::Serializer::Raw->new(
|
|
serializer => 'XML::Simple',
|
|
options => {
|
|
RootName => 'object',
|
|
# KeyAttr => { 'object' => '+classname' },
|
|
# ForceArray => ['IPProfile'],
|
|
} );
|
|
return $s;
|
|
}
|
|
|
|
has '+serializer' => ( default => \&_set_serializer, );
|
|
1;
|
|
}
|
|
|
|
{
|
|
package LWP_Wrapper;
|
|
use Moo;
|
|
use HTTP::Request;
|
|
use HTTP::Headers;
|
|
extends 'LWP::UserAgent';
|
|
|
|
around request => sub {
|
|
my ($next, $self, $method, $uri, $opts) = @_;
|
|
my @headers;
|
|
if ($opts->{headers}) {
|
|
@headers = HTTP::Headers->new(%{ $opts->{headers} });
|
|
}
|
|
my $req = HTTP::Request->new($method, $uri, @headers);
|
|
if ($opts->{content}) {
|
|
$req->content($opts->{content});
|
|
}
|
|
my $res = $self->$next($req);
|
|
return $res;
|
|
};
|
|
}
|
|
|
|
package NGCP::Panel::Utils::DialogicImg;
|
|
|
|
use Moo;
|
|
use Digest::MD5 qw/md5_hex/;
|
|
use HTTP::Tiny;
|
|
use Storable qw/freeze/;
|
|
use Types::Standard qw(Int HashRef);
|
|
with 'Role::REST::Client';
|
|
|
|
has '+type' => ( default => 'application/xml', is => 'rw' );
|
|
# has '+serializer_options' => (default => sub {
|
|
# my $s = Data::Serializer::Raw->new(
|
|
# serializer => 'XML::Simple',
|
|
# options => { RootName => 'object' } );
|
|
# return { serializer => $s };
|
|
# });
|
|
has '+serializer_class' =>
|
|
( is => 'rw', default => sub {'My::Serializer::Custom'} );
|
|
has '+clientattrs' => ( default => sub {
|
|
return {timeout => 5};
|
|
});
|
|
has 'appid' => ( is => 'rw', isa => Int, default => 0 );
|
|
has 'pids' => (
|
|
is => 'rw',
|
|
isa => HashRef,
|
|
default => sub {
|
|
return {
|
|
root => 10_000,
|
|
bn2020 => 10_001,
|
|
};
|
|
} );
|
|
|
|
has 'classinfo' => ( is => 'ro', isa => HashRef, default => sub{
|
|
return {
|
|
bn2020 => { # dummy, not used by _create_generic
|
|
name => 'Node',
|
|
parent => 'root',
|
|
revalidate => 0,
|
|
},
|
|
network => {
|
|
name => 'NetworkInterfaces',
|
|
parent => 'bn2020',
|
|
revalidate => 0,
|
|
},
|
|
interface_collection => {
|
|
name => 'NetworkLogicalInterfaces',
|
|
parent => 'network',
|
|
revalidate => 0,
|
|
},
|
|
interface => {
|
|
name => 'NetworkLogicalInterface',
|
|
parent => 'interface_collection',
|
|
revalidate => 0,
|
|
},
|
|
ip_address => {
|
|
name => 'NetworkInterface',
|
|
parent => 'interface',
|
|
revalidate => 1,
|
|
},
|
|
facility => {
|
|
name => 'Facility',
|
|
parent => 'bn2020',
|
|
revalidate => 0,
|
|
},
|
|
packet_facility_collection => {
|
|
name => 'PacketFacilities',
|
|
parent => 'facility',
|
|
revalidate => 0,
|
|
},
|
|
packet_facility => {
|
|
name => 'PacketFacility',
|
|
parent => 'packet_facility_collection',
|
|
revalidate => 0,
|
|
},
|
|
ds1_spans => {
|
|
name => 'SpanGroup',
|
|
parent => 'facility',
|
|
revalidate => 0,
|
|
},
|
|
ds3_optical => {
|
|
name => 'DS3_Optical',
|
|
parent => 'facility',
|
|
revalidate => 1,
|
|
},
|
|
optical_interface => {
|
|
name => 'Optical_Interface',
|
|
parent => 'ds3_optical',
|
|
revalidate => 0,
|
|
},
|
|
optical_link => {
|
|
name => 'Optical_Link',
|
|
parent => 'optical_interface',
|
|
revalidate => 0,
|
|
},
|
|
ds3_interface => {
|
|
name => 'TDM_DS3',
|
|
parent => 'optical_interface',
|
|
revalidate => 0,
|
|
},
|
|
ds1_spans_optical => {
|
|
name => 'SpanGroup', # TODO: double occurrence, is that acceptable?
|
|
parent => 'ds3_interface',
|
|
revalidate => 0,
|
|
},
|
|
signaling => {
|
|
name => 'Signaling',
|
|
parent => 'bn2020',
|
|
revalidate => 0,
|
|
},
|
|
isdn => {
|
|
name => 'ISDN',
|
|
parent => 'signaling',
|
|
revalidate => 0,
|
|
},
|
|
isdn_d_chan => {
|
|
name => 'ISDNDChan',
|
|
parent => 'isdn',
|
|
revalidate => 1,
|
|
},
|
|
isdn_group => {
|
|
name => 'ISDNGroup',
|
|
parent => 'isdn_d_chan',
|
|
revalidate => 0,
|
|
},
|
|
isdn_circuit_group => {
|
|
name => 'ISDNCircuitGroup',
|
|
parent => 'isdn_group',
|
|
revalidate => 1,
|
|
},
|
|
sip => {
|
|
name => 'SIP',
|
|
parent => 'signaling',
|
|
revalidate => 0,
|
|
},
|
|
sip_ip => {
|
|
name => 'SIPIP',
|
|
parent => 'sip',
|
|
revalidate => 0,
|
|
},
|
|
call_tracing => {
|
|
name => 'CallTracing',
|
|
parent => 'bn2020',
|
|
revalidate => 0,
|
|
},
|
|
snmp_agent => {
|
|
name => 'SNMPClient',
|
|
parent => 'bn2020',
|
|
revalidate => 0,
|
|
},
|
|
ss7 => {
|
|
name => 'SS7',
|
|
parent => 'root',
|
|
revalidate => 0,
|
|
},
|
|
ss7_network => {
|
|
name => 'SS7Network',
|
|
parent => 'ss7',
|
|
revalidate => 0,
|
|
},
|
|
ss7_node_collection => {
|
|
name => 'SS7Nodes',
|
|
parent => 'ss7_network',
|
|
revalidate => 0,
|
|
},
|
|
ss7_node_primary => {
|
|
name => 'SS7PrimaryNode',
|
|
parent => 'ss7_node_collection',
|
|
revalidate => 0,
|
|
},
|
|
ss7_stack => {
|
|
name => 'SS7Stack',
|
|
parent => 'ss7_network',
|
|
revalidate => 1,
|
|
},
|
|
ss7_link_set => {
|
|
name => 'SS7LinkSet',
|
|
parent => 'ss7_stack',
|
|
revalidate => 1,
|
|
},
|
|
ss7_link => {
|
|
name => 'SS7Link',
|
|
parent => 'ss7_link_set',
|
|
revalidate => 1,
|
|
},
|
|
ss7_destination => {
|
|
name => 'SS7Destination',
|
|
parent => 'ss7_stack',
|
|
revalidate => 1,
|
|
},
|
|
ss7_route => {
|
|
name => 'SS7Route',
|
|
parent => 'ss7_destination',
|
|
revalidate => 1,
|
|
},
|
|
ss7_isup_group => { # note: needs isup profile
|
|
name => 'ISUPGroup',
|
|
parent => 'ss7_destination',
|
|
revalidate => 1,
|
|
},
|
|
ss7_circuit_group => {
|
|
name => 'SS7CircuitGroup',
|
|
parent => 'ss7_isup_group',
|
|
revalidate => 1,
|
|
},
|
|
profile_collection => {
|
|
name => 'Profiles',
|
|
parent => 'root',
|
|
revalidate => 0,
|
|
},
|
|
ip_profile_collection => {
|
|
name => 'IPProfiles',
|
|
parent => 'profile_collection',
|
|
revalidate => 0,
|
|
},
|
|
ip_profile => {
|
|
name => 'IPProfile',
|
|
parent => 'ip_profile_collection',
|
|
revalidate => 1,
|
|
},
|
|
vocoder_profile => {
|
|
name => 'VocoderProfile',
|
|
parent => 'ip_profile',
|
|
revalidate => 1,
|
|
},
|
|
sip_profile_collection => {
|
|
name => 'SIPProfiles',
|
|
parent => 'profile_collection',
|
|
revalidate => 0,
|
|
},
|
|
sip_profile => {
|
|
name => 'SIPSGP',
|
|
parent => 'sip_profile_collection',
|
|
revalidate => 1,
|
|
},
|
|
sip_headers => {
|
|
name => 'SIPHeaders',
|
|
parent => 'sip_profile',
|
|
revalidate => 0,
|
|
},
|
|
tdm_profile_collection => {
|
|
name => 'TDMProfiles',
|
|
parent => 'profile_collection',
|
|
revalidate => 0,
|
|
},
|
|
e1_profile => {
|
|
name => 'E1Profile',
|
|
parent => 'tdm_profile_collection',
|
|
revalidate => 0,
|
|
},
|
|
isup_profile_collection => {
|
|
name => 'ISUPProfiles',
|
|
parent => 'profile_collection',
|
|
revalidate => 0,
|
|
},
|
|
isup_itu_profile => {
|
|
name => 'ISUP_ITUProfile',
|
|
parent => 'isup_profile_collection',
|
|
revalidate => 0,
|
|
},
|
|
isup_ansi_profile => {
|
|
name => 'ISUP_ANSIProfile',
|
|
parent => 'isup_profile_collection',
|
|
revalidate => 0,
|
|
},
|
|
external_network_elements => {
|
|
name => 'ExternalNetworkElements',
|
|
parent => 'root',
|
|
revalidate => 0,
|
|
},
|
|
external_gateway_collection => {
|
|
name => 'ExternalGateways',
|
|
parent => 'external_network_elements',
|
|
revalidate => 0,
|
|
},
|
|
external_gateway => {
|
|
name => 'ExternalGateway',
|
|
parent => 'external_gateway_collection',
|
|
revalidate => 1,
|
|
},
|
|
external_nfsserver_collection => {
|
|
name => 'NFSServers',
|
|
parent => 'external_network_elements',
|
|
revalidate => 0,
|
|
},
|
|
external_nfsserver => {
|
|
name => 'NFSServer',
|
|
parent => 'external_nfsserver_collection',
|
|
revalidate => 1,
|
|
},
|
|
external_snmpmanager_collection => {
|
|
name => 'SNMPServers',
|
|
parent => 'external_network_elements',
|
|
revalidate => 0,
|
|
},
|
|
external_snmpmanager => {
|
|
name => 'SNMPServer',
|
|
parent => 'external_snmpmanager_collection',
|
|
revalidate => 1,
|
|
},
|
|
routing_configuration => {
|
|
name => 'RoutingConfiguration',
|
|
parent => 'root',
|
|
revalidate => 0,
|
|
},
|
|
channel_group_collection => {
|
|
name => 'ChannelGroups',
|
|
parent => 'routing_configuration',
|
|
revalidate => 0,
|
|
},
|
|
channel_group => {
|
|
name => 'ChannelGroup',
|
|
parent => 'channel_group_collection',
|
|
revalidate => 1,
|
|
},
|
|
route_table_collection => {
|
|
name => 'RoutingTables',
|
|
parent => 'routing_configuration',
|
|
revalidate => 0,
|
|
},
|
|
route_table => {
|
|
name => 'RouteTable',
|
|
parent => 'route_table_collection',
|
|
revalidate => 1,
|
|
},
|
|
route_element => {
|
|
name => 'RouteElement',
|
|
parent => 'route_table',
|
|
revalidate => 1,
|
|
},
|
|
cg_network_element => {
|
|
name => 'NetworkElement',
|
|
parent => 'channel_group',
|
|
revalidate => 0,
|
|
},
|
|
node_association => {
|
|
name => 'NodeAssociation',
|
|
parent => 'cg_network_element',
|
|
revalidate => 0,
|
|
},
|
|
cg_isdn_circuit_group => {
|
|
name => 'SSLCircuitGroup',
|
|
parent => 'channel_group',
|
|
revalidate => 0,
|
|
},
|
|
};
|
|
});
|
|
|
|
# returns appid or 0
|
|
sub login {
|
|
my ( $self, $username, $password ) = @_;
|
|
my $resp = $self->post(
|
|
'/oamp/user_management/users/logged_in?appid=0',
|
|
{ user => { name => $username, password => $password } } );
|
|
if ( $resp->code == 200 ) {
|
|
my $data = $resp->data;
|
|
$self->appid( $data->{appid} );
|
|
return $self->appid;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
sub obtain_lock {
|
|
my ($self) = @_;
|
|
$self->set_header( 'Content-Length' => '0', );
|
|
my $resp = $self->delete(
|
|
'/oamp/user_management/locks?appid=' . $self->appid );
|
|
$resp = $self->post( '/oamp/user_management/locks?appid=' . $self->appid,
|
|
{} );
|
|
return $resp;
|
|
}
|
|
|
|
###### CREATE methods ######
|
|
|
|
sub create_bn2020 {
|
|
my ($self) = @_;
|
|
|
|
my $data = $self->objects->{bn2020};
|
|
my $resp = $self->post(
|
|
'/oamp/configuration/objects/Node/NULL?pid=10000&appid='
|
|
. $self->appid,
|
|
$data,
|
|
);
|
|
if ( $resp->code == 200 ) {
|
|
$self->pids->{bn2020} = $resp->data->{oid};
|
|
}
|
|
return $resp;
|
|
}
|
|
|
|
sub create_network {
|
|
my ($self) = @_;
|
|
|
|
return $self->_create_generic(undef, 'network');
|
|
}
|
|
|
|
sub create_interface_collection {
|
|
my ($self) = @_;
|
|
|
|
return $self->_create_generic(undef, 'interface_collection');
|
|
}
|
|
|
|
sub create_interface {
|
|
my ($self) = @_;
|
|
|
|
my $resp = $self->_create_generic(undef, 'interface');
|
|
if ( $resp->code == 200 ) {
|
|
if ( $resp->data->{property}{Interface}{value} eq "Control" ) {
|
|
$self->pids->{interface_control} = $resp->data->{oid};
|
|
} elsif ( $resp->data->{property}{Interface}{value} eq "Data A" ) {
|
|
$self->pids->{interface_dataa} = $resp->data->{oid};
|
|
}
|
|
}
|
|
return $resp;
|
|
}
|
|
|
|
sub create_ip_address {
|
|
my ( $self, $options ) = @_;
|
|
|
|
if ( defined $options->{NIIPAddress} && !defined $options->{NIIPGateway} )
|
|
{
|
|
$options->{NIIPGateway} = $options->{NIIPAddress} =~ s/\.[0-9]+$/.1/r;
|
|
}
|
|
return $self->_create_generic($options, 'ip_address');
|
|
}
|
|
|
|
sub create_facility {
|
|
my ($self) = @_;
|
|
|
|
return $self->_create_generic(undef, 'facility');
|
|
}
|
|
|
|
sub create_packet_facility_collection {
|
|
my ($self) = @_;
|
|
|
|
return $self->_create_generic(undef, 'packet_facility_collection');
|
|
}
|
|
|
|
sub create_packet_facility {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'packet_facility');
|
|
}
|
|
|
|
sub create_ds1_spans {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'ds1_spans');
|
|
}
|
|
|
|
sub create_ds3_optical {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'ds3_optical');
|
|
}
|
|
|
|
sub create_optical_interface {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'optical_interface');
|
|
}
|
|
|
|
sub create_optical_link {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'optical_link');
|
|
}
|
|
|
|
sub create_ds3_interface {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'ds3_interface');
|
|
}
|
|
|
|
sub create_ds1_spans_optical {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'ds1_spans_optical');
|
|
}
|
|
|
|
sub create_signaling {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'signaling');
|
|
}
|
|
|
|
sub create_isdn {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'isdn');
|
|
}
|
|
|
|
sub create_isdn_d_chan {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'isdn_d_chan');
|
|
}
|
|
|
|
sub create_isdn_group {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'isdn_group');
|
|
}
|
|
|
|
sub create_isdn_circuit_group {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'isdn_circuit_group');
|
|
}
|
|
|
|
sub create_sip {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'sip');
|
|
}
|
|
|
|
sub create_sip_ip {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'sip_ip');
|
|
}
|
|
|
|
sub create_call_tracing {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'call_tracing');
|
|
}
|
|
|
|
sub create_snmp_agent {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'snmp_agent');
|
|
}
|
|
|
|
sub create_ss7 {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'ss7');
|
|
}
|
|
|
|
sub create_ss7_network {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'ss7_network');
|
|
}
|
|
|
|
sub create_ss7_node_collection {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'ss7_node_collection');
|
|
}
|
|
|
|
sub create_ss7_node_primary {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'ss7_node_primary');
|
|
}
|
|
|
|
sub create_ss7_stack {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'ss7_stack');
|
|
}
|
|
|
|
sub create_ss7_link_set {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'ss7_link_set');
|
|
}
|
|
|
|
sub create_ss7_link {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'ss7_link');
|
|
}
|
|
|
|
sub create_ss7_destination {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'ss7_destination');
|
|
}
|
|
|
|
sub create_ss7_route {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'ss7_route');
|
|
}
|
|
|
|
sub create_ss7_isup_group {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'ss7_isup_group');
|
|
}
|
|
|
|
sub create_ss7_circuit_group {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'ss7_circuit_group');
|
|
}
|
|
|
|
sub create_profile_collection {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'profile_collection');
|
|
}
|
|
|
|
sub create_ip_profile_collection {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'ip_profile_collection');
|
|
}
|
|
|
|
sub create_ip_profile {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'ip_profile');
|
|
}
|
|
|
|
sub create_vocoder_profile {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'vocoder_profile');
|
|
}
|
|
|
|
sub create_sip_profile_collection {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'sip_profile_collection');
|
|
}
|
|
|
|
sub create_sip_profile {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'sip_profile');
|
|
}
|
|
|
|
sub create_sip_headers {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'sip_headers');
|
|
}
|
|
|
|
sub create_tdm_profile_collection {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'tdm_profile_collection');
|
|
}
|
|
|
|
sub create_e1_profile {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'e1_profile');
|
|
}
|
|
|
|
sub create_isup_profile_collection {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'isup_profile_collection');
|
|
}
|
|
|
|
sub create_isup_itu_profile {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'isup_itu_profile');
|
|
}
|
|
|
|
sub create_isup_ansi_profile {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'isup_ansi_profile');
|
|
}
|
|
|
|
sub create_external_network_elements {
|
|
my ( $self ) = @_;
|
|
|
|
return $self->_create_generic(undef, 'external_network_elements');
|
|
}
|
|
|
|
sub create_external_gateway_collection {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'external_gateway_collection');
|
|
}
|
|
|
|
sub create_external_gateway {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'external_gateway');
|
|
}
|
|
|
|
sub create_external_nfsserver_collection {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'external_nfsserver_collection');
|
|
}
|
|
|
|
sub create_external_nfsserver {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'external_nfsserver');
|
|
}
|
|
|
|
sub create_external_snmpmanager_collection {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'external_snmpmanager_collection');
|
|
}
|
|
|
|
sub create_external_snmpmanager {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'external_snmpmanager');
|
|
}
|
|
|
|
sub create_routing_configuration {
|
|
my ($self) = @_;
|
|
|
|
return $self->_create_generic(undef, 'routing_configuration');
|
|
}
|
|
|
|
sub create_channel_group_collection {
|
|
my ($self) = @_;
|
|
|
|
return $self->_create_generic(undef, 'channel_group_collection');
|
|
}
|
|
|
|
sub create_channel_group {
|
|
my ($self, $options) = @_;
|
|
|
|
return $self->_create_generic($options, 'channel_group');
|
|
}
|
|
|
|
sub create_route_table_collection {
|
|
my ($self, $options) = @_;
|
|
|
|
return $self->_create_generic($options, 'route_table_collection');
|
|
}
|
|
|
|
sub create_route_table {
|
|
my ($self, $options) = @_;
|
|
|
|
return $self->_create_generic($options, 'route_table');
|
|
}
|
|
|
|
sub create_route_element {
|
|
my ($self, $options) = @_;
|
|
|
|
return $self->_create_generic($options, 'route_element');
|
|
}
|
|
|
|
sub create_cg_network_element {
|
|
my ($self, $options) = @_;
|
|
|
|
return $self->_create_generic($options, 'cg_network_element');
|
|
}
|
|
|
|
sub create_node_association {
|
|
my ($self, $options) = @_;
|
|
|
|
return $self->_create_generic($options, 'node_association');
|
|
}
|
|
|
|
sub create_cg_isdn_circuit_group {
|
|
my ( $self, $options ) = @_;
|
|
|
|
return $self->_create_generic($options, 'cg_isdn_circuit_group');
|
|
}
|
|
|
|
sub _create_generic {
|
|
my ($self, $options, $class) = @_;
|
|
|
|
my $classinfo = $self->classinfo->{$class};
|
|
my $pid = $self->pids->{$classinfo->{parent}};
|
|
unless ($pid) {
|
|
warn "$class: no valid pid available\n";
|
|
return; # TODO wrong format
|
|
}
|
|
my $classname = $classinfo->{name};
|
|
my $appid = $self->appid;
|
|
my $resp = $self->get(
|
|
"/oamp/configuration/objects/$classname/NULL?detaillevel=4&pid=$pid&appid=$appid",
|
|
);
|
|
if ( $resp->code != 200 ) {
|
|
warn "$class: Failed to fetch resource\n";
|
|
return $resp;
|
|
}
|
|
if ($classinfo->{revalidate}) {
|
|
my $validation_data = $self->_build_validation_data( $resp->data, $pid, $options );
|
|
$resp = $self->get(
|
|
"/oamp/configuration/objects/$classname/NULL",
|
|
$validation_data,
|
|
);
|
|
if ( $resp->code != 200 ) {
|
|
warn "$class: Failed to fetch resource second time (revalidate)\n";
|
|
return $resp;
|
|
}
|
|
}
|
|
my $new_data = $self->_build_response_data( $resp->data, $pid, $options );
|
|
$resp = $self->post(
|
|
"/oamp/configuration/objects/$classname/NULL?pid=$pid&appid=$appid",
|
|
$new_data,
|
|
);
|
|
if ( $resp->code == 200 ) {
|
|
$self->pids->{$class} = $resp->data->{oid};
|
|
}
|
|
return $resp;
|
|
}
|
|
|
|
|
|
# log: 0: none, 1: short, 2: everything
|
|
# necessary keys: ip_sip, ip_rtp, ip_client, out_codecs
|
|
# optional: in_codecs, ip_sip_subnet, ip_rtp_subnet
|
|
# for nfs: ip_nfs_server, nfs_path
|
|
# for snmp: snmp_system_name, snmp_system_location, snmp_system_contact, snmp_community_name
|
|
# for snmp optional: ip_snmp_manager, snmp_version
|
|
# The management IP, the SIP IP and the RTP IP have to be in different subnets
|
|
sub create_general_part_schedule {
|
|
my ($self, $settings, $log) = @_;
|
|
|
|
$self->_create_indent;
|
|
|
|
my $in_codecs = ['G711 ulaw', 'G711 alaw', 'G729', 'AMR',
|
|
'AMR Bandwidth Efficient', 'AMR-WB', 'AMR-WB Bandwidth Efficient',
|
|
'Clear Channel', 'G723 5.3 Kbps', 'G723 6.3 Kbps', 'G722', 'iLBC 30ms',
|
|
'GSM-FR Static Payload Type', 'GSM-FR Dynamic Payload Type',
|
|
'G726-32/G721 Static Payload Type', 'G726-32/G721 Dynamic Payload Type',
|
|
'GSM-EFR'];
|
|
|
|
my $resp = $self->create_bn2020;
|
|
my @in_schedule = map {
|
|
{
|
|
name => 'vocoder_profile', options =>
|
|
{ PayloadType => $_ },
|
|
};
|
|
} @{ $settings->{in_codecs} // $in_codecs };
|
|
my @out_schedule = map {
|
|
{
|
|
name => 'vocoder_profile', options =>
|
|
{ PayloadType => $_ },
|
|
};
|
|
} @{ $settings->{out_codecs} };
|
|
my @nfs_schedule;
|
|
if (defined $settings->{ip_nfs_server} &&
|
|
defined $settings->{nfs_path}) {
|
|
@nfs_schedule = (
|
|
{name => 'external_nfsserver_collection', options => undef}, # needs external_network_elements
|
|
{name => 'external_nfsserver', options => {
|
|
Name => 'ngcp_nfs_server',
|
|
IPAddress => $settings->{ip_nfs_server},
|
|
}},
|
|
{name => 'call_tracing', options => {
|
|
TraceTime => '600',
|
|
MountDirectory => $settings->{nfs_path},
|
|
}},
|
|
);
|
|
}
|
|
my @snmp_schedule;
|
|
if (defined $settings->{snmp_system_name} &&
|
|
defined $settings->{snmp_system_location} &&
|
|
defined $settings->{snmp_system_contact} &&
|
|
defined $settings->{snmp_community_name}) {
|
|
@snmp_schedule = (
|
|
{name => 'external_snmpmanager_collection', options => undef},
|
|
{name => 'external_snmpmanager', options => {
|
|
UserName => 'ngcp',
|
|
CommunityName => $settings->{snmp_community_name},
|
|
ServerIPAddress => $settings->{ip_snmp_manager} // $settings->{ip_client},
|
|
defined $settings->{snmp_version} ? (ServerVersion => $settings->{snmp_version} ) : (),
|
|
}},
|
|
{name => 'snmp_agent', options => {
|
|
SystemName => $settings->{snmp_system_name},
|
|
SystemLoc => $settings->{snmp_system_location},
|
|
SystemContact => $settings->{snmp_system_contact},
|
|
}},
|
|
);
|
|
}
|
|
my $schedule = [
|
|
{name => 'network', options => undef},
|
|
{name => 'interface_collection', options => undef},
|
|
{name => 'interface', options => undef}, # Control
|
|
{name => 'interface', options => undef}, # Data A
|
|
{name => 'ip_address', options => {
|
|
NIIPAddress => $settings->{ip_sip},
|
|
NIIPPhy => 'Services',
|
|
NIIPSubnet => $settings->{ip_sip_subnet} || '24',
|
|
}},
|
|
{name => 'interface', options => undef}, # Data B
|
|
{name => 'ip_address', options => {
|
|
NIIPAddress => $settings->{ip_rtp},
|
|
NIIPPhy => 'Media 0',
|
|
NIIPSubnet => $settings->{ip_rtp_subnet} || '24',
|
|
}},
|
|
{name => 'facility', options => undef},
|
|
{name => 'packet_facility_collection', options => undef},
|
|
{name => 'packet_facility', options => {
|
|
ChannelCount => 50,
|
|
}},
|
|
{name => 'signaling', options => undef},
|
|
{name => 'sip', options => undef},
|
|
{name => 'sip_ip', options => {
|
|
IPAddress => $settings->{ip_sip},
|
|
}},
|
|
{name => 'profile_collection', options => undef},
|
|
{name => 'ip_profile_collection', options => undef},
|
|
{name => 'ip_profile', options => {
|
|
DigitRelay => 'DTMF Packetized',
|
|
Name => 'ngcp_in_profile',
|
|
}},
|
|
@in_schedule,
|
|
{name => 'ip_profile', options => {
|
|
DigitRelay => 'DTMF Packetized',
|
|
Name => 'ngcp_out_profile',
|
|
}},
|
|
@out_schedule,
|
|
{name => 'sip_profile_collection', options => undef},
|
|
{name => 'sip_profile', options => undef},
|
|
{name => 'sip_profile', options => {
|
|
ProfileName => 'SIP-profile-ngcp',
|
|
}},
|
|
{name => 'sip_headers', options => {
|
|
UnsupportedHeader => 'Enabled',
|
|
}},
|
|
#{run => 'download_profiles'},
|
|
{name => 'external_network_elements', options => undef},
|
|
{name => 'external_gateway_collection', options => undef},
|
|
{name => 'external_gateway', options => {
|
|
Name => 'Phone1',
|
|
IPAddress => $settings->{ip_client},
|
|
IPAddress4 => $settings->{ip_client},
|
|
SGP => 'ID: 1 - SIP-profile-ngcp',
|
|
SGPId => '1',
|
|
}},
|
|
@nfs_schedule,
|
|
@snmp_schedule,
|
|
];
|
|
|
|
return $schedule;
|
|
}
|
|
|
|
# log: 0: none, 1: short, 2: everything
|
|
# necessary keys: ip_sip, ip_rtp, ip_client, out_codecs, optional: in_codecs
|
|
sub create_all_sipsip {
|
|
my ($self, $settings, $log) = @_;
|
|
|
|
my $general_schedule = $self->create_general_part_schedule($settings, $log);
|
|
|
|
my $schedule = [
|
|
@{ $general_schedule },
|
|
{name => 'routing_configuration', options => undef},
|
|
{name => 'channel_group_collection', options => undef},
|
|
{name => 'route_table_collection', options => undef},
|
|
{name => 'route_table', options => {
|
|
Name => 'ngcp_route_table',
|
|
}},
|
|
{name => 'channel_group', options => {
|
|
SignalingType => 'SIP',
|
|
InRouteTable => 'ngcp_route_table - ID: 5',
|
|
InIPProfile => 'ngcp_in_profile',
|
|
InIPProfileId => '1',
|
|
OutIPProfile => 'ngcp_out_profile',
|
|
SupportA2F => 'True',
|
|
Name => 'cg_ngcp_sipclient',
|
|
}},
|
|
{name => 'cg_network_element', options => undef},
|
|
{name => 'node_association', options => undef},
|
|
{name => 'route_element', options => {
|
|
StringType => 'Channel Group',
|
|
InChannelGroup => 'cg_ngcp_sipclient',
|
|
RouteActionType => 'Channel Group',
|
|
RouteActionList => 'cg_ngcp_sipclient',
|
|
}},
|
|
#{run => 'download_route_table'},
|
|
#{run => 'download_channel_groups'},
|
|
];
|
|
|
|
$self->_run_schedule($schedule, $log);
|
|
|
|
$self->download_profiles;
|
|
$self->download_route_table;
|
|
$self->download_channel_groups;
|
|
|
|
return 0;
|
|
}
|
|
|
|
# log: 0: none, 1: short
|
|
# necessary keys: ip_sip, ip_rtp, ip_client, out_codecs, optional: in_codecs
|
|
# optional: use_optical_spans (bool), is_isdn_userside (bool)
|
|
sub create_all_sipisdn {
|
|
my ($self, $settings, $log) = @_;
|
|
|
|
my $general_schedule = $self->create_general_part_schedule($settings, $log);
|
|
|
|
my @ds1_spans;
|
|
if ($settings->{use_optical_spans}) {
|
|
@ds1_spans = (
|
|
{name => 'ds3_optical', options => {
|
|
FacilityType => 'Optical',
|
|
}},
|
|
{name => 'optical_interface', options => undef},
|
|
{name => 'optical_link', options => undef},
|
|
{name => 'ds3_interface', options => undef},
|
|
{name => 'ds1_spans_optical', options => undef},
|
|
);
|
|
} else {
|
|
@ds1_spans = (
|
|
{name => 'ds1_spans', options => {
|
|
EndingOffset => '3',
|
|
}},
|
|
);
|
|
}
|
|
|
|
my $resp;
|
|
|
|
my $schedule = [
|
|
@{ $general_schedule },
|
|
{name => 'isdn', options => undef},
|
|
|
|
{name => 'tdm_profile_collection', options => undef},
|
|
{name => 'e1_profile', options => undef},
|
|
@ds1_spans,
|
|
{name => 'isdn_d_chan', options => $settings->{is_isdn_userside} ?
|
|
{
|
|
BaseVariant => 'Euro-ISDN User Side',
|
|
BChanSelection => 'Linear Counter Clockwise',
|
|
} : undef,
|
|
},
|
|
{name => 'isdn_group', options => undef},
|
|
{name => 'isdn_circuit_group', options => {
|
|
EndChannel => 'Span ID: 0 CID: 30',
|
|
}},
|
|
{name => 'isdn_d_chan', options => $settings->{is_isdn_userside} ?
|
|
undef : {
|
|
BaseVariant => 'Euro-ISDN User Side',
|
|
BChanSelection => 'Linear Counter Clockwise',
|
|
},
|
|
},
|
|
{name => 'isdn_group', options => undef},
|
|
{name => 'isdn_circuit_group', options => {
|
|
EndChannel => 'Span ID: 1 CID: 30',
|
|
}},
|
|
#{run => 'download_profiles'},
|
|
{name => 'routing_configuration', options => undef},
|
|
{name => 'channel_group_collection', options => undef},
|
|
{name => 'route_table_collection', options => undef},
|
|
{name => 'route_table', options => {
|
|
Name => 'ngcp_route_table',
|
|
}},
|
|
{name => 'channel_group', options => {
|
|
SignalingType => 'SIP',
|
|
InRouteTable => 'ngcp_route_table - ID: 5',
|
|
InIPProfile => 'ngcp_in_profile',
|
|
InIPProfileId => '1',
|
|
OutIPProfile => 'ngcp_out_profile',
|
|
SupportA2F => 'True',
|
|
Name => 'cg_ngcp_sipclient',
|
|
}},
|
|
{name => 'cg_network_element', options => undef},
|
|
{name => 'node_association', options => undef},
|
|
{name => 'channel_group', options => {
|
|
SignalingType => 'ISDN',
|
|
InRouteTable => 'ngcp_route_table - ID: 5',
|
|
SupportA2F => 'True',
|
|
Name => 'cg_ngcp_isdn_1',
|
|
}},
|
|
{name => 'cg_isdn_circuit_group', options => undef},
|
|
{name => 'channel_group', options => {
|
|
SignalingType => 'ISDN',
|
|
InRouteTable => 'ngcp_route_table - ID: 5',
|
|
SupportA2F => 'True',
|
|
Name => 'cg_ngcp_isdn_2',
|
|
}},
|
|
{name => 'cg_isdn_circuit_group', options => undef},
|
|
{name => 'route_element', options => {
|
|
StringType => 'Channel Group',
|
|
InChannelGroup => 'cg_ngcp_sipclient',
|
|
RouteActionType => 'Channel Group',
|
|
RouteActionList => 'cg_ngcp_isdn_1',
|
|
}},
|
|
{name => 'route_element', options => {
|
|
StringType => 'Channel Group',
|
|
InChannelGroup => 'cg_ngcp_isdn_1',
|
|
RouteActionType => 'Channel Group',
|
|
RouteActionList => 'cg_ngcp_sipclient',
|
|
}},
|
|
{name => 'route_element', options => {
|
|
StringType => 'Channel Group',
|
|
InChannelGroup => 'cg_ngcp_isdn_2',
|
|
RouteActionType => 'Channel Group',
|
|
RouteActionList => 'cg_ngcp_sipclient',
|
|
}},
|
|
#{run => 'download_route_table'},
|
|
#{run => 'download_channel_groups'},
|
|
];
|
|
|
|
$self->_run_schedule($schedule, $log);
|
|
|
|
$self->download_profiles;
|
|
$self->download_route_table;
|
|
$self->download_channel_groups;
|
|
|
|
return 0;
|
|
}
|
|
|
|
# log: 0: none, 1: short
|
|
# necessary keys: ip_sip, ip_rtp, ip_client, out_codecs, ss7_opc, ss7_apc, ss7_dpc
|
|
# optionalkeys: in_codecs
|
|
# optional: use_optical_spans (bool)
|
|
sub create_all_sipss7 {
|
|
my ($self, $settings, $log) = @_;
|
|
|
|
my $general_schedule = $self->create_general_part_schedule($settings, $log);
|
|
|
|
my @ds1_spans;
|
|
if ($settings->{use_optical_spans}) {
|
|
@ds1_spans = (
|
|
{name => 'ds3_optical', options => {
|
|
FacilityType => 'Optical',
|
|
}},
|
|
{name => 'optical_interface', options => undef},
|
|
{name => 'optical_link', options => undef},
|
|
{name => 'ds3_interface', options => undef},
|
|
{name => 'ds1_spans_optical', options => undef},
|
|
);
|
|
} else {
|
|
@ds1_spans = (
|
|
{name => 'ds1_spans', options => {
|
|
EndingOffset => '3',
|
|
}},
|
|
);
|
|
}
|
|
|
|
my $schedule = [
|
|
@{ $general_schedule },
|
|
{name => 'tdm_profile_collection', options => undef},
|
|
{name => 'e1_profile', options => undef},
|
|
{name => 'isup_profile_collection', options => undef},
|
|
{name => 'isup_itu_profile', options => undef},
|
|
@ds1_spans,
|
|
#{run => 'download_profiles'},
|
|
{name => 'ss7', options => undef},
|
|
{name => 'ss7_network', options => undef},
|
|
{name => 'ss7_node_collection', options => undef},
|
|
{name => 'ss7_node_primary', options => undef},
|
|
{name => 'ss7_stack', options => {
|
|
OPC => $settings->{ss7_opc},
|
|
}},
|
|
{name => 'ss7_link_set', options => {
|
|
APC => $settings->{ss7_apc},
|
|
}},
|
|
{name => 'ss7_link', options => undef},
|
|
{name => 'ss7_destination', options => {
|
|
DPC => $settings->{ss7_dpc},
|
|
}},
|
|
{name => 'ss7_route', options => {
|
|
Linkset => 'SS7 Link Set APC: ' . $settings->{ss7_apc},
|
|
}},
|
|
{name => 'ss7_isup_group', options => undef},
|
|
{name => 'ss7_circuit_group', options => {
|
|
StartCIC => '1',
|
|
}},
|
|
|
|
{name => 'ss7_stack', options => { # for loopback purposes
|
|
OPC => $settings->{ss7_dpc},
|
|
}},
|
|
{name => 'ss7_link_set', options => {
|
|
APC => $settings->{ss7_opc},
|
|
}},
|
|
{name => 'ss7_link', options => undef},
|
|
{name => 'ss7_destination', options => {
|
|
DPC => $settings->{ss7_opc},
|
|
}},
|
|
{name => 'ss7_route', options => {
|
|
Linkset => 'SS7 Link Set APC: ' . $settings->{ss7_opc},
|
|
}},
|
|
{name => 'ss7_isup_group', options => undef},
|
|
{name => 'ss7_circuit_group', options => {
|
|
StartCIC => '1',
|
|
}},
|
|
|
|
{name => 'routing_configuration', options => undef},
|
|
{name => 'channel_group_collection', options => undef},
|
|
{name => 'route_table_collection', options => undef},
|
|
{name => 'route_table', options => {
|
|
Name => 'ngcp_route_table',
|
|
}},
|
|
{name => 'channel_group', options => {
|
|
SignalingType => 'SIP',
|
|
InRouteTable => 'ngcp_route_table - ID: 5',
|
|
InIPProfile => 'ngcp_in_profile',
|
|
InIPProfileId => '1',
|
|
OutIPProfile => 'ngcp_out_profile',
|
|
SupportA2F => 'True',
|
|
Name => 'cg_ngcp_sipclient',
|
|
}},
|
|
{name => 'cg_network_element', options => undef},
|
|
{name => 'node_association', options => undef},
|
|
|
|
{name => 'channel_group', options => {
|
|
SignalingType => 'SS7_ISUP',
|
|
InRouteTable => 'ngcp_route_table - ID: 5',
|
|
SupportA2F => 'True',
|
|
Name => 'cg_ngcp_ss7_1',
|
|
}},
|
|
{name => 'cg_isdn_circuit_group', options => undef},
|
|
{name => 'channel_group', options => {
|
|
SignalingType => 'SS7_ISUP',
|
|
InRouteTable => 'ngcp_route_table - ID: 5',
|
|
SupportA2F => 'True',
|
|
Name => 'cg_ngcp_ss7_2',
|
|
}},
|
|
{name => 'cg_isdn_circuit_group', options => undef},
|
|
|
|
{name => 'route_element', options => {
|
|
StringType => 'Channel Group',
|
|
InChannelGroup => 'cg_ngcp_sipclient',
|
|
RouteActionType => 'Channel Group',
|
|
RouteActionList => 'cg_ngcp_ss7_1',
|
|
}},
|
|
{name => 'route_element', options => {
|
|
StringType => 'Channel Group',
|
|
InChannelGroup => 'cg_ngcp_ss7_1',
|
|
RouteActionType => 'Channel Group',
|
|
RouteActionList => 'cg_ngcp_sipclient',
|
|
}},
|
|
{name => 'route_element', options => {
|
|
StringType => 'Channel Group',
|
|
InChannelGroup => 'cg_ngcp_ss7_2',
|
|
RouteActionType => 'Channel Group',
|
|
RouteActionList => 'cg_ngcp_sipclient',
|
|
}},
|
|
#{run => 'download_route_table'},
|
|
#{run => 'download_channel_groups'},
|
|
];
|
|
|
|
$self->_run_schedule($schedule, $log);
|
|
|
|
$self->download_profiles;
|
|
$self->download_route_table;
|
|
$self->download_channel_groups;
|
|
|
|
return 0;
|
|
}
|
|
|
|
###### OTHER STUFF ######
|
|
|
|
sub _run_schedule {
|
|
my ($self, $schedule, $log) = @_;
|
|
|
|
my $resp;
|
|
my $ntotal = $#{$schedule};
|
|
my $i = 0;
|
|
|
|
for my $elem (@{ $schedule }) {
|
|
if (exists $elem->{run}) {
|
|
my $command = $elem->{run};
|
|
$self->$command;
|
|
next;
|
|
}
|
|
my ($name, $options) = @{ $elem }{('name', 'options')};
|
|
my $fun = "create_$name";
|
|
$resp = $self->$fun($options);
|
|
# $resp = $self->_create_generic($options, $name);
|
|
if ($log) {
|
|
my $ind = " " x ($self->classinfo->{$name}{indent}*4);
|
|
my $percent = (100 * $i++) / $ntotal;
|
|
my $shortline = sprintf "%3d%% - %-37s: %d\n", $percent, "$ind$name", $resp->code;
|
|
if ('CODE' eq ref $log) {
|
|
&{ $log }($shortline, $resp);
|
|
} elsif ($log >= 1) {
|
|
print $shortline;
|
|
if ($resp->code != 200) {
|
|
use DDP; p $resp->data;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
sub hash_config {
|
|
my ($self, $config) = @_;
|
|
$Storable::canonical = 1;
|
|
return md5_hex(freeze $config);
|
|
}
|
|
|
|
sub get_config {
|
|
my ($self) = @_;
|
|
|
|
my $appid = $self->appid;
|
|
my $resp = $self->get("/oamp/configuration/objects?appid=$appid");
|
|
my $config = {};
|
|
if ($resp->code != 200) {
|
|
warn "failed to get objects\n";
|
|
return $resp;
|
|
}
|
|
my $classinfo = $self->classinfo;
|
|
my $rev_lookup = {};
|
|
@{$rev_lookup}{map {$_->{name}} values %{$classinfo}} = keys %{$classinfo};
|
|
my $root = $resp->data->{object}[0];
|
|
for my $ch (_get_all_children($root)) {
|
|
$self->_recursive_get($ch, $rev_lookup);
|
|
}
|
|
if ($classinfo->{ip_address}{configuredids}[0]) {
|
|
($config->{ip1}) = $self->_get_specifics(
|
|
'ip_address', $classinfo->{ip_address}{configuredids}[0], ['NIIPAddress']);
|
|
}
|
|
if ($classinfo->{ip_address}{configuredids}[1]) {
|
|
($config->{ip2}) = $self->_get_specifics(
|
|
'ip_address', $classinfo->{ip_address}{configuredids}[1], ['NIIPAddress']);
|
|
}
|
|
if ($classinfo->{external_gateway}{configuredids}[0]) {
|
|
($config->{ip_client}) = $self->_get_specifics(
|
|
'external_gateway', $classinfo->{external_gateway}{configuredids}[0], ['IPAddress']);
|
|
}
|
|
if (exists $classinfo->{vocoder_profile}{configuredids}) {
|
|
for my $id (@{ $classinfo->{vocoder_profile}{configuredids} }) {
|
|
push @{ $config->{in_codecs} }, $self->_get_specifics(
|
|
'vocoder_profile', $id, ['PayloadType']);
|
|
}
|
|
}
|
|
return $config;
|
|
}
|
|
|
|
sub _recursive_get {
|
|
my ($self, $node, $rev_lookup) = @_;
|
|
my $classname = $node->{classname};
|
|
my $oname = $rev_lookup->{$classname};
|
|
my $oid = $node->{oid};
|
|
my $appid = $self->appid;
|
|
for my $ch (_get_all_children($node)) {
|
|
$self->_recursive_get($ch, $rev_lookup);
|
|
}
|
|
if ($oname) {
|
|
$self->pids->{$oname} = $oid;
|
|
push @{ $self->classinfo->{$oname}{configuredids} }, $oid;
|
|
}
|
|
return;
|
|
}
|
|
|
|
sub _get_specifics {
|
|
my ($self, $class, $id, $keys) = @_;
|
|
|
|
my $appid = $self->appid;
|
|
my $classinfo = $self->classinfo->{$class};
|
|
my $classname = $classinfo->{name};
|
|
my @res;
|
|
my $resp = $self->get("/oamp/configuration/objects/$classname/$id?appid=$appid&detaillevel=4");
|
|
if ($resp->code != 200) {
|
|
warn "failed to get objects\n";
|
|
return ();
|
|
}
|
|
for my $key (@{ $keys }) {
|
|
push @res, $resp->data->{property}{$key}{value};
|
|
}
|
|
return @res;
|
|
}
|
|
|
|
sub _create_indent {
|
|
my ($self, @class) = @_;
|
|
my $classinfo = $self->classinfo;
|
|
@class = keys %{ $classinfo } unless @class;
|
|
for my $class (@class) {
|
|
next if (exists $classinfo->{$class}{indent});
|
|
my $parent = $classinfo->{$class}{parent};
|
|
if ($parent eq 'root') {
|
|
$classinfo->{$class}{indent} = 0;
|
|
} else {
|
|
$self->_create_indent($parent);
|
|
$classinfo->{$class}{indent} = $classinfo->{$parent}{indent} + 1;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
sub download_profiles {
|
|
my ($self) = @_;
|
|
|
|
my $appid = $self->appid;
|
|
my $pid = $self->pids->{profile_collection};
|
|
$self->set_header( 'Content-Length' => '0', );
|
|
my $resp = $self->put(
|
|
"/oamp/configuration/objects/Profiles/$pid/provisions/Cached?appid=$appid&sync_key=0",
|
|
);
|
|
return $resp;
|
|
}
|
|
|
|
sub download_route_table {
|
|
my ($self) = @_;
|
|
|
|
my $appid = $self->appid;
|
|
my $pid = $self->pids->{route_table};
|
|
$self->set_header( 'Content-Length' => '0', );
|
|
my $resp = $self->put(
|
|
"/oamp/configuration/objects/RouteTable/$pid/provisions/Cached?appid=$appid&sync_key=0",
|
|
);
|
|
return $resp;
|
|
}
|
|
|
|
sub download_channel_groups {
|
|
my ($self) = @_;
|
|
|
|
my $appid = $self->appid;
|
|
my $pid = $self->pids->{channel_group_collection};
|
|
$self->set_header( 'Content-Length' => '0', );
|
|
my $resp = $self->put(
|
|
"/oamp/configuration/objects/ChannelGroups/$pid/provisions/Cached?appid=$appid&sync_key=0",
|
|
);
|
|
return $resp;
|
|
}
|
|
|
|
#delete all children of bn2020 but not the node itself
|
|
sub delete_all_bn2020 {
|
|
my ($self) = @_;
|
|
|
|
my $appid = $self->appid;
|
|
my $resp = $self->get(
|
|
"/oamp/configuration/objects?appid=$appid",
|
|
);
|
|
if ($resp->code != 200) {
|
|
warn "failed to get objects\n";
|
|
return $resp;
|
|
}
|
|
my $root = $resp->data->{object}[0]; #bn2020
|
|
for my $ch (_get_all_children($root)) {
|
|
$self->_recursive_delete($ch);
|
|
}
|
|
|
|
return $resp;
|
|
}
|
|
|
|
sub _get_all_children {
|
|
my $node = shift;
|
|
if (defined $node->{object}) {
|
|
if ("HASH" eq ref $node->{object}) {
|
|
return ($node->{object},);
|
|
}
|
|
elsif ("ARRAY" eq ref $node->{object}) {
|
|
return @{ $node->{object} };
|
|
}
|
|
}
|
|
return ();
|
|
}
|
|
|
|
sub _recursive_delete {
|
|
my ($self, $node) = @_;
|
|
my $classname = $node->{classname};
|
|
my $oid = $node->{oid};
|
|
my $appid = $self->appid;
|
|
for my $ch (_get_all_children($node)) {
|
|
$self->_recursive_delete($ch);
|
|
}
|
|
return if $classname eq "Node"; # don't delete the bn2020 object (causes reboot)
|
|
my $path = "/oamp/configuration/objects/$classname/$oid?appid=$appid&sync_key=0";
|
|
$self->set_header( 'Content-Length' => '0', );
|
|
my $resp = $self->delete($path);
|
|
#use DDP; p $path; p $resp->code;
|
|
return;
|
|
}
|
|
|
|
sub reboot_and_wait {
|
|
my ($self) = @_;
|
|
|
|
my $appid = $self->appid;
|
|
|
|
$self->set_header( 'Content-Length' => '0', );
|
|
# my $resp = $self->delete("/oamp/configuration/database/new?appid=$appid",
|
|
# '<database name="boot.xml"/>');
|
|
my $resp = $self->_request_with_body("DELETE",
|
|
"/oamp/configuration/database/new?appid=$appid",
|
|
'<database name="boot.xml"/>');
|
|
if ($resp->code != 200) {
|
|
warn "failed to reset config\n";
|
|
return $resp;
|
|
}
|
|
sleep 2; # not to catch the old server
|
|
for (my $i = 0; $i < 30; $i++) { # 600 seconds on 20 seconds timeout
|
|
$resp = $self->get("/");
|
|
last if $resp->code < 400;
|
|
}
|
|
return $resp;
|
|
}
|
|
|
|
# warning: does create a lot of open transactions without deleting them.
|
|
# see the scriptfile for an example how to generate documentation of this
|
|
sub build_documentation {
|
|
my ($self) = @_;
|
|
my $classinfo = $self->classinfo;
|
|
for my $class (keys %{ $classinfo }) {
|
|
my $classname = $classinfo->{$class}{name};
|
|
my $appid = $self->appid;
|
|
my $pid = 10_000;
|
|
my $resp = $self->get(
|
|
"/oamp/configuration/objects/$classname/NULL?detaillevel=4&pid=$pid&appid=$appid",
|
|
);
|
|
if ($resp->code != 200) {
|
|
warn "$class: couldn't fetch info\n";
|
|
next;
|
|
}
|
|
my $data = $resp->data;
|
|
my $options = [];
|
|
for my $p ( keys %{ $data->{property} } ) {
|
|
next if lc($data->{property}{$p}{type}) ne "configure";
|
|
my @choices;
|
|
if ($data->{property}{$p}{choiceset}{choice} &&
|
|
ref $data->{property}{$p}{choiceset}{choice} eq "ARRAY") {
|
|
for my $v (@{ $data->{property}{$p}{choiceset}{choice} }) {
|
|
push @choices, $v->{value} =~ s/^value\((.*)\)$/$1/r;
|
|
}
|
|
}
|
|
push @{ $options }, {
|
|
name => $p,
|
|
default => $data->{property}{$p}{value},
|
|
displayname => $data->{property}{$p}{displayname},
|
|
@choices ? (choices => [@choices]) : (),
|
|
};
|
|
}
|
|
$classinfo->{$class}{options} = $options;
|
|
}
|
|
return $classinfo;
|
|
}
|
|
|
|
sub _build_response_data {
|
|
my ( $self, $req, $pid, $options ) = @_;
|
|
my $resp = {
|
|
pid => $pid,
|
|
property => {},
|
|
};
|
|
for my $p ( keys %{ $req->{property} } ) {
|
|
next
|
|
if lc($req->{property}{$p}{type}) ne "configure";
|
|
$resp->{property}{$p}
|
|
= { configuredvalue => $req->{property}{$p}{value} };
|
|
if ( defined $options->{$p} ) {
|
|
$resp->{property}{$p}{configuredvalue} = $options->{$p};
|
|
}
|
|
}
|
|
return $resp;
|
|
}
|
|
|
|
sub _build_validation_data {
|
|
my ( $self, $req, $pid, $options ) = @_;
|
|
|
|
my $response_data = $self->_build_response_data($req, $pid, $options);
|
|
my @changedopt = ();
|
|
|
|
if ("HASH" eq ref $options && keys %{ $options }) {
|
|
@changedopt = (
|
|
changedproperty => (keys %{ $options })[0],
|
|
);
|
|
}
|
|
|
|
my $resp = {
|
|
pid => $pid,
|
|
appid => $self->appid,
|
|
@changedopt,
|
|
};
|
|
for my $prop (keys %{ $response_data->{property} }) {
|
|
$resp->{$prop} = $response_data->{property}{$prop}{configuredvalue};
|
|
}
|
|
return $resp;
|
|
}
|
|
|
|
sub _build_user_agent {
|
|
my $ua = LWP_Wrapper->new(
|
|
ssl_opts => { verify_hostname => 0 },
|
|
timeout => 20,
|
|
);
|
|
return $ua;
|
|
}
|
|
|
|
sub objects {
|
|
return {
|
|
bn2020 => {
|
|
'property' => {
|
|
'IPType' => { 'configuredvalue' => 'IPv4' },
|
|
'_position_' => { 'configuredvalue' => '' },
|
|
'_localDbSyncKey_' => { 'configuredvalue' => '0' },
|
|
'PacketAudioChannels' => { 'configuredvalue' => 'Unknown' },
|
|
'CFCMode' => { 'configuredvalue' => 'Unknown' },
|
|
'srtpEnable' => { 'configuredvalue' => 'Disabled' },
|
|
'InterfaceType' => { 'configuredvalue' => 'Unknown' },
|
|
'MediaMode' => { 'configuredvalue' => 'Audio Dynamic Density Management' },
|
|
'SwVersion' => { 'configuredvalue' => 'Unknown' },
|
|
'SubNetMask' => { 'configuredvalue' => '' },
|
|
'Name' => { 'configuredvalue' => 'Node0' },
|
|
'ResendLogic' => { 'configuredvalue' => 'Disable' },
|
|
'PacketMultimediaChannels' =>
|
|
{ 'configuredvalue' => 'Unknown' },
|
|
'NetworkMultimediaChannels' =>
|
|
{ 'configuredvalue' => 'Unknown' },
|
|
'IPAddress' => { 'configuredvalue' => '' },
|
|
'ACLName' => { 'configuredvalue' => 'Unrestricted' },
|
|
'NodeType' => { 'configuredvalue' => 'Unknown' },
|
|
'ACL_ID' => { 'configuredvalue' => '0' },
|
|
'IPChannels' => { 'configuredvalue' => 'Unknown' },
|
|
'ID' => { 'configuredvalue' => '0' },
|
|
'_objectName_' =>
|
|
{ 'configuredvalue' => 'BN2020: Node0 - ID: 0' },
|
|
'LicIPChannels' => { 'configuredvalue' => '0' },
|
|
},
|
|
'pid' => '10000',
|
|
|
|
},
|
|
};
|
|
}
|
|
|
|
1;
|
|
|
|
# vim: set tabstop=4 expandtab:
|