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.
		
		
		
		
		
			
		
			
				
					
					
						
							1654 lines
						
					
					
						
							49 KiB
						
					
					
				
			
		
		
	
	
							1654 lines
						
					
					
						
							49 KiB
						
					
					
				| package NGCP::Panel::Utils::DialogicImg;
 | |
| 
 | |
| 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;
 | |
|     };
 | |
| }
 | |
| 
 | |
| 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:
 |