diff options
29 files changed, 1222 insertions, 379 deletions
@@ -1,2 +1,4 @@ .*.swp data/ +web/templates/ +web/files/ diff --git a/ansible/roles/postgres/files/schema-backup.sql b/ansible/roles/postgres/files/schema-backup.sql new file mode 100644 index 0000000..ed94e80 --- /dev/null +++ b/ansible/roles/postgres/files/schema-backup.sql @@ -0,0 +1,610 @@ +-- +-- PostgreSQL database dump +-- + +SET statement_timeout = 0; +SET lock_timeout = 0; +SET client_encoding = 'UTF8'; +SET standard_conforming_strings = on; +SET check_function_bodies = false; +SET client_min_messages = warning; + +-- +-- Name: plpgsql; Type: EXTENSION; Schema: -; Owner: +-- + +CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog; + + +-- +-- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner: +-- + +COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language'; + + +SET search_path = public, pg_catalog; + +-- +-- Name: comment_state; Type: TYPE; Schema: public; Owner: nms +-- + +CREATE TYPE comment_state AS ENUM ( + 'active', + 'inactive', + 'persist', + 'delete' +); + + +ALTER TYPE comment_state OWNER TO nms; + +SET default_tablespace = ''; + +SET default_with_oids = false; + +-- +-- Name: config; Type: TABLE; Schema: public; Owner: nms; Tablespace: +-- + +CREATE TABLE config ( + id integer NOT NULL, + publicvhost character varying, + shortname character varying, + data jsonb +); + + +ALTER TABLE config OWNER TO nms; + +-- +-- Name: config_id_seq; Type: SEQUENCE; Schema: public; Owner: nms +-- + +CREATE SEQUENCE config_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER TABLE config_id_seq OWNER TO nms; + +-- +-- Name: config_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: nms +-- + +ALTER SEQUENCE config_id_seq OWNED BY config.id; + + +-- +-- Name: dhcp; Type: TABLE; Schema: public; Owner: nms; Tablespace: +-- + +CREATE TABLE dhcp ( + switch integer, + "time" timestamp with time zone, + mac macaddr, + ip inet, + dhcp_server integer +); + + +ALTER TABLE dhcp OWNER TO nms; + +-- +-- Name: linknet_ping; Type: TABLE; Schema: public; Owner: nms; Tablespace: +-- + +CREATE TABLE linknet_ping ( + linknet integer NOT NULL, + "time" timestamp with time zone DEFAULT now() NOT NULL, + latency1_ms double precision, + latency2_ms double precision +); + + +ALTER TABLE linknet_ping OWNER TO nms; + +-- +-- Name: linknets; Type: TABLE; Schema: public; Owner: nms; Tablespace: +-- + +CREATE TABLE linknets ( + linknet integer NOT NULL, + switch1 integer NOT NULL, + addr1 inet, + switch2 integer NOT NULL, + addr2 inet, + port1 character varying(10), + port2 character varying(10) +); + + +ALTER TABLE linknets OWNER TO nms; + +-- +-- Name: linknets_linknet_seq; Type: SEQUENCE; Schema: public; Owner: nms +-- + +CREATE SEQUENCE linknets_linknet_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER TABLE linknets_linknet_seq OWNER TO nms; + +-- +-- Name: linknets_linknet_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: nms +-- + +ALTER SEQUENCE linknets_linknet_seq OWNED BY linknets.linknet; + + +-- +-- Name: oplog; Type: TABLE; Schema: public; Owner: nms; Tablespace: +-- + +CREATE TABLE oplog ( + id integer NOT NULL, + "time" timestamp with time zone DEFAULT now(), + systems character varying, + username character varying, + log text +); + + +ALTER TABLE oplog OWNER TO nms; + +-- +-- Name: oplog_id_seq; Type: SEQUENCE; Schema: public; Owner: nms +-- + +CREATE SEQUENCE oplog_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER TABLE oplog_id_seq OWNER TO nms; + +-- +-- Name: oplog_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: nms +-- + +ALTER SEQUENCE oplog_id_seq OWNED BY oplog.id; + + +-- +-- Name: ping; Type: TABLE; Schema: public; Owner: nms; Tablespace: +-- + +CREATE TABLE ping ( + switch integer NOT NULL, + "time" timestamp with time zone DEFAULT now() NOT NULL, + latency_ms double precision +); + + +ALTER TABLE ping OWNER TO nms; + +-- +-- Name: ping_secondary_ip; Type: TABLE; Schema: public; Owner: nms; Tablespace: +-- + +CREATE TABLE ping_secondary_ip ( + switch integer NOT NULL, + "time" timestamp with time zone DEFAULT now() NOT NULL, + latency_ms double precision +); + + +ALTER TABLE ping_secondary_ip OWNER TO nms; + +-- +-- Name: seen_mac; Type: TABLE; Schema: public; Owner: nms; Tablespace: +-- + +CREATE TABLE seen_mac ( + mac macaddr NOT NULL, + address inet NOT NULL, + seen timestamp with time zone DEFAULT now() NOT NULL +); + + +ALTER TABLE seen_mac OWNER TO nms; + +-- +-- Name: snmp; Type: TABLE; Schema: public; Owner: nms; Tablespace: +-- + +CREATE TABLE snmp ( + "time" timestamp without time zone DEFAULT now() NOT NULL, + switch integer NOT NULL, + data jsonb, + id integer NOT NULL +); + + +ALTER TABLE snmp OWNER TO nms; + +-- +-- Name: snmp_id_seq; Type: SEQUENCE; Schema: public; Owner: nms +-- + +CREATE SEQUENCE snmp_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER TABLE snmp_id_seq OWNER TO nms; + +-- +-- Name: snmp_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: nms +-- + +ALTER SEQUENCE snmp_id_seq OWNED BY snmp.id; + + +-- +-- 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, + placement box, + distro_name character varying, + distro_phy_port character varying(100), + traffic_vlan character varying, + tags jsonb DEFAULT '[]'::jsonb +); + + +ALTER TABLE switches OWNER TO nms; + +-- +-- Name: switches_switch_seq; Type: SEQUENCE; Schema: public; Owner: nms +-- + +CREATE SEQUENCE switches_switch_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +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 +-- + +ALTER TABLE ONLY config ALTER COLUMN id SET DEFAULT nextval('config_id_seq'::regclass); + + +-- +-- Name: linknet; Type: DEFAULT; Schema: public; Owner: nms +-- + +ALTER TABLE ONLY linknets ALTER COLUMN linknet SET DEFAULT nextval('linknets_linknet_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: public; Owner: nms +-- + +ALTER TABLE ONLY oplog ALTER COLUMN id SET DEFAULT nextval('oplog_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: public; Owner: nms +-- + +ALTER TABLE ONLY snmp ALTER COLUMN id SET DEFAULT nextval('snmp_id_seq'::regclass); + + +-- +-- Name: seen_mac_pkey; Type: CONSTRAINT; Schema: public; Owner: nms; Tablespace: +-- + +ALTER TABLE ONLY seen_mac + ADD CONSTRAINT seen_mac_pkey PRIMARY KEY (mac, address, seen); + + +-- +-- Name: switches_pkey; Type: CONSTRAINT; Schema: public; Owner: nms; Tablespace: +-- + +ALTER TABLE ONLY switches + ADD CONSTRAINT switches_pkey PRIMARY KEY (switch); + + +-- +-- Name: switches_sysname_key; Type: CONSTRAINT; Schema: public; Owner: nms; Tablespace: +-- + +ALTER TABLE ONLY switches + ADD CONSTRAINT switches_sysname_key UNIQUE (sysname); + + +-- +-- Name: switches_sysname_key1; Type: CONSTRAINT; Schema: public; Owner: nms; Tablespace: +-- + +ALTER TABLE ONLY switches + ADD CONSTRAINT switches_sysname_key1 UNIQUE (sysname); + + +-- +-- 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: +-- + +CREATE INDEX dhcp_mac ON dhcp USING btree (mac); + + +-- +-- 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: +-- + +CREATE INDEX dhcp_time ON dhcp USING btree ("time"); + + +-- +-- 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: +-- + +CREATE INDEX ping_secondary_index ON ping_secondary_ip USING btree ("time"); + + +-- +-- 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: +-- + +CREATE INDEX seen_mac_seen ON seen_mac USING btree (seen); + + +-- +-- 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: +-- + +CREATE INDEX snmp_time15 ON snmp USING btree (id, switch); + + +-- +-- 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: +-- + +CREATE INDEX switches_switch ON switches USING hash (switch); + + +-- +-- 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: +-- + +CREATE INDEX updated_index3 ON ping_secondary_ip USING btree ("time"); + + +-- +-- Name: dhcp_switch_fkey; Type: FK CONSTRAINT; Schema: public; Owner: nms +-- + +ALTER TABLE ONLY dhcp + ADD CONSTRAINT dhcp_switch_fkey FOREIGN KEY (switch) REFERENCES switches(switch); + + +-- +-- Name: snmp_switch_fkey; Type: FK CONSTRAINT; Schema: public; Owner: nms +-- + +ALTER TABLE ONLY snmp + ADD CONSTRAINT snmp_switch_fkey FOREIGN KEY (switch) REFERENCES switches(switch); + + +-- +-- Name: switchname; Type: FK CONSTRAINT; Schema: public; Owner: nms +-- + +ALTER TABLE ONLY ping + ADD CONSTRAINT switchname FOREIGN KEY (switch) REFERENCES switches(switch); + + +-- +-- Name: public; Type: ACL; Schema: -; Owner: postgres +-- + +REVOKE ALL ON SCHEMA public FROM PUBLIC; +REVOKE ALL ON SCHEMA public FROM postgres; +GRANT ALL ON SCHEMA public TO postgres; +GRANT ALL ON SCHEMA public TO PUBLIC; + + +-- +-- Name: config; Type: ACL; Schema: public; Owner: nms +-- + +REVOKE ALL ON TABLE config FROM PUBLIC; +REVOKE ALL ON TABLE config FROM nms; +GRANT ALL ON TABLE config TO nms; + + +-- +-- Name: dhcp; Type: ACL; Schema: public; Owner: nms +-- + +REVOKE ALL ON TABLE dhcp FROM PUBLIC; +REVOKE ALL ON TABLE dhcp FROM nms; +GRANT ALL ON TABLE dhcp TO nms; + + +-- +-- Name: linknet_ping; Type: ACL; Schema: public; Owner: nms +-- + +REVOKE ALL ON TABLE linknet_ping FROM PUBLIC; +REVOKE ALL ON TABLE linknet_ping FROM nms; +GRANT ALL ON TABLE linknet_ping TO nms; + + +-- +-- Name: linknets; Type: ACL; Schema: public; Owner: nms +-- + +REVOKE ALL ON TABLE linknets FROM PUBLIC; +REVOKE ALL ON TABLE linknets FROM nms; +GRANT ALL ON TABLE linknets TO nms; + + +-- +-- Name: ping; Type: ACL; Schema: public; Owner: nms +-- + +REVOKE ALL ON TABLE ping FROM PUBLIC; +REVOKE ALL ON TABLE ping FROM nms; +GRANT ALL ON TABLE ping TO nms; + + +-- +-- Name: ping_secondary_ip; Type: ACL; Schema: public; Owner: nms +-- + +REVOKE ALL ON TABLE ping_secondary_ip FROM PUBLIC; +REVOKE ALL ON TABLE ping_secondary_ip FROM nms; +GRANT ALL ON TABLE ping_secondary_ip TO nms; + + +-- +-- Name: seen_mac; Type: ACL; Schema: public; Owner: nms +-- + +REVOKE ALL ON TABLE seen_mac FROM PUBLIC; +REVOKE ALL ON TABLE seen_mac FROM nms; +GRANT ALL ON TABLE seen_mac TO nms; + + +-- +-- Name: snmp; Type: ACL; Schema: public; Owner: nms +-- + +REVOKE ALL ON TABLE snmp FROM PUBLIC; +REVOKE ALL ON TABLE snmp FROM nms; +GRANT ALL ON TABLE snmp TO nms; +GRANT ALL ON TABLE snmp TO postgres; + + +-- +-- Name: snmp_id_seq; Type: ACL; Schema: public; Owner: nms +-- + +REVOKE ALL ON SEQUENCE snmp_id_seq FROM PUBLIC; +REVOKE ALL ON SEQUENCE snmp_id_seq FROM nms; +GRANT ALL ON SEQUENCE snmp_id_seq TO nms; +GRANT ALL ON SEQUENCE snmp_id_seq TO postgres; + + +-- +-- Name: switches; Type: ACL; Schema: public; Owner: nms +-- + +REVOKE ALL ON TABLE switches FROM PUBLIC; +REVOKE ALL ON TABLE switches FROM nms; +GRANT ALL ON TABLE switches TO nms; + + +-- +-- PostgreSQL database dump complete diff --git a/ansible/roles/postgres/files/schema.sql b/ansible/roles/postgres/files/schema.sql index ed94e80..0be7d17 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,11 +79,11 @@ 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 ( - switch integer, + network integer, "time" timestamp with time zone, mac macaddr, ip inet, @@ -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,42 @@ ALTER SEQUENCE linknets_linknet_seq OWNED BY linknets.linknet; -- --- Name: oplog; Type: TABLE; Schema: public; Owner: nms; Tablespace: +-- 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; + +-- +-- Name: networks_network_seq; Type: SEQUENCE; Schema: public; Owner: 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: oplog; Type: TABLE; Schema: public; Owner: nms; Tablespace: -- CREATE TABLE oplog ( @@ -182,7 +217,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 +230,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 +243,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 +256,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,24 +291,26 @@ 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, distro_name character varying, distro_phy_port character varying(100), + tags jsonb DEFAULT '[]'::jsonb, + deleted boolean DEFAULT false, + mgmt_vlan character varying, traffic_vlan character varying, - tags jsonb DEFAULT '[]'::jsonb + network integer ); @@ -294,35 +331,6 @@ 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 -- @@ -351,7 +359,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 @@ -359,7 +367,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 @@ -367,7 +375,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 @@ -375,7 +383,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 @@ -383,112 +391,104 @@ 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_network; Type: INDEX; Schema: public; Owner: nms; Tablespace: -- -CREATE INDEX dhcp_switch ON dhcp USING btree (switch); +CREATE INDEX dhcp_network ON dhcp USING btree (network); -- --- 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"); -- --- Name: dhcp_switch_fkey; Type: FK CONSTRAINT; Schema: public; Owner: nms --- - -ALTER TABLE ONLY dhcp - ADD CONSTRAINT dhcp_switch_fkey FOREIGN KEY (switch) REFERENCES switches(switch); - - --- -- Name: snmp_switch_fkey; Type: FK CONSTRAINT; Schema: public; Owner: nms -- @@ -551,6 +551,24 @@ GRANT ALL ON TABLE linknets TO nms; -- +-- Name: networks; Type: ACL; Schema: public; Owner: nms +-- + +REVOKE ALL ON TABLE networks FROM PUBLIC; +REVOKE ALL ON TABLE networks FROM nms; +GRANT ALL ON TABLE networks TO nms; + + +-- +-- Name: oplog; Type: ACL; Schema: public; Owner: nms +-- + +REVOKE ALL ON TABLE oplog FROM PUBLIC; +REVOKE ALL ON TABLE oplog FROM nms; +GRANT ALL ON TABLE oplog TO nms; + + +-- -- Name: ping; Type: ACL; Schema: public; Owner: nms -- diff --git a/collectors/dhcptail.pl b/collectors/dhcptail.pl index 5fd8cf0..5f117b9 100755 --- a/collectors/dhcptail.pl +++ b/collectors/dhcptail.pl @@ -27,7 +27,7 @@ my %months = ( my $realtime = 0; my ($dbh, $q,$check); $dbh = nms::db_connect(); -$q = $dbh->prepare("INSERT INTO dhcp (dhcp_server,switch,time,ip,mac) VALUES($nms::config::dhcp_id,(SELECT switch FROM switches WHERE ?::inet << subnet4 and deleted = false ORDER BY sysname LIMIT 1),?,?,?)"); +$q = $dbh->prepare("INSERT INTO dhcp (dhcp_server,network,time,ip,mac) VALUES($nms::config::dhcp_id,(SELECT network FROM networks WHERE ?::inet << subnet4 ORDER BY name LIMIT 1),?,?,?)"); $check = $dbh->prepare("SELECT max(time)::timestamp - ?::timestamp < '0s'::interval as doit FROM dhcp where dhcp_server = $nms::config::dhcp_id;"); open(SYSLOG, "tail -n 9999999 -F /var/log/messages |") or die "Unable to tail syslog: $!"; diff --git a/collectors/ping.pl b/collectors/ping.pl index 82c5c42..e8fcbdd 100755 --- a/collectors/ping.pl +++ b/collectors/ping.pl @@ -29,6 +29,9 @@ while (1) { if ($elapsed < $target) { sleep($target - ($now - $last)); } + + my @influx_tree = (); + $last = time(); # ping loopbacks my $ping = Net::Oping->new; @@ -82,27 +85,18 @@ while (1) { $latency //= "\\N"; $dbh->pg_putcopydata("$switch\t$latency\n"); if($latency ne "\\N") { - my $cv = AE::cv; - $influx->write( - database => $nms::config::influx_database, - data => [ - { - measurement => 'ping', - tags => { - switch => $sysname, - ip => $ip, - version => 'v4' - }, - fields => { - latency => $latency, - }, - }], - on_success => $cv, - on_error => sub { - $cv->croak("Failed to write data: @_"); - } - ); - $cv->recv; + push (@influx_tree, + { + measurement => 'ping', + tags => { + switch => $sysname, + ip => $ip, + version => 'v4' + }, + fields => { + latency => $latency, + }, + }); } } @@ -120,29 +114,20 @@ while (1) { $latency //= "\\N"; $dbh->pg_putcopydata("$switch\t$latency\n"); - if($latency ne "\\N") { - my $cv = AE::cv; - $influx->write( - database => $nms::config::influx_database, - data => [ - { - measurement => 'ping', - tags => { - switch => $sysname, - ip => $ip, - version => 'v6' - }, - fields => { - latency => $latency, - }, - }], - on_success => $cv, - on_error => sub { - $cv->croak("Failed to write data: @_"); - } - ); - $cv->recv; - } + if($latency ne "\\N") { + push (@influx_tree, + { + measurement => 'ping', + tags => { + switch => $sysname, + ip => $ip, + version => 'v6' + }, + fields => { + latency => $latency, + }, + }); + } } $dbh->pg_putcopyend(); @@ -172,4 +157,16 @@ while (1) { $dbh->pg_putcopyend(); } $dbh->commit; + + my $cv = AE::cv; + $influx->write( + database => $nms::config::influx_database, + data => [@influx_tree], + on_success => $cv, + on_error => sub { + $cv->croak("Failed to write data: @_"); + } + ); + $cv->recv; + } diff --git a/collectors/snmpfetchng.pl b/collectors/snmpfetchng.pl index 9c06f4a..02b75b8 100755 --- a/collectors/snmpfetchng.pl +++ b/collectors/snmpfetchng.pl @@ -4,9 +4,10 @@ use warnings; use DBI; use POSIX; #use Time::HiRes qw(time); +use lib '/opt/gondul/include'; +use FixedSNMP; use SNMP; use Data::Dumper; -use lib '/opt/gondul/include'; use nms qw(convert_mac convert_decimal); use IO::Socket::IP; use Scalar::Util qw(looks_like_number); @@ -32,7 +33,7 @@ EOF # Borrowed from snmpfetch.pl our $qswitch = $dbh->prepare(<<"EOF") SELECT - sysname,switch,host(mgmt_v4_addr) as ip,host(mgmt_v6_addr) as ip2,community, + sysname,switch,host(mgmt_v6_addr) as ip2,host(mgmt_v4_addr) as ip,community, DATE_TRUNC('second', now() - last_updated - poll_frequency) AS overdue FROM switches @@ -103,7 +104,7 @@ sub inner_loop } } mylog( "Polling " . @switches . " switches: $poll_todo"); - SNMP::MainLoop(6); + SNMP::MainLoop(5); } sub callback{ @@ -115,6 +116,7 @@ sub callback{ my @nicids; my $total = 0; my %tree2; + my @influx_tree = (); for my $ret (@top) { for my $var (@{$ret}) { @@ -162,65 +164,45 @@ sub callback{ for my $nic (@nicids) { $tree2{'ports'}{$tree{$nic}{'ifName'}} = $tree{$nic}; my $tmp_field = ''; - for my $tmp_key (keys $tree{$nic}) { + for my $tmp_key (keys %{$tree{$nic}}) { if(looks_like_number($tree{$nic}{$tmp_key})) { $tmp_field = $tree{$nic}{$tmp_key}; } else { $tmp_field = '"'.$tree{$nic}{$tmp_key}.'"'; } - - my $cv = AE::cv; - $influx->write( - database => $nms::config::influx_database, - data => [ + push (@influx_tree, { measurement => 'ports', tags => { switch => $switch{'sysname'}, - interface => $tree{$nic}{'ifName'}, + interface => $tree{$nic}{'ifName'}, }, fields => { $tmp_key => $tmp_field }, - }], - on_success => $cv, - on_error => sub { - $cv->croak("Failed to write data: @_"); - } - ); - $cv->recv; + }); } delete $tree{$nic}; } + for my $iid (keys %tree) { my $tmp_field = ''; for my $key (keys %{$tree{$iid}}) { $tree2{'misc'}{$key}{$iid} = $tree{$iid}{$key}; - if(looks_like_number($tree{$iid}{$key})) { + if(looks_like_number($tree{$iid}{$key})) { $tmp_field = $tree{$iid}{$key}; } else { $tmp_field = '"'.$tree{$iid}{$key}.'"'; } - my $cv = AE::cv; - $influx->write( - database => $nms::config::influx_database, - data => [ + push (@influx_tree, { measurement => 'snmp', tags => { switch => $switch{'sysname'}, }, fields => { $key => $tmp_field }, - }], - on_success => $cv, - on_error => sub { - $cv->croak("Failed to write data: @_"); - } - ); - $cv->recv; - - + }); } } if ($total > 0) { @@ -230,21 +212,22 @@ sub callback{ or die "Couldn't unlock switch"; $dbh->commit; if ($total > 0) { - my $cv = AE::cv; - $influx->write( - database => $nms::config::influx_database, - data => [ - { - measurement => 'snmp', - tags => { - switch => $switch{'sysname'}, - }, - fields => { 'execution_time' => (time - $switch{'start'}) }, - }], - on_success => $cv, - on_error => sub { - $cv->croak("Failed to write data: @_"); - } + push (@influx_tree, + { + measurement => 'snmp', + tags => { + switch => $switch{'sysname'}, + }, + fields => { 'execution_time' => (time - $switch{'start'}) }, + }); + my $cv = AE::cv; + $influx->write( + database => $nms::config::influx_database, + data => [@influx_tree], + on_success => $cv, + on_error => sub { + $cv->croak("Failed to write data: @_"); + } ); $cv->recv; diff --git a/include/config.pm b/include/config.pm.dist index dcc784d..78f03cc 100755 --- a/include/config.pm +++ b/include/config.pm.dist @@ -14,7 +14,7 @@ our $graphite_port = "2003"; # Influx our $influx_host = "http://localhost:8086"; our $influx_username = "gondulWrite"; -our $influx_password = "funfunfunWrite"; +our $influx_password = "pasr"; our $influx_database = "gondul"; # Max SNMP polls to fire off at the same time. diff --git a/include/nms/snmp.pm b/include/nms/snmp.pm index 45ab6c6..6165a5a 100644 --- a/include/nms/snmp.pm +++ b/include/nms/snmp.pm @@ -1,6 +1,7 @@ #! /usr/bin/perl use strict; use warnings; +use FixedSNMP; use SNMP; use nms; package nms::snmp; diff --git a/include/nms/util.pm b/include/nms/util.pm index 511da33..69f5392 100644 --- a/include/nms/util.pm +++ b/include/nms/util.pm @@ -91,10 +91,11 @@ sub guess_placement_dx { $y = 880; $xx = $x + 230; $yy = $y + 40; - } elsif ($name =~ /^distro(\d)$/) { + } elsif ($name =~ /^s(\d).floor$/) { my $d = ($1); + $d -= 1; $src = "distro"; - $x = 1550 - $d * 700; + $x = 1550 - $d * 600; $y = 410; $xx = $x + 230; $yy = $y + 40; @@ -180,11 +181,12 @@ sub guess_placement_tg { $y = int(759 + 20.5 * $s); $xx = $x + 65; $yy = $y + 14; - } elsif ($name =~ /^distro(\d)/) { + } elsif ($name =~ /^s(\d).floor/) { my $d = ($1); $src = "distro"; - $x = 292 + $d * 165; - $y = 415; + $d -= 1; + $x = 260 + $d * 145; + $y = 417; $xx = $x + 130; $yy = $y + 20; } else { diff --git a/include/nms/web.pm b/include/nms/web.pm index 6592bfb..588498f 100755 --- a/include/nms/web.pm +++ b/include/nms/web.pm @@ -85,7 +85,8 @@ sub finalize_output { $json{'time'} = int($query->fetchrow_hashref()->{'time'}); $json{'hash'} = $hash; if (defined($get_params{'now'})) { - $cc{'max-age'} = "3600"; + $cc{'max-age'} = "60"; + $cc{'stale-while-revalidate'} = "3600"; } printcc; diff --git a/templating/templating.py b/templating/templating.py index 9794655..fff5d42 100755 --- a/templating/templating.py +++ b/templating/templating.py @@ -3,14 +3,15 @@ import requests,traceback from jinja2 import Template,Environment,FileSystemLoader,TemplateNotFound import json +import netaddr import http.server from enum import Enum -endpoints = "read/oplog read/snmp read/switches-management public/config public/dhcp public/dhcp-summary public/ping public/switches public/switch-state".split() +endpoints = "read/networks read/oplog read/snmp read/switches-management public/distro-tree public/config public/dhcp public/dhcp-summary public/ping public/switches public/switch-state".split() objects = dict() def getEndpoint(endpoint): - r = requests.get("http://localhost:8080/api/%s" % endpoint) + r = requests.get("http://localhost:80/api/%s" % endpoint) if (r.status_code != 200): raise Exception("Bad status code for endpoint %s: %s" % (endpoint, r.status_code)) return r.json() @@ -19,7 +20,33 @@ def updateData(): for a in endpoints: objects[a] = getEndpoint(a) -env = Environment(loader=FileSystemLoader(['templates/','/opt/gondul/data/templates', '/opt/gondul/web/templates']),lstrip_blocks=True, trim_blocks=True) +def netmask(ip): + return netaddr.IPNetwork(ip).netmask +def cidr(ip): + return netaddr.IPNetwork(ip).prefixlen +def networkId(ip): + return netaddr.IPNetwork(ip).ip +def getFirstDhcpIp(ip): + return netaddr.IPNetwork(ip)[3] +def getLastDhcpIp(ip): + return netaddr.IPNetwork(ip)[-1] +def getDistro(src): + return src.split(":")[0] +def getPort(src): + return src.split(":")[1] +def getFirstFapIp(ip): + return netaddr.IPNetwork(ip)[netaddr.IPNetwork(ip).size/2] + +env = Environment(loader=FileSystemLoader(['templates/','/opt/gondul/data/templates', '/opt/gondul/web/templates']), trim_blocks=True) + +env.filters["netmask"] = netmask +env.filters["cidr"] = cidr +env.filters["networkId"] = networkId +env.filters["getFirstDhcpIp"] = getFirstDhcpIp +env.filters["getLastDhcpIp"] = getLastDhcpIp +env.filters["agentDistro"] = getDistro +env.filters["agentPort"] = getPort +env.filters["getFirstFapIP"] = getFirstFapIp class Mode(Enum): Get = 1 diff --git a/web/api/public/dhcp b/web/api/public/dhcp index 0b0bb49..f153a49 100755 --- a/web/api/public/dhcp +++ b/web/api/public/dhcp @@ -8,16 +8,16 @@ use warnings; use Data::Dumper; nms::web::setwhen('60m'); -my $q = $nms::web::dbh->prepare('select distinct on (sysname) extract(epoch from date_trunc(\'second\',time)) as time,sysname from dhcp join switches on dhcp.switch = switches.switch where ' . $nms::web::when . ' and switches.deleted = false order by sysname,time desc;'); +my $q = $nms::web::dbh->prepare('select distinct on (name) extract(epoch from date_trunc(\'second\',time)) as time,name from dhcp join networks on dhcp.network = networks.network where ' . $nms::web::when . ' order by name,time desc;'); $q->execute(); while ( my $ref = $q->fetchrow_hashref() ) { - my $sysname = $ref->{'sysname'}; - $json{'dhcp'}{$ref->{'sysname'}} = $ref->{'time'}; + my $sysname = $ref->{'sname'}; + $json{'dhcp'}{$ref->{'name'}} = $ref->{'time'}; } -my $q2 = $nms::web::dbh->prepare("select sysname,count(distinct mac) as clients,count(distinct ip) as addresses,count(mac) as acks from dhcp natural join switches where $nms::web::when and switches.deleted = false group by switches.sysname;"); +my $q2 = $nms::web::dbh->prepare("select name,count(distinct mac) as clients,count(distinct ip) as addresses,count(mac) as acks from dhcp natural join networks where $nms::web::when group by networks.name;"); $q2->execute(); while (my $ref = $q2->fetchrow_hashref()) { - $nms::web::json{'switches'}{$ref->{sysname}} = $ref; + $nms::web::json{'networks'}{$ref->{name}} = $ref; } $nms::web::cc{'max-age'} = "10"; diff --git a/web/api/public/ping b/web/api/public/ping index 1928368..be37875 100755 --- a/web/api/public/ping +++ b/web/api/public/ping @@ -4,7 +4,7 @@ use strict; use warnings; use nms::web; -nms::web::setwhen('15s'); +nms::web::setwhen('25s'); my $q = $nms::web::dbh->prepare("SELECT DISTINCT ON (sysname) (" . $nms::web::now . " - time) as age,sysname, latency_ms FROM ping NATURAL JOIN switches WHERE time in (select max(time) from ping where " . $nms::web::when . " group by switch)"); @@ -37,5 +37,5 @@ while ( my $ref = $lq->fetchrow_hashref() ) { } $nms::web::cc{'max-age'} = "1"; -$nms::web::cc{'stale-while-revalidate'} = "15"; +$nms::web::cc{'stale-while-revalidate'} = "5"; finalize_output(); diff --git a/web/api/public/switch-state b/web/api/public/switch-state index 965e881..528bf7d 100755 --- a/web/api/public/switch-state +++ b/web/api/public/switch-state @@ -7,17 +7,19 @@ use strict; use warnings; use Data::Dumper; -my $target = $ENV{REQUEST_URI}; -$target =~ s/$ENV{SCRIPT_NAME}//; -$target =~ s/^\///; -my ($switch, $port) = split(/\//,$target,2); +#my $target = $ENV{REQUEST_URI}; +#$target =~ s/$ENV{SCRIPT_NAME}//; +#$target =~ s/^\///; +#my ($switch, $port) = split(/\//,$target,2); +my $port; +my $switch; my $q; -if (!defined($switch)) { - $q = $nms::web::dbh->prepare('select sysname,extract(epoch from date_trunc(\'second\',time)) as time,data from snmp natural join switches where id in (select max(id) from snmp where ' . $nms::web::when . ' and switches.deleted = false group by switch);'); -} else { - $q = $nms::web::dbh->prepare('select sysname,extract(epoch from date_trunc(\'second\',time)) as time,data from snmp natural join switches where id in (select max(id) from snmp where ' . $nms::web::when . 'group by switch) and sysname = ' . $nms::web::dbh->quote($switch) . ' and switches.deleted = false;'); -} +#if (!defined($switch)) { + $q = $nms::web::dbh->prepare('select sysname,extract(epoch from date_trunc(\'second\',time)) as time,data from snmp natural join switches where id in (select max(id) from snmp where ' . $nms::web::when . ' group by switch) and switches.deleted = \'f\' and not switches.tags \?& array[\'ignoreswitchstate\'];'); +#} else { +# $q = $nms::web::dbh->prepare('select sysname,extract(epoch from date_trunc(\'second\',time)) as time,data from snmp natural join switches where id in (select max(id) from snmp where ' . $nms::web::when . 'group by switch) and sysname = ' . $nms::web::dbh->quote($switch) . ';'); +#} $q->execute(); while ( my $ref = $q->fetchrow_hashref() ) { @@ -42,7 +44,7 @@ while ( my $ref = $q->fetchrow_hashref() ) { $json{'switches'}{$sysname}{ifs}{$smallport}{'ifAlias'} = $port{'ifAlias'}; } if ($data{'ports'}{$porti}{'ifType'} ne "propVirtual" and - $data{'ports'}{$porti}{'ifAlias'} =~ m/LAG member/i) { + $data{'ports'}{$porti}{'ifAlias'} =~ m/Fysisk/i) { if ($port{'ifAdminStatus'} eq "up") { $json{'switches'}{$sysname}{'uplinks'}{'ifHCInOctets'} += $port{'ifHCInOctets'}; $json{'switches'}{$sysname}{'uplinks'}{'ifHCOutOctets'} += $port{'ifHCOutOctets'}; @@ -83,9 +85,9 @@ while ( my $ref = $q->fetchrow_hashref() ) { nms::web::setwhen('15m','10m'); my $q2; if (!defined($switch)) { - $q2 = $nms::web::dbh->prepare('select sysname,extract(epoch from date_trunc(\'second\',time)) as time,data from snmp natural join switches where id in (select max(id) from snmp where ' . $nms::web::when . 'group by switch);'); + $q2 = $nms::web::dbh->prepare('select sysname,extract(epoch from date_trunc(\'second\',time)) as time,data from snmp natural join switches where id in (select max(id) from snmp where ' . $nms::web::when . ' group by switch) and switches.deleted = \'f\' and not switches.tags \?& array[\'ignoreswitchstate\'];'); } else { - $q2 = $nms::web::dbh->prepare('select sysname,extract(epoch from date_trunc(\'second\',time)) as time,data from snmp natural join switches where id in (select max(id) from snmp where ' . $nms::web::when . 'group by switch) and sysname = ' . $nms::web::dbh->quote($switch) . ';'); + $q2 = $nms::web::dbh->prepare('select sysname,extract(epoch from date_trunc(\'second\',time)) as time,data from snmp natural join switches where id in (select max(id) from snmp where ' . $nms::web::when . 'group by switch) and switches.deleted = \'f\' and not switches.tags \?& array[\'ignoreswitchstate\'] and sysname = ' . $nms::web::dbh->quote($switch) . ';'); } $q2->execute(); @@ -109,7 +111,7 @@ while ( my $ref = $q2->fetchrow_hashref() ) { $json{'then'}{$sysname}{ifs}{$smallport}{'ifAlias'} = $port{'ifAlias'}; } if ($data{'ports'}{$porti}{'ifType'} ne "propVirtual" and - $data{'ports'}{$porti}{'ifAlias'} =~ m/LAG member/i) { + $data{'ports'}{$porti}{'ifAlias'} =~ m/Fysisk/i) { if ($port{'ifAdminStatus'} eq "up") { $json{'then'}{$sysname}{'uplinks'}{'ifHCInOctets'} += $port{'ifHCInOctets'}; $json{'then'}{$sysname}{'uplinks'}{'ifHCOutOctets'} += $port{'ifHCOutOctets'}; diff --git a/web/api/read/distro-management b/web/api/read/distro-management index 7fbebef..55ca07e 100755 --- a/web/api/read/distro-management +++ b/web/api/read/distro-management @@ -19,7 +19,7 @@ my $q2; $nms::web::cc{'max-age'} = "5"; $nms::web::cc{'stale-while-revalidate'} = "30"; -$q2 = $nms::web::dbh->prepare('SELECT distro_name,sysname,subnet4,subnet6,traffic_vlan,distro_phy_port FROM switches WHERE placement is not null AND distro_name is not null AND distro_phy_port is not null and deleted = false'); +$q2 = $nms::web::dbh->prepare('SELECT distro_name,sysname,distro_phy_port FROM switches WHERE placement is not null AND distro_name is not null AND distro_phy_port 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 index 870ae8c..870ae8c 100644..100755 --- a/web/api/read/networks +++ b/web/api/read/networks diff --git a/web/api/read/switches-management b/web/api/read/switches-management index 77badf4..b42c84b 100755 --- a/web/api/read/switches-management +++ b/web/api/read/switches-management @@ -13,14 +13,20 @@ use Data::Dumper; my $target = $ENV{REQUEST_URI}; $target =~ s/$ENV{SCRIPT_NAME}//; $target =~ s/^\///; -my ($switch, $port) = split(/\//,$target,2); +my $switch; +my $port; + +if ($target !~ m/now=/) { + ($switch, $port) = split(/\//,$target,2); +} + my $q2; $nms::web::cc{'max-age'} = "5"; $nms::web::cc{'stale-while-revalidate'} = "30"; if (!defined($switch)) { - $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;'); + $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, host(mgmt_net.gw4) as mgmt_v4_gw, host(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,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;'); } diff --git a/web/api/read/template-list b/web/api/read/template-list new file mode 100755 index 0000000..d1c8773 --- /dev/null +++ b/web/api/read/template-list @@ -0,0 +1,21 @@ +#! /usr/bin/perl +# vim:ts=8:sw=8 + +use lib '/opt/gondul/include'; +use nms::web; +use strict; +use warnings; + +my $template_dir = "/opt/gondul/web/templates"; + +opendir (DIR, $template_dir) or die $!; + +while (my $file = readdir(DIR)) { + next if ($file =~ m/^\./); + my %meh; + $meh{'file'} = $file; + + push @{$nms::web::json{'templates'}},\%meh; +} + +nms::web::finalize_output(); diff --git a/web/api/write/network-add b/web/api/write/network-add index d1aab4e..d1aab4e 100644..100755 --- a/web/api/write/network-add +++ b/web/api/write/network-add diff --git a/web/api/write/network-update b/web/api/write/network-update index f6684c5..6344c37 100644..100755 --- a/web/api/write/network-update +++ b/web/api/write/network-update @@ -23,51 +23,23 @@ 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; -} +my @fields = ('name','last_updated','subnet4','subnet6','gw4','gw6','routing_point','vlan','tags'); foreach my $tmp2 (@tmp) { my %network = %{$tmp2}; my $affected = 0; my %template = (); map { $template{$_} = 'DEFAULT' } @fields; - if (not defined($network{'sysname'})) { + if (not defined($network{'name'})) { next; } - $sth->execute( $network{'sysname'}); + $sth->execute( $network{'name'}); 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{$_})) { @@ -76,24 +48,9 @@ foreach my $tmp2 (@tmp) { } 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'}; + $nms::web::dbh->do("INSERT INTO NETWORKS (name, last_updated, subnet4, subnet6, routing_point, gw4, gw6, vlan, tags) VALUES ($template{'name'}, $template{'last_updated'}, $template{'subnet4'}, $template{'subnet6'}, $template{'routing_point'}, $template{'gw4'}, $template{'gw6'}, $template{'vlan'}, $template{'tags'});"); + push @added, $network{'name'}; } 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; } @@ -103,8 +60,8 @@ foreach my $tmp2 (@tmp) { 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'}; + $nms::web::dbh->do("UPDATE networks SET " . join(", ", @set) . "WHERE name=" . $dbh->quote($network{'name'}) . ";"); + push @dups, $network{'name'}; } } $json{'networks_addded'} = \@added; diff --git a/web/api/write/switch-update b/web/api/write/switch-update index b71548b..bcf69e1 100755 --- a/web/api/write/switch-update +++ b/web/api/write/switch-update @@ -23,7 +23,7 @@ my @dups; my $sth = $nms::web::dbh->prepare("SELECT sysname FROM switches WHERE sysname=?"); -my @fields = ( 'community', 'tags', 'distro_name', 'distro_phy_port', 'mgmt_v4_addr', 'mgmt_v4_gw', 'mgmt_v4_netsize', 'mgmt_v6_addr', 'mgmt_v6_gw', 'mgmt_v6_netsize', 'mgmt_vlan', 'placement', 'poll_frequency', 'subnet4', 'subnet6', 'sysname', 'traffic_vlan', 'deleted'); +my @fields = ( 'community', 'tags', 'distro_name', 'distro_phy_port', 'mgmt_v4_addr', 'mgmt_v6_addr', 'mgmt_vlan', 'placement', 'poll_frequency', 'sysname', 'traffic_vlan', 'deleted'); sub convertplace { diff --git a/web/index.html b/web/index.html index d8f2a60..7b07f09 100644 --- a/web/index.html +++ b/web/index.html @@ -143,14 +143,15 @@ <div class="span3 col-lg-6"> <textarea id="template-input" class="form-control" cols="80" rows="25"></textarea> <div class="form-inline"> - <div class="form-group"> - <button onclick="nmsTemplate.fromFile('HOWTO.txt')" class="btn btn-info">Load HOWTO.txt</button> - <button onclick="nmsTemplate.fromFile('switches.txt')" class="btn btn-info">Load switches.txt</button> - <button onclick="nmsTemplate.fromFile('switch.txt')" class="btn btn-info">Load switch.txt</button> - </div> + https://gondul.tg.lol/api/templates/ + <div class="form-group"> + <select onchange="nmsTemplate.fromFile(this.value)" class="form-control" id="nmsTemplate-select"> + <option value="">Select template</option> + </select> + </div> <div class="form-group"> <label for="template-query-params">Query parameters</label> - <input type="text" class="form-control" id="template-query-params" value="?switch=e13-1&foo=bar" /> + <input type="text" class="form-control" id="template-query-params" value="?a=r1.ring:ge-1/0/2.0:mgmt+irb.666" /> </div> <div class="form-group"> <button onclick="nmsTemplate.test()" class="btn btn-primary">Test</button> @@ -158,7 +159,7 @@ </div> </div> <div class="span3 col-lg-6"> - <textarea id="template-output" class="form-control" disabled cols="80" rows="25"></textarea> + <textarea id="template-output" class="form-control" readonly cols="80" rows="25"></textarea> </div> </div> </div> diff --git a/web/js/nms-draw-chart.js b/web/js/nms-draw-chart.js index da621e7..60698c0 100644 --- a/web/js/nms-draw-chart.js +++ b/web/js/nms-draw-chart.js @@ -16,63 +16,65 @@ function drawLatency(canvas, sw, chart, callback) { var dataset = []; $.getJSON( "/query?db=gondul&q="+q, function( results ) { - results['results'][0]['series'].forEach(function(serie) { - var data = []; - serie['values'].forEach(function(element) { - data.push({t: new Date(element[0]), y: element[1]}); - }); - var borderColor = "rgba(0,155,200,255)"; - console.log(serie['tags']['version']); - if(serie['tags']['version'] === "v6") { - borderColor = "rgba(100,155,100,255)"; + try { + results['results'][0]['series'].forEach(function(serie) { + var data = []; + serie['values'].forEach(function(element) { + data.push({t: new Date(element[0]), y: element[1]}); + }); + var borderColor = "rgba(0,155,200,255)"; + if(serie['tags']['version'] === "v6") { + borderColor = "rgba(100,155,100,255)"; + } + dataset.push({data: data, fill:false, borderColor:borderColor, label:serie['tags']['version'] }); + }); + if(chart != false) { + chart.data.datasets = dataset; + chart.update(); + return; } - dataset.push({data: data, fill:false, borderColor:borderColor, label:serie['tags']['version'] }); - }); - if(chart != false) { - chart.data.datasets = dataset; - chart.update(); - return; - } - var ctx = document.getElementById(canvas).getContext('2d'); - var myChart = new Chart(ctx, { - type: 'line', - data: { - datasets: dataset - }, - options: { - legend: { - display: false + var ctx = document.getElementById(canvas).getContext('2d'); + var myChart = new Chart(ctx, { + type: 'line', + data: { + datasets: dataset }, - scales: { - xAxes:[{ - type: 'time', - time: { - format: "HH:mm", - unit: 'minute', - tooltipFormat: 'HH:mm', - displayFormats: { - 'minute': 'HH:mm', - 'hour': 'HH:mm', - min: '00:00', - max: '23:59' - }, - } - }], - yAxes: [{ - ticks: { - beginAtZero: true + options: { + legend: { + display: false + }, + scales: { + xAxes:[{ + type: 'time', + time: { + format: "HH:mm", + unit: 'minute', + tooltipFormat: 'HH:mm', + displayFormats: { + 'minute': 'HH:mm', + 'hour': 'HH:mm', + min: '00:00', + max: '23:59' + }, + } + }], + yAxes: [{ + ticks: { + beginAtZero: true + } + }] + }, + responsive: true, + animation: false, + elements: { + line: { + tension: 0.05 } - }] - }, - responsive: true, - animation: false, - elements: { - line: { - tension: 0.05 - } - } - } - }); + } + } + }); + } catch(e) { + } if(callback != undefined) { callback(myChart); } @@ -95,6 +97,7 @@ function drawSumOfPorts(canvas, sw) { var bits_in = []; var bits_out = []; + results['results'][0]['series'].forEach(function(serie) { // Bytes in diff --git a/web/js/nms-info-box.js b/web/js/nms-info-box.js index 1971b61..a7ddfc1 100644 --- a/web/js/nms-info-box.js +++ b/web/js/nms-info-box.js @@ -50,6 +50,10 @@ var nmsInfoBox = nmsInfoBox || { 'name': 'SNMP', 'panels': ['switchSNMP:misc'] }, + 'links': { + 'name': 'Links', + 'panels': ['switchLinks'] + }, 'edit': { 'name': 'Edit settings', 'panels': ['switchEdit'] @@ -125,7 +129,11 @@ var nmsInfoBox = nmsInfoBox || { 'jnxBoxSerialNo': { 'name': 'Serial numbers', 'panels': ['inventoryListing:jnxBoxSerialNo'] - } + }, + 'transceiver': { + 'name': 'Transceivers', + 'panels': ['inventoryListing:transceiver'] + } } }, { @@ -657,7 +665,13 @@ var switchPortsPanel = function () { indicies.push(obj); } indicies.sort(function(a,b) { - return snmpJson[a].ifIndex - snmpJson[b].ifIndex; + var tmpx = [ snmpJson[a].ifName, snmpJson[b].ifName ]; + tmpx.sort(); + if (tmpx[0] == snmpJson[a].ifName) { + return -1; + } else { + return 1; + } }); for(var obji in indicies) { var obj = indicies[obji]; @@ -686,7 +700,7 @@ var switchPortsPanel = function () { } } catch(e) {}; - groupObj.innerHTML = '<span class="panel-heading" style="display:block;"><a class="collapse-controller" role="button" data-toggle="collapse" href="#'+cleanObj+'-group">' + snmpJson[obj].ifDescr + ' </a><small>' + snmpJson[obj].ifAlias + '</small><span class="pull-right">' + traffic + '<i class="btn-xs ' + button + '"><span class="glyphicon ' + glyphicon + '" title="' + title + '" aria-hidden="true"></span></i></span></span>'; + groupObj.innerHTML = '<span class="panel-heading" style="display:block;"><a class="collapse-controller" role="button" data-toggle="collapse" href="#'+cleanObj+'-group">' + snmpJson[obj].ifName + ' </a><small>' + snmpJson[obj].ifAlias + '</small><span class="pull-right">' + traffic + '<i class="btn-xs ' + button + '"><span class="glyphicon ' + glyphicon + '" title="' + title + '" aria-hidden="true"></span></i></span></span>'; var groupObjCollapse = document.createElement("div"); groupObjCollapse.id = cleanObj + "-group"; @@ -885,6 +899,9 @@ var inventoryListingPanel = function() { case 'jnxBoxSerialNo': listTitle = 'Serial Numbers'; break; + case 'transceiver': + listTitle = 'Transceivers'; + break; default: listTitle = 'Distro names'; } @@ -900,15 +917,18 @@ var inventoryListingPanel = function() { switch (this.mode) { case 'distro_name': value = nmsData.switches.switches[sw]["distro_name"]; + resultArray.push([sw, value]); break; case 'sysDescr': value = nmsData.snmp.snmp[sw]["misc"]["sysDescr"][0]; + resultArray.push([sw, value]); break; case 'jnxBoxSerialNo': if(testTree(nmsData,["snmp","snmp",sw,"misc","entPhysicalSerialNum"])) { for (var x in nmsData.snmp.snmp[sw]["misc"]["entPhysicalSerialNum"]) { value = "misc" + x + ":" + nmsData.snmp.snmp[sw]["misc"]["entPhysicalSerialNum"][x]; - resultArray.push([sw, value]); + var entPhysicalDescr = nmsData.snmp.snmp[sw]["misc"]["entPhysicalDescr"][x]; + resultArray.push([sw, entPhysicalDescr+': '+value]); } } if (testTree(nmsData,["snmp","snmp",sw,"misc","jnxVirtualChassisMemberSerialnumber"])) { @@ -918,11 +938,23 @@ var inventoryListingPanel = function() { } } value = nmsData.snmp.snmp[sw]["misc"]["jnxBoxSerialNo"][0]; + resultArray.push([sw, value]); break; + case 'transceiver': + if(testTree(nmsData,["snmp","snmp",sw,"misc","entPhysicalSerialNum"])) { + for (var x in nmsData.snmp.snmp[sw]["misc"]["entPhysicalSerialNum"]) { + var entPhysicalDescr = nmsData.snmp.snmp[sw]["misc"]["entPhysicalDescr"][x]; + if(!entPhysicalDescr.match(/^SFP/)) { + continue; + } + value = entPhysicalDescr + ": " + nmsData.snmp.snmp[sw]["misc"]["entPhysicalSerialNum"][x]; + resultArray.push([sw, entPhysicalDescr+': '+value]); + } + } + break; + } } catch (e) {console.log("sw: " + sw); console.log(e);} - - resultArray.push([sw, value]); } resultArray.sort(); @@ -986,7 +1018,12 @@ var switchEditPanel = function () { var tmpsw = '\'' + this.sw + '\''; var tmpv = '\'' + v + '\''; var tmphandler = '"nmsInfoBox._editChange(' + tmpsw + ',' + tmpv + ');"'; + if(v == 'community') { + var html = '<input type="password" autocomplete="off" onfocus="this.type = \'text\'" class="form-control" value="' + template[v] + '" id="edit-' + this.sw + '-' + v + '" onchange=' + tmphandler + ' oninput=' + tmphandler + '>'; + } + else { 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>"; } @@ -1199,6 +1236,40 @@ nmsInfoBox.setLegendPick = function(tag,id) { } nmsInfoBox.addPanelType("switchSummary",switchSummaryPanel); +var switchLinks = function() { + nmsInfoPanel.call(this,"switchLinks"); + var latencyChart; + this.init = function() { + this.refresh(); + }; + this.refresh = function(reason) { + var content = []; + if (this.sw == false) { + console.log("ugh, cleanup failed?"); + return; + } + var sw = this.sw; + + var topp = document.createElement("div") + var urls = [ "https://gondul.tg.lol/api/templates/magic.conf/switch=" + sw, + "http://185.110.148.5/api/templates/magic.conf/switch=" + sw, + "http://gondul.tg.lol/api/templates/magic.conf/switch=" + sw ]; + if (testTree(nmsData,['smanagement','switches',sw])) { + var mg = nmsData["smanagement"]["switches"][sw]; + urls.push("ssh://[" + mg.mgmt_v6_addr + "]"); + urls.push("ssh://" + mg.mgmt_v4_addr); + } + for (var x in urls) { + topp.appendChild(document.createElement("br")); + var link = document.createElement("a"); + link.href = urls[x]; + link.textContent = urls[x]; + topp.appendChild(link); + } + this._render(topp); + }; +}; +nmsInfoBox.addPanelType("switchLinks",switchLinks); /* * Panel type: Add network * @@ -1253,7 +1324,6 @@ var networkListPanel = function() { 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); @@ -1384,7 +1454,7 @@ var networkEditPanel = function() { }; this.save = function () { - var myData = nmsInfoBox._editStringify(this.sw); + var myData = nmsInfoBox._editStringify(this.sw,"name"); $.ajax({ type: "POST", url: "/api/write/network-update", @@ -1500,7 +1570,7 @@ nmsInfoBox._editChange = function(sw, v) { out.value = myData; }; -nmsInfoBox._editStringify = function(sw) { - nmsInfoBox._editValues['sysname'] = sw; +nmsInfoBox._editStringify = function(sw, sysname='sysname') { + nmsInfoBox._editValues[sysname] = sw; return JSON.stringify([nmsInfoBox._editValues]); }; diff --git a/web/js/nms-map-handlers.js b/web/js/nms-map-handlers.js index f9fe52b..ba20e03 100644 --- a/web/js/nms-map-handlers.js +++ b/web/js/nms-map-handlers.js @@ -73,6 +73,13 @@ var handler_cpu = { name:"CPU utilization" }; +var handler_memory = { + init:memoryInit, + getInfo:memoryInfo, + tag:"memory", + name:"Memory utilization" +}; + var handler_health = { init:healthInit, getInfo:healthInfo, @@ -133,12 +140,13 @@ var handlers = [ handler_dhcp, handler_snmp, handler_cpu, + handler_memory, handler_snmpup ]; function uplinkInfo(sw) { - var ret = new handlerInfo("uplink","Uplinks"); + var ret = new handlerInfo("snmpup","Uplinks"); ret.why = "Uplinks"; ret.score = 0; var u = 0; @@ -180,7 +188,7 @@ function uplinkInfo(sw) } } } - if (testTree(nmsData,['switchstate','switches',sw,'clients','live'])) { + if (testTree(nmsData,['switchstate','switches',sw,'clients','total'])) { var tu = parseInt(nmsData.switchstate.switches[sw].clients.live); var tt = parseInt(nmsData.switchstate.switches[sw].clients.total); ret.data[1] = {}; @@ -478,7 +486,7 @@ function pingInfo(sw) ret.data[3].description = "Distro-port"; ret.data[3].value = "Distro port is live"; if (isNaN(ping) && isNaN(ping6)) { - ret.score = 850; + ret.score = 700; ret.why = "Distro port is alive, but no IPv4/IPv6 ping. ROLLBACK!"; } } @@ -516,13 +524,13 @@ function getDhcpColor(stop) function dhcpUpdater() { - if (!testTree(nmsData,['dhcp','dhcp']) || !testTree(nmsData,['switches','switches'])) { - return + if (!testTree(nmsData,['dhcp','dhcp']) || !testTree(nmsData,['switches','switches']) || !testTree(nmsData,['smanagement','switches'])) { + return; } var now = nmsData.dhcp.time; for (var sw in nmsData.switches.switches) { var c = nmsColor.blue; - var s = nmsData.dhcp.dhcp[sw]; + var s = nmsData.dhcp.dhcp[nmsData.smanagement.switches[sw].traffic_vlan]; if (s == undefined) { nmsMap.setSwitchColor(sw,c); continue; @@ -536,11 +544,24 @@ function dhcpInfo(sw) { var ret = new handlerInfo("dhcp","DHCP state"); ret.why = "No DHCP data"; ret.data[0].description = "DHCP age"; - if (testTree(nmsData,['dhcp','dhcp',sw])) { + if (!testTree(nmsData,['dhcp','dhcp']) || !testTree(nmsData,['switches','switches']) || !testTree(nmsData,['smanagement','switches'])) { + return ret.data[1] = {}; + } + var dhcpClients = 0; + var clientPortsUp = 0; + var clientPortsUp = setTree(nmsData,['switchstate','switches',sw,'clients','live'],0); + var clientPortsTotal = setTree(nmsData,['switchstate','switches',sw,'clients','total'],0); + if (testTree(nmsData,['dhcp','networks',nmsData.smanagement.switches[sw].traffic_vlan,'clients'])) { + dhcpClients = nmsData.dhcp.networks[nmsData.smanagement.switches[sw].traffic_vlan].clients; + } + if (testTree(nmsData,['dhcp','dhcp',nmsData.smanagement.switches[sw].traffic_vlan])) { var now = nmsData.dhcp.time; - var then = nmsData.dhcp.dhcp[sw]; + var then = nmsData.dhcp.dhcp[nmsData.smanagement.switches[sw].traffic_vlan]; var diff = now - then; var divider = 6; + if (dhcpClients < 10) { + divider = 12; + } if(tagged(sw,'slowdhcp')) { divider = 12; } @@ -551,24 +572,39 @@ function dhcpInfo(sw) { } else { ret.data[0].value = "No DHCP data"; if (testTree(nmsData,['smanagement','switches',sw])) { - if (nmsData.smanagement.switches[sw].subnet4 == undefined || - nmsData.smanagement.switches[sw].subnet4 == "") { - ret.data[0].value = "No associated subnets"; + if (nmsData.smanagement.switches[sw].traffic_vlan == undefined || + nmsData.smanagement.switches[sw].traffic_vlan == "") { + ret.data[0].value = "No associated networks"; ret.score = 0; - ret.why = "No subnet registered"; + ret.why = "No network associated"; } else { - ret.score = 350; - ret.why = "No DHCP data"; + if (!(clientPortsUp < 2 && clientPortsTotal > 20)) { + ret.score = 350; + ret.why = "No DHCP data"; + } else { + ret.data[0].value = "No DHCP data, but too few clients anyway"; + } } } else { ret.score = 100; ret.why = "No management data for DHCP"; } } - if (testTree(nmsData,['dhcp','switches',sw,'clients'])) { + if (testTree(nmsData,['dhcp','networks',nmsData.smanagement.switches[sw].traffic_vlan,'clients'])) { + var dhcpClients = nmsData.dhcp.networks[nmsData.smanagement.switches[sw].traffic_vlan].clients; ret.data[1] = {}; - ret.data[1].value = nmsData.dhcp.switches[sw].clients; + ret.data[1].value = nmsData.dhcp.networks[nmsData.smanagement.switches[sw].traffic_vlan].clients; ret.data[1].description = "DHCP clients"; + if (testTree(nmsData,['switchstate','switches',sw,'clients','live'])) { + var tu = parseInt(nmsData.switchstate.switches[sw].clients.live); + var tt = parseInt(nmsData.switchstate.switches[sw].clients.total); + if (tu - dhcpClients > 5) { + if (ret.score < 450) { + ret.score = 450; + ret.why = "Far more client ports than dhcp clients"; + } + } + } } if (testTree(nmsData,['switches','switches',sw, 'tags'])) { if (tagged(sw,'ignoredhcp')) { @@ -709,7 +745,7 @@ function snmpInit() { } function snmpUpInfo(sw) { - var ret = new handlerInfo("snmpup","SNMP uplink data"); + var ret = new handlerInfo("uplink","SNMP uplink data"); ret.why = "No SNMP data"; ret.score = 0; @@ -718,16 +754,20 @@ function snmpUpInfo(sw) { var seen_up = 0; for (var port in nmsData.snmp.snmp[sw].ports) { var x = nmsData.snmp.snmp[sw].ports[port]; - if (x["ifAlias"].match(/Uplink/i) && x["ifOperStatus"] == "up") { + if (x["ifAlias"].match(/Gruppe/i) && x["ifOperStatus"] == "up") { total_up += parseInt(x["ifHighSpeed"]); } - if (x["ifAlias"].match(/LAG Member/i) && x["ifOperStatus"] == "up") { + if (x["ifAlias"].match(/Fysisk/i) && x["ifOperStatus"] == "up") { seen_up += parseInt(x["ifHighSpeed"]); } } ret.data[0].value = "LAG member speed and total speed is " + seen_up; if (total_up != seen_up) { ret.score = 500; + if (tagged(sw,'ignoreuplink')) { + ret.score = 0; + } + ret.why = "LAG member (ge/xe/et) speed is " + seen_up + " but logical (ae) is " + total_up; ret.data[0].value = ret.why; } @@ -777,6 +817,47 @@ function cpuUpdater() { } } } +function memoryUpdater() { + for (var sw in nmsData.switches.switches) { + try { + var buffer = 0; + for (var u in nmsData.snmp.snmp[sw].misc.jnxOperatingBuffer) { + var local = nmsData.snmp.snmp[sw].misc['jnxOperatingBuffer'][u]; + buffer = Math.max(nmsData.snmp.snmp[sw].misc.jnxOperatingBuffer[u],buffer); + } + nmsMap.setSwitchColor(sw, nmsColor.getColorStop(buffer * 10)); + nmsMap.setSwitchInfo(sw, buffer + " % "); + } catch (e) { + nmsMap.setSwitchColor(sw, "white"); + nmsMap.setSwitchInfo(sw, "N/A"); + } + } +} +function memoryInfo(sw) { + var ret = new handlerInfo("memory","Memory utilization"); + ret.why = "No Memory info"; + ret.score = 0; + + if (testTree(nmsData,['snmp','snmp',sw, 'misc','jnxOperatingBuffer'])) { + var memory = 0; + for (var u in nmsData.snmp.snmp[sw].misc.jnxOperatingBuffer) { + var local = nmsData.snmp.snmp[sw].misc['jnxOperatingBuffer'][u]; + memory = Math.max(nmsData.snmp.snmp[sw].misc.jnxOperatingBuffer[u],memory); + } + if (memory < 70) { + ret.score = 0; + } else if (memory < 80) { + ret.score = 100; + } else if (memory < 90) { + ret.score = memory * 2; + } else { + ret.score = memory * 6; + } + ret.why = "Memory utilization: " + memory + "%"; + ret.data[0].value = memory + "%"; + } + return ret; +} function tagged(sw, tag) { if (testTree(nmsData,['switches','switches',sw, 'tags'])) { @@ -793,6 +874,14 @@ function mgmtInfo(sw) { ret.why = "All good"; if (testTree(nmsData,['smanagement','switches',sw])) { var mg = nmsData.smanagement.switches[sw]; + var traffic_vlan = "N/A"; + var mgmt_vlan = "N/A"; + if (testTree(nmsData,['networks','networks',mg.traffic_vlan,"vlan"])) { + traffic_vlan = nmsData["networks"]["networks"][mg.traffic_vlan]["vlan"]; + } + if (testTree(nmsData,['networks','networks',mg.mgmt_vlan,"vlan"])) { + mgmt_vlan = nmsData["networks"]["networks"][mg.mgmt_vlan]["vlan"]; + } ret.data = [{ value: mg.mgmt_v4_addr || "N/A", @@ -809,7 +898,14 @@ function mgmtInfo(sw) { }, { value: mg.distro_name || "N/A", description: "Distro" - }]; + }, { + value: traffic_vlan || "N/A", + description: "Client VLAN" + }, { + value: mgmt_vlan || "N/A", + description: "Management VLAN" + } + ]; if ((mg.mgmt_v4_addr == undefined || mg.mgmt_v4_addr == "") && (mg.mgmt_v6_addr == undefined || mg.mgmt_v6_addr == "")) { ret.why = "No IPv4 or IPv6 management IP"; ret.score = 1000; @@ -843,6 +939,16 @@ function cpuInit() { setLegend(5,"white","N/A"); cpuUpdater(); } +function memoryInit() { + nmsData.addHandler("snmp", "mapHandler", memoryUpdater); + nmsColor.drawGradient([nmsColor.green,nmsColor.orange,nmsColor.red]); + setLegend(1,getColorStop(0),"0 %"); + setLegend(2,getColorStop(250),"25 %"); + setLegend(3,getColorStop(600),"60 %"); + setLegend(4,getColorStop(1000),"100 %"); + setLegend(5,"white","N/A"); + memoryUpdater(); +} function healthInfo(sw) { var worst = new handlerInfo("health", "Health"); diff --git a/web/js/nms-template.js b/web/js/nms-template.js index c34ef34..0f25367 100644 --- a/web/js/nms-template.js +++ b/web/js/nms-template.js @@ -4,36 +4,52 @@ var nmsTemplate = nmsTemplate || { } nmsTemplate.test = function() { - var input = document.getElementById("template-input"); - var output = document.getElementById("template-output"); - var qp = document.getElementById("template-query-params"); - $.ajax({ - type: "POST", - url: "/api/templates/test" + qp.value, - async: false, - data: input.value, - dataType: "text", - success: function (indata, textStatus, jqXHR) { - var output = document.getElementById("template-output"); - output.value = jqXHR.responseText; - }, - error: function (jqXHR, textStatus) { - var output = document.getElementById("template-output"); - output.value = jqXHR.responseText; - } - }); + var input = document.getElementById("template-input"); + var output = document.getElementById("template-output"); + var qp = document.getElementById("template-query-params"); + $.ajax({ + type: "POST", + url: "/api/templates/test" + qp.value, + async: false, + data: input.value, + dataType: "text", + success: function (indata, textStatus, jqXHR) { + var output = document.getElementById("template-output"); + output.value = jqXHR.responseText; + }, + error: function (jqXHR, textStatus) { + var output = document.getElementById("template-output"); + output.value = jqXHR.responseText; + } + }); } nmsTemplate.fromFile = function(template) { - $.ajax({ - type: "GET", - url: "/templates/" + template, - async: false, - dataType: "text", - success: function (indata, textStatus, jqXHR) { - var output = document.getElementById("template-input"); - output.value = indata; - } - }); - nmsTemplate.test(); + if(template == '') { return; } + $.ajax({ + type: "GET", + url: "/templates/" + template, + async: false, + dataType: "text", + success: function (indata, textStatus, jqXHR) { + var output = document.getElementById("template-input"); + output.value = indata; + } + }); + nmsTemplate.test(); } + +nmsTemplate.getTemplates = function() { + $.ajax({ + type: "GET", + url: "/api/read/template-list", + async: false, + dataType: "json", + success: function (indata, textStatus, jqXHR) { + $.each( indata['templates'], function( value ) { + $('#nmsTemplate-select').append($("<option></option>").attr("value",indata['templates'][value]['file']).text(indata['templates'][value]['file'])); + }); + } + }); +} +//nmsTemplate.getTemplates(); diff --git a/web/js/nms-time.js b/web/js/nms-time.js index 315ac79..30604cd 100644 --- a/web/js/nms-time.js +++ b/web/js/nms-time.js @@ -10,11 +10,15 @@ */ var nmsTime = nmsTime || { _now: undefined, - _handle: undefined + _handle: undefined, + _stopTime: undefined } nmsTime.replayEvent = function() { - throw "Not yet implemented."; + var eStart = setTree(nmsData,["config","config","data","start"],"2018-03-23T00:00:00+0200"); + nmsTime._stopTime = new Date(setTree(nmsData,["config","config","data","end"],"2018-04-01T14:30:00+0200")); + nmsTime.setNow(eStart); + nmsTime.startPlayback(10); } nmsTime.isRealTime = function() { @@ -89,6 +93,10 @@ nmsTime.step = function(amount) { nmsTime.realTime(); return; } + if (nmsTime._stopTime != undefined && nmsTime._now.getTime() >= nmsTime._stopTime.getTime()) { + nmsTime.stopPlayback(); + nmsTime._stopTime = undefined; + } nmsTime._now.setMinutes(nmsTime._now.getMinutes() + amount); nmsTime._updateData(); } diff --git a/web/js/nms.js b/web/js/nms.js index b872ec1..3a37e4a 100644 --- a/web/js/nms.js +++ b/web/js/nms.js @@ -134,7 +134,7 @@ function nmsTimer(handler, interval, name, description) { function byteCount(bytes,precision) { if (precision ==undefined) precision = 1; - var units = ['', 'K', 'M', 'G', 'T', 'P']; + var units = ['', 'K', 'M', 'G', 'T', 'P', 'E','Z']; var i = 0; while (bytes > 1024) { bytes = bytes / 1024; @@ -356,6 +356,7 @@ function getInitialConfig() { } else { nms._public = false; document.body.classList.add("gondul-private"); + nmsTemplate.getTemplates(); } } }); @@ -639,14 +640,25 @@ function nmsUpdateNavbarGraph() { * do stuff with nmsData.snmp.snmp[sw].misc * } * + * New: setTree(root, array, default): + * same thing, but instead of just returing true/false, return the value found + * or the provided default. */ -function testTree(root, ar) { - if (ar == undefined || root == undefined) - return false; - for (var i in ar) { - root = root[ar[i]]; - if (root == undefined) - return false; +function setTree(root, ar, def) { + if (ar == undefined || root == undefined) { + return def; + } else { + for (var i in ar) { + root = root[ar[i]]; + if (root == undefined) + return def; + } } - return true; + return root; +} +function testTree(root, ar) { + var x = setTree(root,ar,false); + if (x != false) + return true; } + diff --git a/web/templates/HOWTO.txt b/web/templates/HOWTO.txt index ed47926..641878e 100644 --- a/web/templates/HOWTO.txt +++ b/web/templates/HOWTO.txt @@ -8,7 +8,7 @@ We utilize Jinja2 templates. -#} {% set url = "localhost" -%} -{% set example_switch = "distro0" -%} +{% set example_switch = "r1.tele" -%} See http://jinja.pocoo.org/ for the full documentation of the templating language. |