diff options
| author | root <root@colazero.tele.tg18.gathering.org> | 2018-03-21 14:13:32 +0100 | 
|---|---|---|
| committer | root <root@colazero.tele.tg18.gathering.org> | 2018-03-21 14:13:32 +0100 | 
| commit | 05e09f3b63269a48d1beb0dc9900b180101cec7f (patch) | |
| tree | b96dbc2cc53a79968e4c60a7b3a729ea4d937299 | |
| parent | c6d676b8d07dcd081626ad86849900977327bbb7 (diff) | |
| parent | 8bee35e8be72510d8bdc7ed5de49a8d031e829a5 (diff) | |
Merge branch 'master' of github.com:tech-server/gondul
| -rw-r--r-- | ansible/roles/postgres/files/schema.sql | 101 | ||||
| -rwxr-xr-x | web/api/public/switches | 2 | ||||
| -rw-r--r-- | web/api/read/networks | 37 | ||||
| -rwxr-xr-x | web/api/read/switches-management | 4 | ||||
| -rw-r--r-- | web/api/write/network-add | 49 | ||||
| -rw-r--r-- | web/api/write/network-update | 114 | ||||
| -rwxr-xr-x | web/api/write/switch-add | 8 | ||||
| -rw-r--r-- | web/index.html | 7 | ||||
| -rw-r--r-- | web/js/nms-info-box.js | 266 | ||||
| -rw-r--r-- | web/js/nms.js | 17 | 
10 files changed, 536 insertions, 69 deletions
diff --git a/ansible/roles/postgres/files/schema.sql b/ansible/roles/postgres/files/schema.sql index 41d513d..ed94e80 100644 --- a/ansible/roles/postgres/files/schema.sql +++ b/ansible/roles/postgres/files/schema.sql @@ -10,14 +10,14 @@ SET check_function_bodies = false;  SET client_min_messages = warning;  -- --- Name: plpgsql; Type: EXTENSION; Schema: -; Owner:  +-- Name: plpgsql; Type: EXTENSION; Schema: -; Owner:  --  CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;  -- --- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner:  +-- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner:  --  COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language'; @@ -44,7 +44,7 @@ SET default_tablespace = '';  SET default_with_oids = false;  -- --- Name: config; Type: TABLE; Schema: public; Owner: nms; Tablespace:  +-- Name: config; Type: TABLE; Schema: public; Owner: nms; Tablespace:  --  CREATE TABLE config ( @@ -79,7 +79,7 @@ ALTER SEQUENCE config_id_seq OWNED BY config.id;  -- --- Name: dhcp; Type: TABLE; Schema: public; Owner: nms; Tablespace:  +-- Name: dhcp; Type: TABLE; Schema: public; Owner: nms; Tablespace:  --  CREATE TABLE dhcp ( @@ -94,7 +94,7 @@ CREATE TABLE dhcp (  ALTER TABLE dhcp OWNER TO nms;  -- --- Name: linknet_ping; Type: TABLE; Schema: public; Owner: nms; Tablespace:  +-- Name: linknet_ping; Type: TABLE; Schema: public; Owner: nms; Tablespace:  --  CREATE TABLE linknet_ping ( @@ -108,7 +108,7 @@ CREATE TABLE linknet_ping (  ALTER TABLE linknet_ping OWNER TO nms;  -- --- Name: linknets; Type: TABLE; Schema: public; Owner: nms; Tablespace:  +-- Name: linknets; Type: TABLE; Schema: public; Owner: nms; Tablespace:  --  CREATE TABLE linknets ( @@ -146,7 +146,7 @@ ALTER SEQUENCE linknets_linknet_seq OWNED BY linknets.linknet;  -- --- Name: oplog; Type: TABLE; Schema: public; Owner: nms; Tablespace:  +-- Name: oplog; Type: TABLE; Schema: public; Owner: nms; Tablespace:  --  CREATE TABLE oplog ( @@ -182,7 +182,7 @@ ALTER SEQUENCE oplog_id_seq OWNED BY oplog.id;  -- --- Name: ping; Type: TABLE; Schema: public; Owner: nms; Tablespace:  +-- Name: ping; Type: TABLE; Schema: public; Owner: nms; Tablespace:  --  CREATE TABLE ping ( @@ -195,7 +195,7 @@ CREATE TABLE ping (  ALTER TABLE ping OWNER TO nms;  -- --- Name: ping_secondary_ip; Type: TABLE; Schema: public; Owner: nms; Tablespace:  +-- Name: ping_secondary_ip; Type: TABLE; Schema: public; Owner: nms; Tablespace:  --  CREATE TABLE ping_secondary_ip ( @@ -208,7 +208,7 @@ CREATE TABLE ping_secondary_ip (  ALTER TABLE ping_secondary_ip OWNER TO nms;  -- --- Name: seen_mac; Type: TABLE; Schema: public; Owner: nms; Tablespace:  +-- Name: seen_mac; Type: TABLE; Schema: public; Owner: nms; Tablespace:  --  CREATE TABLE seen_mac ( @@ -221,7 +221,7 @@ CREATE TABLE seen_mac (  ALTER TABLE seen_mac OWNER TO nms;  -- --- Name: snmp; Type: TABLE; Schema: public; Owner: nms; Tablespace:  +-- Name: snmp; Type: TABLE; Schema: public; Owner: nms; Tablespace:  --  CREATE TABLE snmp ( @@ -256,27 +256,23 @@ ALTER SEQUENCE snmp_id_seq OWNED BY snmp.id;  -- --- Name: switches; Type: TABLE; Schema: public; Owner: nms; Tablespace:  +-- Name: switches; Type: TABLE; Schema: public; Owner: nms; Tablespace:  --  CREATE TABLE switches (      switch integer DEFAULT nextval(('"switches_switch_seq"'::text)::regclass) NOT NULL,      mgmt_v4_addr inet, +    mgmt_v6_addr inet, +    mgmt_vlan character varying,      sysname character varying NOT NULL,      last_updated timestamp with time zone,      locked boolean DEFAULT false NOT NULL,      poll_frequency interval DEFAULT '00:01:00'::interval NOT NULL,      community character varying DEFAULT 'FullPuppTilNMS'::character varying NOT NULL, -    mgmt_v6_addr inet,      placement box, -    subnet4 cidr, -    subnet6 cidr,      distro_name character varying,      distro_phy_port character varying(100), -    mgmt_v6_gw inet, -    mgmt_v4_gw inet, -    mgmt_vlan integer DEFAULT 666, -    traffic_vlan integer, +    traffic_vlan character varying,      tags jsonb DEFAULT '[]'::jsonb  ); @@ -298,6 +294,35 @@ CREATE SEQUENCE switches_switch_seq  ALTER TABLE switches_switch_seq OWNER TO nms;  -- +-- Name: networks; Type: TABLE; Schema: public; Owner: nms; Tablespace: +-- + +CREATE TABLE networks ( +    network integer DEFAULT nextval(('"networks_network_seq"'::text)::regclass) NOT NULL, +    name character varying NOT NULL, +    last_updated timestamp with time zone, +    placement box, +    subnet4 cidr, +    subnet6 cidr, +    gw4 inet, +    gw6 inet, +    routing_point character varying, +    vlan integer, +    tags jsonb DEFAULT '[]'::jsonb +); + +ALTER TABLE networks OWNER TO nms; + +CREATE SEQUENCE networks_network_seq +    START WITH 1 +    INCREMENT BY 1 +    NO MINVALUE +    NO MAXVALUE +    CACHE 1; + +ALTER TABLE networks_network_seq OWNER TO nms; + +--  -- Name: id; Type: DEFAULT; Schema: public; Owner: nms  -- @@ -326,7 +351,7 @@ ALTER TABLE ONLY snmp ALTER COLUMN id SET DEFAULT nextval('snmp_id_seq'::regclas  -- --- Name: seen_mac_pkey; Type: CONSTRAINT; Schema: public; Owner: nms; Tablespace:  +-- Name: seen_mac_pkey; Type: CONSTRAINT; Schema: public; Owner: nms; Tablespace:  --  ALTER TABLE ONLY seen_mac @@ -334,7 +359,7 @@ ALTER TABLE ONLY seen_mac  -- --- Name: switches_pkey; Type: CONSTRAINT; Schema: public; Owner: nms; Tablespace:  +-- Name: switches_pkey; Type: CONSTRAINT; Schema: public; Owner: nms; Tablespace:  --  ALTER TABLE ONLY switches @@ -342,7 +367,7 @@ ALTER TABLE ONLY switches  -- --- Name: switches_sysname_key; Type: CONSTRAINT; Schema: public; Owner: nms; Tablespace:  +-- Name: switches_sysname_key; Type: CONSTRAINT; Schema: public; Owner: nms; Tablespace:  --  ALTER TABLE ONLY switches @@ -350,7 +375,7 @@ ALTER TABLE ONLY switches  -- --- Name: switches_sysname_key1; Type: CONSTRAINT; Schema: public; Owner: nms; Tablespace:  +-- Name: switches_sysname_key1; Type: CONSTRAINT; Schema: public; Owner: nms; Tablespace:  --  ALTER TABLE ONLY switches @@ -358,98 +383,98 @@ ALTER TABLE ONLY switches  -- --- Name: dhcp_ip; Type: INDEX; Schema: public; Owner: nms; Tablespace:  +-- Name: dhcp_ip; Type: INDEX; Schema: public; Owner: nms; Tablespace:  --  CREATE INDEX dhcp_ip ON dhcp USING btree (ip);  -- --- Name: dhcp_mac; Type: INDEX; Schema: public; Owner: nms; Tablespace:  +-- Name: dhcp_mac; Type: INDEX; Schema: public; Owner: nms; Tablespace:  --  CREATE INDEX dhcp_mac ON dhcp USING btree (mac);  -- --- Name: dhcp_switch; Type: INDEX; Schema: public; Owner: nms; Tablespace:  +-- Name: dhcp_switch; Type: INDEX; Schema: public; Owner: nms; Tablespace:  --  CREATE INDEX dhcp_switch ON dhcp USING btree (switch);  -- --- Name: dhcp_time; Type: INDEX; Schema: public; Owner: nms; Tablespace:  +-- Name: dhcp_time; Type: INDEX; Schema: public; Owner: nms; Tablespace:  --  CREATE INDEX dhcp_time ON dhcp USING btree ("time");  -- --- Name: ping_index; Type: INDEX; Schema: public; Owner: nms; Tablespace:  +-- Name: ping_index; Type: INDEX; Schema: public; Owner: nms; Tablespace:  --  CREATE INDEX ping_index ON ping USING btree ("time");  -- --- Name: ping_secondary_index; Type: INDEX; Schema: public; Owner: nms; Tablespace:  +-- Name: ping_secondary_index; Type: INDEX; Schema: public; Owner: nms; Tablespace:  --  CREATE INDEX ping_secondary_index ON ping_secondary_ip USING btree ("time");  -- --- Name: seen_mac_addr_family; Type: INDEX; Schema: public; Owner: nms; Tablespace:  +-- Name: seen_mac_addr_family; Type: INDEX; Schema: public; Owner: nms; Tablespace:  --  CREATE INDEX seen_mac_addr_family ON seen_mac USING btree (family(address));  -- --- Name: seen_mac_seen; Type: INDEX; Schema: public; Owner: nms; Tablespace:  +-- Name: seen_mac_seen; Type: INDEX; Schema: public; Owner: nms; Tablespace:  --  CREATE INDEX seen_mac_seen ON seen_mac USING btree (seen);  -- --- Name: snmp_time; Type: INDEX; Schema: public; Owner: nms; Tablespace:  +-- Name: snmp_time; Type: INDEX; Schema: public; Owner: nms; Tablespace:  --  CREATE INDEX snmp_time ON snmp USING btree ("time");  -- --- Name: snmp_time15; Type: INDEX; Schema: public; Owner: nms; Tablespace:  +-- Name: snmp_time15; Type: INDEX; Schema: public; Owner: nms; Tablespace:  --  CREATE INDEX snmp_time15 ON snmp USING btree (id, switch);  -- --- Name: snmp_time6; Type: INDEX; Schema: public; Owner: nms; Tablespace:  +-- Name: snmp_time6; Type: INDEX; Schema: public; Owner: nms; Tablespace:  --  CREATE INDEX snmp_time6 ON snmp USING btree ("time" DESC, switch);  -- --- Name: switches_switch; Type: INDEX; Schema: public; Owner: nms; Tablespace:  +-- Name: switches_switch; Type: INDEX; Schema: public; Owner: nms; Tablespace:  --  CREATE INDEX switches_switch ON switches USING hash (switch);  -- --- Name: updated_index2; Type: INDEX; Schema: public; Owner: nms; Tablespace:  +-- Name: updated_index2; Type: INDEX; Schema: public; Owner: nms; Tablespace:  --  CREATE INDEX updated_index2 ON linknet_ping USING btree ("time");  -- --- Name: updated_index3; Type: INDEX; Schema: public; Owner: nms; Tablespace:  +-- Name: updated_index3; Type: INDEX; Schema: public; Owner: nms; Tablespace:  --  CREATE INDEX updated_index3 ON ping_secondary_ip USING btree ("time"); @@ -583,5 +608,3 @@ GRANT ALL ON TABLE switches TO nms;  --  -- PostgreSQL database dump complete --- - diff --git a/web/api/public/switches b/web/api/public/switches index 44fde3c..8e7f333 100755 --- a/web/api/public/switches +++ b/web/api/public/switches @@ -13,7 +13,7 @@ use Data::Dumper;  $nms::web::cc{'max-age'} = "5";  $nms::web::cc{'stale-while-revalidate'} = "30"; -my $q2 = $nms::web::dbh->prepare('select switch,sysname,tags,distro_name,placement,mgmt_v4_addr,mgmt_v6_addr,mgmt_v4_gw,mgmt_v6_gw,mgmt_vlan,traffic_vlan,poll_frequency,community,last_updated from switches where placement is not null and deleted = false'); +my $q2 = $nms::web::dbh->prepare('select switch, sysname, tags, distro_name, placement, last_updated from switches where placement is not null and deleted = false');  $q2->execute();  while (my $ref = $q2->fetchrow_hashref()) { diff --git a/web/api/read/networks b/web/api/read/networks new file mode 100644 index 0000000..870ae8c --- /dev/null +++ b/web/api/read/networks @@ -0,0 +1,37 @@ +#! /usr/bin/perl +# vim:ts=8:sw=8 + +use CGI qw(fatalsToBrowser); +use DBI; +use lib '/opt/gondul/include'; +use nms; +use nms::web; +use strict; +use warnings; +use Data::Dumper; + +$nms::web::cc{'max-age'} = "5"; +$nms::web::cc{'stale-while-revalidate'} = "30"; + +my $q2 = $nms::web::dbh->prepare('select network, name, vlan, tags, routing_point, placement, last_updated, subnet4, subnet6, gw4, gw6 from networks'); + +$q2->execute(); +while (my $ref = $q2->fetchrow_hashref()) { +	$ref->{'placement'} =~ /\((-?\d+),(-?\d+)\),\((-?\d+),(-?\d+)\)/; +	my ($x1, $y1, $x2, $y2) = ($1, $2, $3, $4); +	my $name = $ref->{'name'}; +	$nms::web::json{'networks'}{$ref->{'name'}}{'vlan'} = $ref->{'vlan'}; +	$nms::web::json{'networks'}{$ref->{'name'}}{'subnet4'} = $ref->{'subnet4'}; +	$nms::web::json{'networks'}{$ref->{'name'}}{'subnet6'} = $ref->{'subnet6'}; +	$nms::web::json{'networks'}{$ref->{'name'}}{'gw4'} = $ref->{'gw4'}; +	$nms::web::json{'networks'}{$ref->{'name'}}{'gw6'} = $ref->{'gw6'}; +	$nms::web::json{'networks'}{$ref->{'name'}}{'placement'}{'x'} = $x2; +	$nms::web::json{'networks'}{$ref->{'name'}}{'placement'}{'y'} = $y2; +	$nms::web::json{'networks'}{$ref->{'name'}}{'placement'}{'width'} = $x1 - $x2; +	$nms::web::json{'networks'}{$ref->{'name'}}{'placement'}{'height'} = $y1 - $y2; +	$nms::web::json{'networks'}{$ref->{'name'}}{'routing_point'} = $ref->{'routing_point'}; +	my $data = JSON::XS::decode_json($ref->{'tags'}); +	$nms::web::json{'networks'}{$ref->{'name'}}{'tags'} = $data; +} + +finalize_output(); diff --git a/web/api/read/switches-management b/web/api/read/switches-management index 9182b60..77badf4 100755 --- a/web/api/read/switches-management +++ b/web/api/read/switches-management @@ -20,9 +20,9 @@ $nms::web::cc{'max-age'} = "5";  $nms::web::cc{'stale-while-revalidate'} = "30";  if (!defined($switch)) { -	$q2 = $nms::web::dbh->prepare('select sysname,host(mgmt_v4_addr) as mgmt_v4_addr,subnet4,subnet6,host(mgmt_v6_addr) as mgmt_v6_addr,host(mgmt_v4_gw) as mgmt_v4_gw,host(mgmt_v6_gw) as mgmt_v6_gw,mgmt_vlan,traffic_vlan,poll_frequency,last_updated,distro_name,distro_phy_port,community from switches where placement is not null and deleted = false'); +	$q2 = $nms::web::dbh->prepare('select switches.sysname, host(switches.mgmt_v4_addr) as mgmt_v4_addr, host(switches.mgmt_v6_addr) as mgmt_v6_addr, switches.mgmt_vlan, switches.traffic_vlan, switches.poll_frequency, switches.last_updated, switches.distro_name, switches.distro_phy_port, switches.community, traffic_net.subnet4, traffic_net.subnet6, mgmt_net.gw4 as mgmt_v4_gw, mgmt_net.gw6 as mgmt_v6_gw from switches left join networks as traffic_net on (switches.traffic_vlan = traffic_net.name) left join networks as mgmt_net on (switches.mgmt_vlan = mgmt_net.name) where switches.placement is not null and switches.deleted = false;');  } else { -	$q2 = $nms::web::dbh->prepare('select sysname,host(mgmt_v4_addr) as mgmt_v4_addr,subnet4,subnet6,host(mgmt_v6_addr) as mgmt_v6_addr,host(mgmt_v4_gw) as mgmt_v4_gw,host(mgmt_v6_gw) as mgmt_v6_gw,mgmt_vlan,traffic_vlan,poll_frequency,last_updated,distro_name,distro_phy_port,community from switches where placement is not null and deleted = false and sysname = ' . $nms::web::dbh->quote($switch) . ';'); +	$q2 = $nms::web::dbh->prepare('select sysname,host(mgmt_v4_addr) as mgmt_v4_addr,host(mgmt_v6_addr) as mgmt_v6_addr,mgmt_vlan,traffic_vlan,poll_frequency,last_updated,distro_name,distro_phy_port,community from switches where placement is not null and sysname = ' . $nms::web::dbh->quote($switch) . ' and switches.deleted = false;');  }  $q2->execute(); diff --git a/web/api/write/network-add b/web/api/write/network-add new file mode 100644 index 0000000..d1aab4e --- /dev/null +++ b/web/api/write/network-add @@ -0,0 +1,49 @@ +#! /usr/bin/perl +# vim:ts=8:sw=8 + +#use CGI qw(fatalsToBrowser); +use DBI; +use lib '/opt/gondul/include'; +use nms; +use nms::web qw(%get_params %json finalize_output get_input $dbh); +use nms::util qw(guess_placement); +use strict; +use warnings; +use JSON; +use Data::Dumper; +use nms::oplog qw(oplog); + +$nms::web::cc{'max-age'} = "0"; + +my $in = get_input(); +my @tmp = @{JSON::XS::decode_json($in)}; + +my @added; +my @dups; + +my $sth = $nms::web::dbh->prepare("SELECT name FROM networks WHERE name=?"); + +foreach my $tmp2 (@tmp) { +	my %network = %{$tmp2}; +	my $affected = 0; +	my %template = (); +	if (not defined($network{'name'})) { +		next; +	} + +	$sth->execute( $network{'name'}); +	while ( my @row = $sth->fetchrow_array ) { +		$affected += 1; +	} + +	if ($affected == 0) { +		$nms::web::dbh->do("INSERT INTO NETWORKS (name)  VALUES ('$network{'name'}');"); +		push @added, $network{'name'}; +		oplog("\"" . $network{'name'} . "\"", "Network added: " . $network{'name'}); +	} +} + +$json{'networks_addded'} = \@added; + +print "X-ban: /api/.*\n"; +finalize_output(); diff --git a/web/api/write/network-update b/web/api/write/network-update new file mode 100644 index 0000000..f6684c5 --- /dev/null +++ b/web/api/write/network-update @@ -0,0 +1,114 @@ +#! /usr/bin/perl +# vim:ts=8:sw=8 + +#use CGI qw(fatalsToBrowser); +use DBI; +use lib '/opt/gondul/include'; +use nms; +use nms::web qw(%get_params %json finalize_output get_input $dbh); +use nms::util qw(guess_placement); +use strict; +use warnings; +use JSON; +use Data::Dumper; + +$nms::web::cc{'max-age'} = "0"; + +my $in = get_input(); +my @tmp = @{JSON::XS::decode_json($in)}; + +my @added; +my @dups; + +my $sth = $nms::web::dbh->prepare("SELECT name FROM networks WHERE name=?"); + + +my @fields = ('name','last_updated','placement','subnet4','subnet6','gw4','gw6','routing_point','vlan','tags'); + +sub convertplace +{ +	my %in = %{$_[0]}; +	my %out = (); + +	if (not defined $in{'x1'} and defined($in{'x'})) { +		$out{'x1'} = int($in{'x'}); +		$out{'y1'} = int($in{'y'}); +		$out{'xx'} = int($in{'x'} + $in{'width'}); +		$out{'yy'} = int($in{'y'} + $in{'height'}); +	} else { +		return \%in; +	} +	return \%out; +} + +foreach my $tmp2 (@tmp) { +	my %network = %{$tmp2}; +	my $affected = 0; +	my %template = (); +	map { $template{$_} = 'DEFAULT' } @fields; +	if (not defined($network{'sysname'})) { +		next; +	} + +	$sth->execute( $network{'sysname'}); +	while ( my @row = $sth->fetchrow_array ) { +		$affected += 1; +	} + +	if ($affected == 0) { +		my %placement; +		if (not defined ($network{'placement'})) { +			%placement = guess_placement($network{'sysname'}); +		} else { +			%placement = %{convertplace($network{'sysname'})}; +		} +		my ($x1,$x2,$y1,$y2); +		$x1 = $placement{'x1'}; +		$y1 = $placement{'y1'}; +		$x2 = $placement{'xx'}; +		$y2 = $placement{'yy'}; +		$network{'placement'} = "(($x1,$y1),($x2,$y2))"; + +		map { +			if (defined ($template{$_})) { +					$template{$_} = $dbh->quote($network{$_}); +			} +		} keys %network; + + +		$nms::web::dbh->do("INSERT INTO NETWORKS (name, last_updated, placement, subnet4, subnet6, routing_point, gw4, gw6, vlan, tags)  VALUES ($template{'sysname'}, $template{'last_updated'}, $template{'placement'}, $template{'subnet4'}, $template{'subnet6'}, $template{'routing_point'}, $template{'gw4'}, $template{'gw6'}, $template{'vlan'}, $template{'tags'});"); +		push @added, $network{'sysname'}; +	} else { +		if (defined($network{'placement'})) { +			my %placement; +			if ($network{'placement'} eq "reset") { +				%placement = guess_placement($network{'sysname'}); +			} else { +				%placement = %{convertplace($network{'placement'})}; +			} +			my ($x1,$x2,$y1,$y2); +			$x1 = $placement{'x1'}; +			$y1 = $placement{'y1'}; +			$x2 = $placement{'xx'}; +			$y2 = $placement{'yy'}; +			$network{'placement'} = "(($x1,$y1),($x2,$y2))"; +			push @dups, "not really, but: " . $network{'placement'}; +		} +		if (defined($network{'tags'})) { +			$network{'tags'} =~ s/'/"/g; +		} +		my @set; +		map { +			if (defined($template{$_})) { +				push @set, "$_=" . $dbh->quote($network{$_}); +			} +		} keys %network; +		$nms::web::dbh->do("UPDATE NETWORKS SET " . join(", ", @set) . "WHERE name=" . $dbh->quote($network{'sysname'}) . ";"); +		push @dups, $network{'sysname'}; +	} +} +$json{'networks_addded'} = \@added; +$json{'networks_updated'} = \@dups; + +print "X-ban: /api/.*networks.*\n"; +finalize_output(); diff --git a/web/api/write/switch-add b/web/api/write/switch-add index dbaa1e5..c92cf31 100755 --- a/web/api/write/switch-add +++ b/web/api/write/switch-add @@ -23,7 +23,7 @@ my @dups;  my $sth = $nms::web::dbh->prepare("SELECT sysname FROM switches WHERE sysname=?"); -my @fields = ( 'community', 'distro_name', 'distro_phy_port', 'mgmt_v4_addr', 'mgmt_v4_gw', 'mgmt_v6_addr', 'mgmt_v6_gw', 'mgmt_vlan', 'placement', 'poll_frequency', 'subnet4', 'subnet6', 'sysname', 'traffic_vlan'); +my @fields = ( 'community', 'distro_name', 'distro_phy_port', 'mgmt_v4_addr', 'mgmt_v6_addr', 'mgmt_vlan', 'placement', 'poll_frequency', 'sysname', 'traffic_vlan');  sub convertplace  { @@ -74,15 +74,15 @@ foreach my $tmp2 (@tmp) {  		$x2 = $placement{'xx'};  		$y2 = $placement{'yy'};  		$switch{'placement'} = "(($x1,$y1),($x2,$y2))"; -		 +  		map {  			if (defined ($template{$_})) {  					$template{$_} = $dbh->quote($switch{$_});  			}  		} keys %switch; -		 -		$nms::web::dbh->do("INSERT INTO SWITCHES (mgmt_v4_addr, sysname, poll_frequency, community, mgmt_v6_addr, placement,subnet4,subnet6,distro_name)  VALUES ($template{'mgmt_v4_addr'}, $template{'sysname'}, $template{'poll_frequency'}, $template{'community'}, $template{'mgmt_v6_addr'}, $template{'placement'},$template{'subnet4'},$template{'subnet6'},$template{'distro_name'});"); + +		$nms::web::dbh->do("INSERT INTO SWITCHES (mgmt_v4_addr, sysname, poll_frequency, community, mgmt_v6_addr, placement, distro_name)  VALUES ($template{'mgmt_v4_addr'}, $template{'sysname'}, $template{'poll_frequency'}, $template{'community'}, $template{'mgmt_v6_addr'}, $template{'placement'}, $template{'distro_name'});");  		push @added, $switch{'sysname'};  		oplog("\"" . $switch{'sysname'} . "\"", "Switch added: " . $switch{'sysname'});  	} diff --git a/web/index.html b/web/index.html index aeb26b3..d8f2a60 100644 --- a/web/index.html +++ b/web/index.html @@ -70,8 +70,11 @@  	  	<li class="gondul-is-private"><a href="#" onclick="nmsMap.moveSet(true);">Enable switch moving</a></li>  	  	<li class="gondul-is-private"><a href="#" onclick="nmsMap.moveSet(false);">Disable switch moving</a></li>  	  	<li class="gondul-is-private"><a href="#" onclick="nmsInfoBox.showWindow('addSwitch')">Add switch</a></li> -		<li class="gondul-is-private divider"> </li> -		<li class="gondul-is-private dropdown-header">Inventory lists</li> +      <li class="gondul-is-private divider"> </li> +      <li class="gondul-is-private"><a href="#" onclick="nmsInfoBox.showWindow('listNetwork')">List networks</a></li> +      <li class="gondul-is-private"><a href="#" onclick="nmsInfoBox.showWindow('addNetwork')">Add network</a></li> +      <li class="gondul-is-private divider"> </li> +      <li class="gondul-is-private dropdown-header">Inventory lists</li>  	  	<li class="gondul-is-private"><a href="#" onclick="nmsInfoBox.showWindow('inventoryListing','distro_name');">Distro names</a></li>  	  	<li class="gondul-is-private"><a href="#" onclick="nmsInfoBox.showWindow('inventoryListing','sysDescr')">System description</a></li>  	  	<li class="gondul-is-private"><a href="#" onclick="nmsInfoBox.showWindow('inventoryListing','jnxBoxSerialNo')">Serial Numbers</a></li> diff --git a/web/js/nms-info-box.js b/web/js/nms-info-box.js index 73dcd72..1971b61 100644 --- a/web/js/nms-info-box.js +++ b/web/js/nms-info-box.js @@ -57,6 +57,20 @@ var nmsInfoBox = nmsInfoBox || {  		}  	},  	{ +		'id': 'networkInfo', +		'title': 'Network info', +		'views': { +			'initial': { +				'name': 'Summary', +				'panels': ['networkSummary'] +			}, +			'edit': { +				'name': 'Edit settings', +				'panels': ['networkEdit'] +			} +		} +	}, +	{  		'id': 'addSwitch',  		'title': 'Add new switch(es)',  		'views': { @@ -67,6 +81,16 @@ var nmsInfoBox = nmsInfoBox || {  		}  	},  	{ +		'id': 'addNetwork', +		'title': 'Add new network(s)', +		'views': { +			'initial': { +				'name': 'Add network', +				'panels': ['networkAdd'] +			} +		} +	}, +	{  		'id': 'searchHelp',  		'title': 'Search help',  		'views': { @@ -76,16 +100,16 @@ var nmsInfoBox = nmsInfoBox || {  			}  		}  	}, -        { -                'id': 'searchResults', -                'title': 'Search Results', -                'views': { -                        'initial': { -                                'name': 'Search Results', -                                'panels': ['searchResults'] -                        } -                } -        }, +  { +		'id': 'searchResults', +		'title': 'Search Results', +		'views': { +			'initial': { +				'name': 'Search Results', +				'panels': ['searchResults'] +			} +		} +	},  	{  		'id': 'inventoryListing',  		'title': 'Inventory listing', @@ -103,8 +127,18 @@ var nmsInfoBox = nmsInfoBox || {  				'panels': ['inventoryListing:jnxBoxSerialNo']  			}  		} -	} -	], +	}, +	{ +		'id': 'listNetwork', +		'title': 'Networks', +		'views': { +			'initial': { +				'name': 'List all networks', +				'panels': ['listNetworks'] +			} +		} +	}, +],  	_panelTypes: {} //Populate by using the nmsInfoBox.addPanelType method  }; @@ -952,7 +986,7 @@ var switchEditPanel = function () {  			var tmpsw = '\'' + this.sw + '\'';  			var tmpv = '\'' + v + '\'';  			var tmphandler = '"nmsInfoBox._editChange(' + tmpsw + ',' + tmpv + ');"'; -			var html = '<input type="text" class="form-control" value="' + template[v] + '" id="edit-' + this.sw + '-' + v + '" onchange=' + tmphandler + ' oninput=' + tmphandler + ' ' + (v == 'sysname' ? "readonly" : "") + '>'; +			var html = '<input type="text" class="form-control" value="' + template[v] + '" id="edit-' + this.sw + '-' + v + '" onchange=' + tmphandler + ' oninput=' + tmphandler + ' ' + (v == 'sysname' || v == 'subnet4' || v == 'subnet6' || v == 'mgmt_v4_gw' || v == 'mgmt_v6_gw' ? "readonly" : "") + '>';  			if (v == "placement") {  				v = "placement <a onclick='var _x = document.getElementById(\"edit-" + this.sw + "-placement\"); _x.value = \"\\\"reset\\\"\"; _x.oninput();' class='pull-right'>Reset</a>";  			} @@ -1164,6 +1198,212 @@ nmsInfoBox.setLegendPick = function(tag,id) {  	nms.legendPick = {handler: tag, idx: id};  }  nmsInfoBox.addPanelType("switchSummary",switchSummaryPanel); + +/* +* Panel type: Add network +* +* Lets you add a new network using the network-add api +* +*/ +var networkAddPanel = function() { +	nmsInfoPanel.call(this,"networkAdd"); +	this.refresh = function(reason) { +		var domObj = document.createElement("div"); +		domObj.innerHTML = '<input type="text" class="form-control" id="create-network-name" placeholder="Space-seaprated list of networks"><button class="btn btn-default" onclick="nmsInfoBox._windowHandler.doInPanel(\'' + this.id +'\',\'save\');">Add network</button>' +		this._render(domObj); +	}; +	this.save = function () { +		var name = document.getElementById('create-network-name').value.split(" "); +		var myData = []; +		for (var v in name) { +			myData.push({"name":name[v]}); +		} +		var myData = JSON.stringify(myData); +		$.ajax({ +			type: "POST", +			url: "/api/write/network-add", +			dataType: "text", +			data:myData, +			success: function (data, textStatus, jqXHR) { +				var result = JSON.parse(data); +				if(result.networks_added.length > 0) { // FIXME unresolved variable switches_addded +					nmsInfoBox.hide(); +				} +				nmsData.invalidate("switches"); +				nmsData.invalidate("smanagement"); +				nmsData.invalidate("networks"); +			} +		}); +	}; +}; +nmsInfoBox.addPanelType("networkAdd",networkAddPanel); + +/* +* List networks +* +* Shows all networks +* +*/ +var networkListPanel = function() { +	nmsInfoPanel.call(this,"listNetworks"); +	this.refresh = function(reason) { +		var collator = new Intl.Collator(undefined, {numeric: true, sensitivity: 'base'}); +		var networks = nmsData.networks.networks; +		var table = document.createElement('table'); +		table.className = "table table-condensed"; +		table.id = "searchResults-table" +		for (var net in networks) { +			console.log(networks[net]); +			var row = table.insertRow(net); +			var cell1 = row.insertCell(0); +			var cell2 = row.insertCell(1); +			var cell3 = row.insertCell(2); +			cell1.innerHTML = "<a href='#' onclick='nmsInfoBox.showWindow(\"networkInfo\",\""+net+"\");'>"+net+ '</a>'; +			cell2.innerHTML = networks[net].vlan; +			cell3.innerHTML = networks[net].routing_point; +		} +		this._render(table); + +	}; +}; +nmsInfoBox.addPanelType("listNetworks",networkListPanel); + +/* +* Panel type: Network summary +* +* Display a summary +* +*/ +var networkSummaryPanel = function() { +	nmsInfoPanel.call(this,"networkSummary"); +	this.refresh = function(reason) { +		var network = this.sw; + +	}; +} +nmsInfoBox.addPanelType("networkSummary",networkSummaryPanel); + +/* +* Panel type: Edit networki +* +*  Lets you edit basic networks data through the network-update api +* +*/ +var networkEditPanel = function() { +	nmsInfoPanel.call(this,"networkEdit"); +	this.refresh = function(reason) { +		var net = []; +		try { +			net = nmsData.networks.networks[this.sw]; +		} catch(e) {} + + +		var domObj = document.createElement("div"); +		var template = {}; + +		nmsInfoBox._editValues = {}; +		var place; +		var tags; +		for (var v in net) { +			/* +			* Placement and tags needs to be sent and edited +			* as plain JSON... +			*/ +			if (v == "placement") { +				place = JSON.stringify(net[v]); +				template[v] = place; +				continue; +			} +			if (v == "tags") { +				tags = JSON.stringify(net[v]); +				template[v] = tags; +				continue; +			} +			template[v] = nmsInfoBox._nullBlank(net[v]); +		} +		var content = []; +		for (v in template) { +			var tmpsw = '\'' + this.sw + '\''; +			var tmpv = '\'' + v + '\''; +			var tmphandler = '"nmsInfoBox._editChange(' + tmpsw + ',' + tmpv + ');"'; +			var html = '<input type="text" class="form-control" value="' + template[v] + '" id="edit-' + this.sw + '-' + v + '" onchange=' + tmphandler + ' oninput=' + tmphandler + ' ' + (v == 'name' ? "readonly" : "") + '>'; +			if (v == "placement") { +				v = "placement <a onclick='var _x = document.getElementById(\"edit-" + this.sw + "-placement\"); _x.value = \"\\\"reset\\\"\"; _x.oninput();' class='pull-right'>Reset</a>"; +			} +			content.push([v, html]); +		} + +		content.sort(); + +		var table = nmsInfoBox._makeTable(content); +		domObj.appendChild(table); + +		var outputCont = document.createElement("div"); +		outputCont.id = "edit-output-cont"; +		outputCont.classList.add("collapse"); +		outputCont.innerHTML = "<h5>Request preview</h5>"; +		var output = document.createElement("output"); +		output.id = "edit-output"; +		outputCont.appendChild(output); +		domObj.appendChild(outputCont); + +		var nav = document.createElement("nav"); +		nav.classList.add("nav","nav-pills"); + +		var submit = document.createElement("button"); +		submit.innerHTML = "Save changes"; +		submit.classList.add("btn", "btn-primary"); +		submit.id = "edit-submit-" + this.sw; +		submit.setAttribute("onclick","nmsInfoBox._windowHandler.doInPanel('" + this.id + "','save');"); +		nav.appendChild(submit); + +		var toggleDetails = document.createElement("button"); +		toggleDetails.innerHTML = '<span class="glyphicon glyphicon-menu-hamburger" aria-hidden="true"></span>'; +		toggleDetails.classList.add("btn", "btn-default", "pull-right"); +		toggleDetails.dataset.toggle = "collapse"; +		toggleDetails.dataset.target = "#edit-output-cont"; +		toggleDetails.title = "Show request preview"; +		toggleDetails.id = "edit-toggle-details-" + this.sw; +		nav.appendChild(toggleDetails); + +		domObj.appendChild(nav); + +		this._render(domObj); +		if (place) { +			var pval = document.getElementById("edit-" + this.sw + "-placement"); +			if (pval) { +				pval.value = place; +			} +		} +		if (tags) { +			var ptags = document.getElementById("edit-" + this.sw + "-tags"); +			if (ptags) { +				ptags.value = tags; +			} +		} + +	}; +	this.save = function () { +		var myData = nmsInfoBox._editStringify(this.sw); +		$.ajax({ +			type: "POST", +			url: "/api/write/network-update", +			dataType: "text", +			data:myData, +			success: function (data, textStatus, jqXHR) { +				var result = JSON.parse(data); +				if(result.switches_updated.length > 0) { // FIXME unresolved variable switches_addded +					nmsInfoBox.hide(); +				} +				nmsData.invalidate("switches"); +				nmsData.invalidate("smanagement"); +			} +		}); +	}; +}; +nmsInfoBox.addPanelType("networkEdit",networkEditPanel); + +  /*   * General-purpose table-maker?   * diff --git a/web/js/nms.js b/web/js/nms.js index 5421f2f..0caac24 100644 --- a/web/js/nms.js +++ b/web/js/nms.js @@ -27,7 +27,7 @@ var nms = {  	timers: {  		tvmode: false  	}, -	 +  	menuShowing:true,  	get uptime() {  		return (Date.now() - this._startTime)/1000; @@ -105,13 +105,13 @@ function nmsTimer(handler, interval, name, description) {  	this.interval = parseInt(interval);  	this.name = name;  	this.description = description; -	this.start = function() {  +	this.start = function() {  		if (this.handle) {  			this.stop();  		}  		this.handle = setInterval(this.handler,this.interval);  		}; -	this.stop = function() {  +	this.stop = function() {  		if (this.handle)  			clearInterval(this.handle);  			this.handle = false; @@ -371,7 +371,7 @@ function getInitialConfig() {  function initNMS() {  	// Only used for dev-purposes now. Accessible through nms.uptime.  	nms._startTime = Date.now(); -	 +  	// Public  	nmsData.registerSource("config","/api/public/config");  	nmsData.registerSource("ping", "/api/public/ping"); @@ -392,10 +392,11 @@ function initNMS() {  	nmsData.registerSource("ticker","bananabananbanana");  	if (!nms._public) { -		// Private	 +		// Private  		nmsData.registerSource("snmp","/api/read/snmp");  		nmsData.registerSource("smanagement","/api/read/switches-management");  		nmsData.registerSource("oplog", "/api/read/oplog"); +		nmsData.registerSource("networks","/api/read/networks");  	//	setInterval(nmsUpdateNavbarGraph, 30000);  	//	nmsUpdateNavbarGraph();  		nmsOplog.init(); @@ -415,7 +416,7 @@ function detectHandler() {  	if (views == undefined || views == "")  		views = "ping";  	views = views.split(","); -	 +  	if (views.length > 1) {  		nms.tvmode.start(views,interval);  		return; @@ -597,7 +598,7 @@ function restoreSettings()  {  	try {  		var retrieve = JSON.parse(atob(getCookie("nms"))); -	} catch(e) {  +	} catch(e) {  	}  	try {  		var retrieve2 = getUrlVars()['nms']; @@ -626,7 +627,7 @@ function restoreSettings()  function nmsUpdateNavbarGraph() {  	var img = document.getElementById("navbar-graph");  	var w = 200; -	 +  	img.src = "/render/?target=movingAverage(averageSeries(ping.*.*.ipv4),%225min%22)&target=secondYAxis(averageSeries(perSecond(snmp.*.*.ports.*.{ifHCInOctets,ifHCOutOctets})))&bgcolor=%23ffffff00&width=" + w + "&height=20&format=svg&from=-30min&until=now&graphOnly=true";  }  /*  | 
