Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Release.

  • Loading branch information...
commit cfeaa7ada27e4d1aad6713cb05a505042a540c71 2 parents e8fb885 + 803ef01
Heinz N. Gies Licenser authored
Showing with 2,314 additions and 1,778 deletions.
  1. +4 −1 .gitignore
  2. +4 −1 Makefile
  3. +112 −0 apps/wiggle/mibs/WIGGLE-MIB.funcs
  4. +857 −0 apps/wiggle/mibs/WIGGLE-MIB.mib
  5. +5 −1 apps/wiggle/src/wiggle.app.src
  6. +4 −0 apps/wiggle/src/wiggle.erl
  7. +8 −0 apps/wiggle/src/wiggle.hrl
  8. +39 −15 apps/wiggle/src/wiggle_app.erl
  9. +29 −137 apps/wiggle/src/wiggle_cloud_handler.erl
  10. +63 −166 apps/wiggle/src/wiggle_dataset_handler.erl
  11. +57 −172 apps/wiggle/src/wiggle_dtrace_handler.erl
  12. +74 −185 apps/wiggle/src/wiggle_group_handler.erl
  13. +57 −11 apps/wiggle/src/wiggle_handler.erl
  14. +52 −157 apps/wiggle/src/wiggle_hypervisor_handler.erl
  15. +55 −169 apps/wiggle/src/wiggle_iprange_handler.erl
  16. +44 −166 apps/wiggle/src/wiggle_package_handler.erl
  17. +201 −0 apps/wiggle/src/wiggle_rest_handler.erl
  18. +30 −134 apps/wiggle/src/wiggle_session_handler.erl
  19. +132 −0 apps/wiggle/src/wiggle_snmp_handler.erl
  20. +4 −1 apps/wiggle/src/wiggle_sup.erl
  21. +103 −206 apps/wiggle/src/wiggle_user_handler.erl
  22. +148 −197 apps/wiggle/src/wiggle_vm_handler.erl
  23. +8 −9 apps/wiggle/src/wiggle_vnc_handler.erl
  24. +90 −0 generate_zabbix_template.sh
  25. 0  plugins/.gitignore
  26. +22 −2 rebar.config
  27. +9 −0 rel/files/app.config
  28. +25 −0 rel/files/wiggle
  29. +47 −44 rel/files/wiggle.xml
  30. +1 −1  rel/pkg/Makefile
  31. +1 −1  rel/pkg/install.sh
  32. +5 −2 rel/reltool.config
  33. +4 −0 snmp/conf/agent.conf
  34. +1 −0  snmp/conf/community.conf
  35. +4 −0 snmp/conf/context.conf
  36. +7 −0 snmp/conf/standard.conf
  37. 0  snmp/conf/usm.conf
  38. +7 −0 snmp/conf/vacm.conf
  39. +1 −0  snmp/db/.gitignore
5 .gitignore
View
@@ -1,3 +1,7 @@
+wiggle_template.xml
+apps/wiggle/include/WIGGLE-MIB.hrl
+crash.log
+*.bin
*.version
apps/wiggle/src/wiggle_version.hrl
apps/wiggle/.eunit/
@@ -7,7 +11,6 @@ rel/pkg/build-info
gproc_dist_*
standalone.config
ebin
-db
deps
*~
.DS_Store
5 Makefile
View
@@ -27,7 +27,7 @@ test: all
$(REBAR) skip_deps=true xref
$(REBAR) skip_deps=true eunit
-rel: all
+rel: all zabbix
$(REBAR) generate
relclean:
@@ -39,6 +39,9 @@ package: rel
console: all
erl -pa deps/*/ebin apps/*/ebin -s wiggle -config standalone.config
+zabbix:
+ sh generate_zabbix_template.sh
+
###
### Docs
###
112 apps/wiggle/mibs/WIGGLE-MIB.funcs
View
@@ -0,0 +1,112 @@
+{name, {wiggle_snmp_handler, name, []}}.
+{version, {wiggle_snmp_handler, version, []}}.
+
+{usersP999, {wiggle_snmp_handler, p999, [<<"/api/0.1.0/users">>]}}.
+{usersP99, {wiggle_snmp_handler, p99, [<<"/api/0.1.0/users">>]}}.
+{usersP95, {wiggle_snmp_handler, p95, [<<"/api/0.1.0/users">>]}}.
+{usersP75, {wiggle_snmp_handler, p75, [<<"/api/0.1.0/users">>]}}.
+{usersP25, {wiggle_snmp_handler, p25, [<<"/api/0.1.0/users">>]}}.
+{usersCount, {wiggle_snmp_handler, count, [<<"/api/0.1.0/users">>]}}.
+{usersMin, {wiggle_snmp_handler, min, [<<"/api/0.1.0/users">>]}}.
+{usersMedian, {wiggle_snmp_handler, median, [<<"/api/0.1.0/users">>]}}.
+{usersMean, {wiggle_snmp_handler, mean, [<<"/api/0.1.0/users">>]}}.
+{usersMax, {wiggle_snmp_handler, max, [<<"/api/0.1.0/users">>]}}.
+
+{sessionsP999, {wiggle_snmp_handler, p999, [<<"/api/0.1.0/sessions">>]}}.
+{sessionsP99, {wiggle_snmp_handler, p99, [<<"/api/0.1.0/sessions">>]}}.
+{sessionsP95, {wiggle_snmp_handler, p95, [<<"/api/0.1.0/sessions">>]}}.
+{sessionsP75, {wiggle_snmp_handler, p75, [<<"/api/0.1.0/sessions">>]}}.
+{sessionsP25, {wiggle_snmp_handler, p25, [<<"/api/0.1.0/sessions">>]}}.
+{sessionsCount, {wiggle_snmp_handler, count, [<<"/api/0.1.0/sessions">>]}}.
+{sessionsMin, {wiggle_snmp_handler, min, [<<"/api/0.1.0/sessions">>]}}.
+{sessionsMedian, {wiggle_snmp_handler, median, [<<"/api/0.1.0/sessions">>]}}.
+{sessionsMean, {wiggle_snmp_handler, mean, [<<"/api/0.1.0/sessions">>]}}.
+{sessionsMax, {wiggle_snmp_handler, max, [<<"/api/0.1.0/sessions">>]}}.
+
+{groupsP999, {wiggle_snmp_handler, p999, [<<"/api/0.1.0/groups">>]}}.
+{groupsP99, {wiggle_snmp_handler, p99, [<<"/api/0.1.0/groups">>]}}.
+{groupsP95, {wiggle_snmp_handler, p95, [<<"/api/0.1.0/groups">>]}}.
+{groupsP75, {wiggle_snmp_handler, p75, [<<"/api/0.1.0/groups">>]}}.
+{groupsP25, {wiggle_snmp_handler, p25, [<<"/api/0.1.0/groups">>]}}.
+{groupsCount, {wiggle_snmp_handler, count, [<<"/api/0.1.0/groups">>]}}.
+{groupsMin, {wiggle_snmp_handler, min, [<<"/api/0.1.0/groups">>]}}.
+{groupsMedian, {wiggle_snmp_handler, median, [<<"/api/0.1.0/groups">>]}}.
+{groupsMean, {wiggle_snmp_handler, mean, [<<"/api/0.1.0/groups">>]}}.
+{groupsMax, {wiggle_snmp_handler, max, [<<"/api/0.1.0/groups">>]}}.
+
+{cloudP999, {wiggle_snmp_handler, p999, [<<"/api/0.1.0/cloud">>]}}.
+{cloudP99, {wiggle_snmp_handler, p99, [<<"/api/0.1.0/cloud">>]}}.
+{cloudP95, {wiggle_snmp_handler, p95, [<<"/api/0.1.0/cloud">>]}}.
+{cloudP75, {wiggle_snmp_handler, p75, [<<"/api/0.1.0/cloud">>]}}.
+{cloudP25, {wiggle_snmp_handler, p25, [<<"/api/0.1.0/cloud">>]}}.
+{cloudCount, {wiggle_snmp_handler, count, [<<"/api/0.1.0/cloud">>]}}.
+{cloudMin, {wiggle_snmp_handler, min, [<<"/api/0.1.0/cloud">>]}}.
+{cloudMedian, {wiggle_snmp_handler, median, [<<"/api/0.1.0/cloud">>]}}.
+{cloudMean, {wiggle_snmp_handler, mean, [<<"/api/0.1.0/cloud">>]}}.
+{cloudMax, {wiggle_snmp_handler, max, [<<"/api/0.1.0/cloud">>]}}.
+
+{hypervisorsP999, {wiggle_snmp_handler, p999, [<<"/api/0.1.0/hypervisors">>]}}.
+{hypervisorsP99, {wiggle_snmp_handler, p99, [<<"/api/0.1.0/hypervisors">>]}}.
+{hypervisorsP95, {wiggle_snmp_handler, p95, [<<"/api/0.1.0/hypervisors">>]}}.
+{hypervisorsP75, {wiggle_snmp_handler, p75, [<<"/api/0.1.0/hypervisors">>]}}.
+{hypervisorsP25, {wiggle_snmp_handler, p25, [<<"/api/0.1.0/hypervisors">>]}}.
+{hypervisorsCount, {wiggle_snmp_handler, count, [<<"/api/0.1.0/hypervisors">>]}}.
+{hypervisorsMin, {wiggle_snmp_handler, min, [<<"/api/0.1.0/hypervisors">>]}}.
+{hypervisorsMedian, {wiggle_snmp_handler, median, [<<"/api/0.1.0/hypervisors">>]}}.
+{hypervisorsMean, {wiggle_snmp_handler, mean, [<<"/api/0.1.0/hypervisors">>]}}.
+{hypervisorsMax, {wiggle_snmp_handler, max, [<<"/api/0.1.0/hypervisors">>]}}.
+
+{dtraceP999, {wiggle_snmp_handler, p999, [<<"/api/0.1.0/dtrace">>]}}.
+{dtraceP99, {wiggle_snmp_handler, p99, [<<"/api/0.1.0/dtrace">>]}}.
+{dtraceP95, {wiggle_snmp_handler, p95, [<<"/api/0.1.0/dtrace">>]}}.
+{dtraceP75, {wiggle_snmp_handler, p75, [<<"/api/0.1.0/dtrace">>]}}.
+{dtraceP25, {wiggle_snmp_handler, p25, [<<"/api/0.1.0/dtrace">>]}}.
+{dtraceCount, {wiggle_snmp_handler, count, [<<"/api/0.1.0/dtrace">>]}}.
+{dtraceMin, {wiggle_snmp_handler, min, [<<"/api/0.1.0/dtrace">>]}}.
+{dtraceMedian, {wiggle_snmp_handler, median, [<<"/api/0.1.0/dtrace">>]}}.
+{dtraceMean, {wiggle_snmp_handler, mean, [<<"/api/0.1.0/dtrace">>]}}.
+{dtraceMax, {wiggle_snmp_handler, max, [<<"/api/0.1.0/dtrace">>]}}.
+
+{vmsP999, {wiggle_snmp_handler, p999, [<<"/api/0.1.0/vms">>]}}.
+{vmsP99, {wiggle_snmp_handler, p99, [<<"/api/0.1.0/vms">>]}}.
+{vmsP95, {wiggle_snmp_handler, p95, [<<"/api/0.1.0/vms">>]}}.
+{vmsP75, {wiggle_snmp_handler, p75, [<<"/api/0.1.0/vms">>]}}.
+{vmsP25, {wiggle_snmp_handler, p25, [<<"/api/0.1.0/vms">>]}}.
+{vmsCount, {wiggle_snmp_handler, count, [<<"/api/0.1.0/vms">>]}}.
+{vmsMin, {wiggle_snmp_handler, min, [<<"/api/0.1.0/vms">>]}}.
+{vmsMedian, {wiggle_snmp_handler, median, [<<"/api/0.1.0/vms">>]}}.
+{vmsMean, {wiggle_snmp_handler, mean, [<<"/api/0.1.0/vms">>]}}.
+{vmsMax, {wiggle_snmp_handler, max, [<<"/api/0.1.0/vms">>]}}.
+
+{iprangesP999, {wiggle_snmp_handler, p999, [<<"/api/0.1.0/ipranges">>]}}.
+{iprangesP99, {wiggle_snmp_handler, p99, [<<"/api/0.1.0/ipranges">>]}}.
+{iprangesP95, {wiggle_snmp_handler, p95, [<<"/api/0.1.0/ipranges">>]}}.
+{iprangesP75, {wiggle_snmp_handler, p75, [<<"/api/0.1.0/ipranges">>]}}.
+{iprangesP25, {wiggle_snmp_handler, p25, [<<"/api/0.1.0/ipranges">>]}}.
+{iprangesCount, {wiggle_snmp_handler, count, [<<"/api/0.1.0/ipranges">>]}}.
+{iprangesMin, {wiggle_snmp_handler, min, [<<"/api/0.1.0/ipranges">>]}}.
+{iprangesMedian, {wiggle_snmp_handler, median, [<<"/api/0.1.0/ipranges">>]}}.
+{iprangesMean, {wiggle_snmp_handler, mean, [<<"/api/0.1.0/ipranges">>]}}.
+{iprangesMax, {wiggle_snmp_handler, max, [<<"/api/0.1.0/ipranges">>]}}.
+
+{datasetsP999, {wiggle_snmp_handler, p999, [<<"/api/0.1.0/datasets">>]}}.
+{datasetsP99, {wiggle_snmp_handler, p99, [<<"/api/0.1.0/datasets">>]}}.
+{datasetsP95, {wiggle_snmp_handler, p95, [<<"/api/0.1.0/datasets">>]}}.
+{datasetsP75, {wiggle_snmp_handler, p75, [<<"/api/0.1.0/datasets">>]}}.
+{datasetsP25, {wiggle_snmp_handler, p25, [<<"/api/0.1.0/datasets">>]}}.
+{datasetsCount, {wiggle_snmp_handler, count, [<<"/api/0.1.0/datasets">>]}}.
+{datasetsMin, {wiggle_snmp_handler, min, [<<"/api/0.1.0/datasets">>]}}.
+{datasetsMedian, {wiggle_snmp_handler, median, [<<"/api/0.1.0/datasets">>]}}.
+{datasetsMean, {wiggle_snmp_handler, mean, [<<"/api/0.1.0/datasets">>]}}.
+{datasetsMax, {wiggle_snmp_handler, max, [<<"/api/0.1.0/datasets">>]}}.
+
+{packagesP999, {wiggle_snmp_handler, p999, [<<"/api/0.1.0/packages">>]}}.
+{packagesP99, {wiggle_snmp_handler, p99, [<<"/api/0.1.0/packages">>]}}.
+{packagesP95, {wiggle_snmp_handler, p95, [<<"/api/0.1.0/packages">>]}}.
+{packagesP75, {wiggle_snmp_handler, p75, [<<"/api/0.1.0/packages">>]}}.
+{packagesP25, {wiggle_snmp_handler, p25, [<<"/api/0.1.0/packages">>]}}.
+{packagesCount, {wiggle_snmp_handler, count, [<<"/api/0.1.0/packages">>]}}.
+{packagesMin, {wiggle_snmp_handler, min, [<<"/api/0.1.0/packages">>]}}.
+{packagesMedian, {wiggle_snmp_handler, median, [<<"/api/0.1.0/packages">>]}}.
+{packagesMean, {wiggle_snmp_handler, mean, [<<"/api/0.1.0/packages">>]}}.
+{packagesMax, {wiggle_snmp_handler, max, [<<"/api/0.1.0/packages">>]}}.
857 apps/wiggle/mibs/WIGGLE-MIB.mib
View
@@ -0,0 +1,857 @@
+-- 1.3.6.1.4.1
+WIGGLE-MIB DEFINITIONS ::= BEGIN
+
+ IMPORTS
+ experimental FROM RFC1155-SMI
+ RowStatus FROM STANDARD-MIB
+ DisplayString FROM RFC1213-MIB
+ OBJECT-TYPE FROM RFC-1212
+ enterprises FROM SNMPv2-SMI
+ ;
+
+ fifo OBJECT IDENTIFIER ::= { enterprises 41822 }
+-- Group section
+ wiggle OBJECT IDENTIFIER ::= { fifo 1 }
+
+ users OBJECT IDENTIFIER ::= { wiggle 3 }
+ sessions OBJECT IDENTIFIER ::= { wiggle 4 }
+ groups OBJECT IDENTIFIER ::= { wiggle 5 }
+
+ cloud OBJECT IDENTIFIER ::= { wiggle 6 }
+ hypervisors OBJECT IDENTIFIER ::= { wiggle 7 }
+ dtrace OBJECT IDENTIFIER ::= { wiggle 8 }
+ vms OBJECT IDENTIFIER ::= { wiggle 9 }
+ ipranges OBJECT IDENTIFIER ::= { wiggle 10 }
+ datasets OBJECT IDENTIFIER ::= { wiggle 11 }
+ packages OBJECT IDENTIFIER ::= { wiggle 12 }
+
+
+
+-- General section.
+ name OBJECT-TYPE
+ SYNTAX DisplayString (SIZE (0..255))
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "My own name"
+ ::= { wiggle 1 }
+
+ version OBJECT-TYPE
+ SYNTAX DisplayString (SIZE (0..255))
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "wiggle version"
+ ::= { wiggle 2 }
+
+-- Users Section
+ usersP999 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "99.9 percertile"
+ ::= { users 1 }
+
+ usersP99 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "99 percertile"
+ ::= { users 2 }
+
+ usersP95 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "95 percertile"
+ ::= { users 3 }
+
+ usersP75 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "75 percertile"
+ ::= { users 4 }
+
+ usersP25 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "25 percertile"
+ ::= { users 5 }
+
+ usersCount OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { users 6 }
+
+ usersMin OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { users 7 }
+
+ usersMedian OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { users 8 }
+
+ usersMean OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { users 9 }
+
+ usersMax OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { users 10 }
+
+-- Sessions Section
+ sessionsP999 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "99.9 percertile"
+ ::= { sessions 1 }
+
+ sessionsP99 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "99 percertile"
+ ::= { sessions 2 }
+
+ sessionsP95 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "95 percertile"
+ ::= { sessions 3 }
+
+ sessionsP75 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "75 percertile"
+ ::= { sessions 4 }
+
+ sessionsP25 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "25 percertile"
+ ::= { sessions 5 }
+
+ sessionsCount OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { sessions 6 }
+
+ sessionsMin OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { sessions 7 }
+
+ sessionsMedian OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { sessions 8 }
+
+ sessionsMean OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { sessions 9 }
+
+ sessionsMax OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { sessions 10 }
+
+-- Groups Section
+ groupsP999 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "99.9 percertile"
+ ::= { groups 1 }
+
+ groupsP99 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "99 percertile"
+ ::= { groups 2 }
+
+ groupsP95 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "95 percertile"
+ ::= { groups 3 }
+
+ groupsP75 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "75 percertile"
+ ::= { groups 4 }
+
+ groupsP25 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "25 percertile"
+ ::= { groups 5 }
+
+ groupsCount OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { groups 6 }
+
+ groupsMin OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { groups 7 }
+
+ groupsMedian OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { groups 8 }
+
+ groupsMean OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { groups 9 }
+
+ groupsMax OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { groups 10 }
+
+-- Cloud Section
+ cloudP999 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "99.9 percertile"
+ ::= { cloud 1 }
+
+ cloudP99 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "99 percertile"
+ ::= { cloud 2 }
+
+ cloudP95 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "95 percertile"
+ ::= { cloud 3 }
+
+ cloudP75 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "75 percertile"
+ ::= { cloud 4 }
+
+ cloudP25 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "25 percertile"
+ ::= { cloud 5 }
+
+ cloudCount OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { cloud 6 }
+
+ cloudMin OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { cloud 7 }
+
+ cloudMedian OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { cloud 8 }
+
+ cloudMean OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { cloud 9 }
+
+ cloudMax OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { cloud 10 }
+
+-- Hypervisors Section
+ hypervisorsP999 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "99.9 percertile"
+ ::= { hypervisors 1 }
+
+ hypervisorsP99 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "99 percertile"
+ ::= { hypervisors 2 }
+
+ hypervisorsP95 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "95 percertile"
+ ::= { hypervisors 3 }
+
+ hypervisorsP75 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "75 percertile"
+ ::= { hypervisors 4 }
+
+ hypervisorsP25 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "25 percertile"
+ ::= { hypervisors 5 }
+
+ hypervisorsCount OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { hypervisors 6 }
+
+ hypervisorsMin OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { hypervisors 7 }
+
+ hypervisorsMedian OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { hypervisors 8 }
+
+ hypervisorsMean OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { hypervisors 9 }
+
+ hypervisorsMax OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { hypervisors 10 }
+
+-- Dtrace Section
+ dtraceP999 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "99.9 percertile"
+ ::= { dtrace 1 }
+
+ dtraceP99 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "99 percertile"
+ ::= { dtrace 2 }
+
+ dtraceP95 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "95 percertile"
+ ::= { dtrace 3 }
+
+ dtraceP75 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "75 percertile"
+ ::= { dtrace 4 }
+
+ dtraceP25 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "25 percertile"
+ ::= { dtrace 5 }
+
+ dtraceCount OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { dtrace 6 }
+
+ dtraceMin OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { dtrace 7 }
+
+ dtraceMedian OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { dtrace 8 }
+
+ dtraceMean OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { dtrace 9 }
+
+ dtraceMax OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { dtrace 10 }
+
+-- VMs Section
+ vmsP999 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "99.9 percertile"
+ ::= { vms 1 }
+
+ vmsP99 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "99 percertile"
+ ::= { vms 2 }
+
+ vmsP95 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "95 percertile"
+ ::= { vms 3 }
+
+ vmsP75 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "75 percertile"
+ ::= { vms 4 }
+
+ vmsP25 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "25 percertile"
+ ::= { vms 5 }
+
+ vmsCount OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { vms 6 }
+
+ vmsMin OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { vms 7 }
+
+ vmsMedian OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { vms 8 }
+
+ vmsMean OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { vms 9 }
+
+ vmsMax OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { vms 10 }
+
+-- Ipranges Section
+ iprangesP999 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "99.9 percertile"
+ ::= { ipranges 1 }
+
+ iprangesP99 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "99 percertile"
+ ::= { ipranges 2 }
+
+ iprangesP95 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "95 percertile"
+ ::= { ipranges 3 }
+
+ iprangesP75 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "75 percertile"
+ ::= { ipranges 4 }
+
+ iprangesP25 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "25 percertile"
+ ::= { ipranges 5 }
+
+ iprangesCount OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { ipranges 6 }
+
+ iprangesMin OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { ipranges 7 }
+
+ iprangesMedian OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { ipranges 8 }
+
+ iprangesMean OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { ipranges 9 }
+
+ iprangesMax OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { ipranges 10 }
+
+-- Datasets Section
+ datasetsP999 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "99.9 percertile"
+ ::= { datasets 1 }
+
+ datasetsP99 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "99 percertile"
+ ::= { datasets 2 }
+
+ datasetsP95 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "95 percertile"
+ ::= { datasets 3 }
+
+ datasetsP75 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "75 percertile"
+ ::= { datasets 4 }
+
+ datasetsP25 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "25 percertile"
+ ::= { datasets 5 }
+
+ datasetsCount OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { datasets 6 }
+
+ datasetsMin OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { datasets 7 }
+
+ datasetsMedian OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { datasets 8 }
+
+ datasetsMean OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { datasets 9 }
+
+ datasetsMax OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { datasets 10 }
+
+-- Packages Section
+ packagesP999 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "99.9 percertile"
+ ::= { packages 1 }
+
+ packagesP99 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "99 percertile"
+ ::= { packages 2 }
+
+ packagesP95 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "95 percertile"
+ ::= { packages 3 }
+
+ packagesP75 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "75 percertile"
+ ::= { packages 4 }
+
+ packagesP25 OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "25 percertile"
+ ::= { packages 5 }
+
+ packagesCount OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { packages 6 }
+
+ packagesMin OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { packages 7 }
+
+ packagesMedian OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { packages 8 }
+
+ packagesMean OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { packages 9 }
+
+ packagesMax OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "number of events"
+ ::= { packages 10 }
+
+END
6 apps/wiggle/src/wiggle.app.src
View
@@ -1,7 +1,7 @@
{application, wiggle,
[
{description, ""},
- {vsn, "0.4.7p1"},
+ {vsn, "0.4.8"},
{registered, []},
{applications, [
kernel,
@@ -13,6 +13,10 @@
jsx,
lager,
mimetypes,
+ newrelic,
+ snmp,
+ mnesia,
+ eplugin,
cowboy
]},
{mod, { wiggle_app, []}},
4 apps/wiggle/src/wiggle.erl
View
@@ -5,6 +5,7 @@
-ignore_xref([start/0]).
start() ->
+ application:start(sasl),
lager:start(),
application:start(mdns_client_lib),
application:start(libsnarlmatch),
@@ -18,5 +19,8 @@ start() ->
application:start(crypto),
application:start(ranch),
application:start(cowboy),
+ application:start(newrelic),
+ application:start(mnesia),
+ application:start(snmp),
application:start(wiggle).
8 apps/wiggle/src/wiggle.hrl
View
@@ -0,0 +1,8 @@
+-record(state, {module, path, method, version, token, content, reply, obj, body, start, path_bin, etag}).
+
+-define(P(State), State#state.path_bin).
+-define(MEx(Path, Service, Start), statman_histogram:record_value({Path, {ext, Service}}, Start)).
+-define(MSnarl(Path, Start), ?MEx(Path, <<"snarl">>, Start)).
+-define(MSniffle(Path, Start), ?MEx(Path, <<"sniffle">>, Start)).
+-define(MHowl(Path, Start), ?MEx(Path, <<"howl">>, Start)).
+-define(M(Path, Start), statman_histogram:record_value({Path, total}, Start)).
54 apps/wiggle/src/wiggle_app.erl
View
@@ -9,30 +9,54 @@
%% Application callbacks
%% ===================================================================
-
start(_StartType, _StartArgs) ->
{ok, Port} = application:get_env(wiggle, port),
{ok, Acceptors} = application:get_env(wiggle, acceptors),
+ PluginDispatchs = eplugin:fold('wiggle:dispatchs', []),
Dispatch = cowboy_router:compile(
- [{'_', [{<<"/api/:version/users/[...]">>, wiggle_user_handler, []},
- {<<"/api/:version/sessions/[...]">>, wiggle_session_handler, []},
- {<<"/api/:version/groups/[...]">>, wiggle_group_handler, []},
- {<<"/api/:version/cloud/[...]">>, wiggle_cloud_handler, []},
- {<<"/api/:version/hypervisors/[...]">>, wiggle_hypervisor_handler, []},
- {<<"/api/:version/dtrace/:uuid/stream">>, wiggle_dtrace_stream, []},
- {<<"/api/:version/dtrace/[...]">>, wiggle_dtrace_handler, []},
- {<<"/api/:version/vms/:uuid/console">>, wiggle_console_handler, []},
- {<<"/api/:version/vms/:uuid/vnc">>, wiggle_vnc_handler, []},
- {<<"/api/:version/vms/[...]">>, wiggle_vm_handler, []},
- {<<"/api/:version/ipranges/[...]">>, wiggle_iprange_handler, []},
- {<<"/api/:version/datasets/[...]">>, wiggle_dataset_handler, []},
- {<<"/api/:version/packages/[...]">>, wiggle_package_handler, []}]}]
+ [{'_', [{<<"/api/:version/users/[...]">>,
+ wiggle_rest_handler, [wiggle_user_handler]},
+ {<<"/api/:version/sessions/[...]">>,
+ wiggle_rest_handler, [wiggle_session_handler]},
+ {<<"/api/:version/groups/[...]">>,
+ wiggle_rest_handler, [wiggle_group_handler]},
+ {<<"/api/:version/cloud/[...]">>,
+ wiggle_rest_handler, [wiggle_cloud_handler]},
+ {<<"/api/:version/hypervisors/[...]">>,
+ wiggle_rest_handler, [wiggle_hypervisor_handler]},
+ {<<"/api/:version/dtrace/:uuid/stream">>,
+ wiggle_dtrace_stream, []},
+ {<<"/api/:version/dtrace/[...]">>,
+ wiggle_rest_handler, [wiggle_dtrace_handler]},
+ {<<"/api/:version/vms/:uuid/console">>,
+ wiggle_console_handler, []},
+ {<<"/api/:version/vms/:uuid/vnc">>,
+ wiggle_vnc_handler, []},
+ {<<"/api/:version/vms/[...]">>,
+ wiggle_rest_handler, [wiggle_vm_handler]},
+ {<<"/api/:version/ipranges/[...]">>,
+ wiggle_rest_handler, [wiggle_iprange_handler]},
+ {<<"/api/:version/datasets/[...]">>,
+ wiggle_rest_handler, [wiggle_dataset_handler]},
+ {<<"/api/:version/packages/[...]">>,
+ wiggle_rest_handler, [wiggle_package_handler]}] ++
+ PluginDispatchs
+ }]
),
{ok, _} = cowboy:start_http(http, Acceptors, [{port, Port}],
[{env, [{dispatch, Dispatch}]}]),
- wiggle_sup:start_link().
+ R = wiggle_sup:start_link(),
+ statman_server:add_subscriber(statman_aggregator),
+ wiggle_snmp_handler:start(),
+ case application:get_env(newrelic,license_key) of
+ undefined ->
+ ok;
+ _ ->
+ newrelic_poller:start_link(fun newrelic_statman:poll/0)
+ end,
+ R.
stop(_State) ->
ok.
166 apps/wiggle/src/wiggle_cloud_handler.erl
View
@@ -1,83 +1,17 @@
-%% Feel free to use, reuse and abuse the code in this file.
-
-%% @doc Hello world handler.
-module(wiggle_cloud_handler).
-include("wiggle_version.hrl").
+-include("wiggle.hrl").
--export([init/3,
- rest_init/2]).
-
--export([content_types_provided/2,
- content_types_accepted/2,
- allowed_methods/2,
- resource_exists/2,
- forbidden/2,
- options/2,
- service_available/2,
- is_authorized/2]).
-
--export([to_json/2,
- from_json/2,
- to_msgpack/2,
- from_msgpack/2]).
-
--ignore_xref([to_json/2,
- from_json/2,
- from_msgpack/2,
- to_msgpack/2,
- allowed_methods/2,
- content_types_accepted/2,
- content_types_provided/2,
- forbidden/2,
- init/3,
- is_authorized/2,
- service_available/2,
- options/2,
- resource_exists/2,
- rest_init/2]).
-
--record(state, {path, method, version, token, content, reply, obj, body}).
+-export([allowed_methods/3,
+ permission_required/1,
+ get/1,
+ handle_request/2]).
-init(_Transport, _Req, []) ->
- {upgrade, protocol, cowboy_rest}.
-
-rest_init(Req, _) ->
- wiggle_handler:initial_state(Req).
-
-service_available(Req, State = #state{path = [<<"connection">>]}) ->
- {true, Req, State};
-
-service_available(Req, State) ->
- case {libsniffle:servers(), libsnarl:servers()} of
- {[], _} ->
- {false, Req, State};
- {_, []} ->
- {false, Req, State};
- _ ->
- {true, Req, State}
- end.
-
-options(Req, State) ->
- Methods = allowed_methods(State#state.version, State#state.token, State#state.path),
- Req1 = cowboy_req:set_resp_header(
- <<"access-control-allow-methods">>,
- string:join(
- lists:map(fun erlang:binary_to_list/1,
- [<<"HEAD">>, <<"OPTIONS">> | Methods]), ", "), Req),
- {ok, Req1, State}.
-
-content_types_provided(Req, State) ->
- {[
- {<<"application/json">>, to_json},
- {<<"application/x-msgpack">>, to_msgpack}
- ], Req, State}.
-
-content_types_accepted(Req, State) ->
- {wiggle_handler:accepted(), Req, State}.
-
-allowed_methods(Req, State) ->
- {[<<"HEAD">>, <<"OPTIONS">> | allowed_methods(State#state.version, State#state.token, State#state.path)], Req, State}.
+-ignore_xref([allowed_methods/3,
+ permission_required/1,
+ get/1,
+ handle_request/2]).
allowed_methods(_Version, _Token, [<<"connection">>]) ->
[<<"GET">>];
@@ -85,51 +19,22 @@ allowed_methods(_Version, _Token, [<<"connection">>]) ->
allowed_methods(_Version, _Token, []) ->
[<<"GET">>].
-resource_exists(Req, State = #state{path = []}) ->
- {true, Req, State};
-
-resource_exists(Req, State = #state{path = [<<"connection">>]}) ->
- {true, Req, State}.
-
-is_authorized(Req, State = #state{method = <<"OPTIONS">>}) ->
- {true, Req, State};
-
-is_authorized(Req, State = #state{path = [<<"connection">>]}) ->
- {true, Req, State};
+get(_) ->
+ {ok, undefined}.
-is_authorized(Req, State = #state{token = undefined}) ->
- {{false, <<"x-snarl-token">>}, Req, State};
+permission_required(#state{path = [<<"connection">>]}) ->
+ {ok, always};
-is_authorized(Req, State) ->
- {true, Req, State}.
+permission_required(#state{path = []}) ->
+ {ok, [<<"cloud">>, <<"cloud">>, <<"status">>]};
-forbidden(Req, State = #state{method = <<"OPTIONS">>}) ->
- {false, Req, State};
-
-forbidden(Req, State = #state{path = [<<"connection">>]}) ->
- {false, Req, State};
-
-forbidden(Req, State = #state{token = undefined}) ->
- {true, Req, State};
-
-forbidden(Req, State = #state{path = []}) ->
- {allowed(State#state.token, [<<"cloud">>, <<"cloud">>, <<"status">>]), Req, State};
-
-forbidden(Req, State) ->
- {true, Req, State}.
+permission_required(_State) ->
+ undefined.
%%--------------------------------------------------------------------
%% GET
%%--------------------------------------------------------------------
-to_json(Req, State) ->
- {Reply, Req1, State1} = handle_request(Req, State),
- {jsx:encode(Reply), Req1, State1}.
-
-to_msgpack(Req, State) ->
- {Reply, Req1, State1} = handle_request(Req, State),
- {msgpack:pack(Reply, [jsx]), Req1, State1}.
-
handle_request(Req, State = #state{path = [<<"connection">>]}) ->
Res = jsxd:thread([{set, <<"sniffle">>, length(libsniffle:servers())},
{set, <<"snarl">>, length(libsnarl:servers())},
@@ -138,28 +43,40 @@ handle_request(Req, State = #state{path = [<<"connection">>]}) ->
{Res, Req, State};
handle_request(Req, State = #state{path = []}) ->
+ Start = now(),
case libsniffle:cloud_status() of
{ok, {Metrics, Warnings}} ->
+ ?MSniffle(?P(State), Start),
+ Start1 = now(),
Vers0 = case libsnarl:version() of
{ok, SrvVer} when is_binary(SrvVer) ->
[{snarl, SrvVer}];
_ ->
[{snarl, <<"not connected">>}]
end,
+ ?MSnarl(?P(State), Start1),
+ Start2 = now(),
Vers1 = case libsniffle:version() of
{ok, SrvVer1} when is_binary(SrvVer1) ->
[{sniffle, SrvVer1} | Vers0];
_ ->
[{sniffle, <<"not connected">>} | Vers0]
end,
+ ?MSniffle(?P(State), Start2),
+ Start3 = now(),
Vers2 = case libhowl:version() of
{ok, SrvVer2} when is_binary(SrvVer2) ->
[{howl, SrvVer2} | Vers1];
_ ->
[{howl, <<"not connected">>} | Vers1]
end,
+ ?MHowl(?P(State), Start3),
+ Start4 = now(),
{ok, Users} = libsnarl:user_list(),
+ ?MSnarl(?P(State), Start4),
+ Start5 = now(),
{ok, Vms} = libsniffle:vm_list(),
+ ?MSniffle(?P(State), Start5),
{[{versions, [{wiggle, ?VERSION} | Vers2]},
{metrics, [{<<"users">>, length(Users)},
{<<"vms">>, length(Vms)} |
@@ -168,28 +85,3 @@ handle_request(Req, State = #state{path = []}) ->
_ ->
{[{warnings, [{cloud, <<"down!">>}]}], Req, State}
end.
-
-
-%%--------------------------------------------------------------------
-%% PUT
-%%--------------------------------------------------------------------
-
-from_json(Req, State) ->
- {false, Req, State}.
-
-from_msgpack(Req, State) ->
- {false, Req, State}.
-
-%%--------------------------------------------------------------------
-%% DEETE
-%%--------------------------------------------------------------------
-
-allowed(Token, Perm) ->
- case libsnarl:allowed({token, Token}, Perm) of
- not_found ->
- true;
- true ->
- false;
- false ->
- true
- end.
229 apps/wiggle/src/wiggle_dataset_handler.erl
View
@@ -3,84 +3,24 @@
%% @doc Hello world handler.
-module(wiggle_dataset_handler).
--export([init/3,
- rest_init/2]).
-
--export([content_types_provided/2,
- content_types_accepted/2,
- allowed_methods/2,
- resource_exists/2,
- delete_resource/2,
- forbidden/2,
- options/2,
- post_is_create/2,
- create_path/2,
- service_available/2,
- is_authorized/2]).
-
--export([to_json/2,
- from_json/2,
- to_msgpack/2,
- from_msgpack/2]).
-
--ignore_xref([to_json/2,
- from_json/2,
- from_msgpack/2,
- to_msgpack/2,
- allowed_methods/2,
- content_types_accepted/2,
- content_types_provided/2,
- delete_resource/2,
- forbidden/2,
- init/3,
- post_is_create/2,
- create_path/2,
- is_authorized/2,
- options/2,
- service_available/2,
- resource_exists/2,
- rest_init/2]).
--record(state, {path, method, version, token, content, reply, obj, body}).
-
-init(_Transport, _Req, []) ->
- {upgrade, protocol, cowboy_rest}.
-
-rest_init(Req, _) ->
- wiggle_handler:initial_state(Req).
-
-service_available(Req, State) ->
- case {libsniffle:servers(), libsnarl:servers()} of
- {[], _} ->
- {false, Req, State};
- {_, []} ->
- {false, Req, State};
- _ ->
- {true, Req, State}
- end.
-
-options(Req, State) ->
- Methods = allowed_methods(State#state.version, State#state.token, State#state.path),
- Req1 = cowboy_req:set_resp_header(
- <<"access-control-allow-methods">>,
- string:join(
- lists:map(fun erlang:binary_to_list/1,
- [<<"HEAD">>, <<"OPTIONS">> | Methods]), ", "), Req),
- {ok, Req1, State}.
-
-post_is_create(Req, State) ->
- {true, Req, State}.
+-include("wiggle.hrl").
-content_types_provided(Req, State) ->
- {[
- {<<"application/json">>, to_json},
- {<<"application/x-msgpack">>, to_msgpack}
- ], Req, State}.
+-export([allowed_methods/3,
+ get/1,
+ permission_required/1,
+ handle_request/2,
+ create_path/3,
+ handle_write/3,
+ delete_resource/2]).
-content_types_accepted(Req, State) ->
- {wiggle_handler:accepted(), Req, State}.
+-ignore_xref([allowed_methods/3,
+ get/1,
+ permission_required/1,
+ handle_request/2,
+ create_path/3,
+ handle_write/3,
+ delete_resource/2]).
-allowed_methods(Req, State) ->
- {[<<"HEAD">>, <<"OPTIONS">> | allowed_methods(State#state.version, State#state.token, State#state.path)], Req, State}.
allowed_methods(_Version, _Token, []) ->
[<<"GET">>, <<"POST">>];
@@ -91,72 +31,47 @@ allowed_methods(_Version, _Token, [_Dataset]) ->
allowed_methods(_Version, _Token, [_Dataset, <<"metadata">>|_]) ->
[<<"PUT">>, <<"DELETE">>].
-resource_exists(Req, State = #state{path = []}) ->
- {true, Req, State};
+get(State = #state{path = [Dataset | _]}) ->
+ Start = now(),
+ R = libsniffle:dataset_get(Dataset),
+ ?MSniffle(?P(State), Start),
+ R.
-resource_exists(Req, State = #state{path = [Dataset | _]}) ->
- case libsniffle:dataset_get(Dataset) of
- not_found ->
- {false, Req, State};
- {ok, Obj} ->
- {true, Req, State#state{obj = Obj}}
- end.
+permission_required(#state{method = <<"POST">>, path = []}) ->
+ {ok, [<<"cloud">>, <<"datasets">>, <<"create">>]};
-is_authorized(Req, State = #state{method = <<"OPTIONS">>}) ->
- {true, Req, State};
-
-is_authorized(Req, State = #state{token = undefined}) ->
- {{false, <<"x-snarl-token">>}, Req, State};
-
-is_authorized(Req, State) ->
- {true, Req, State}.
-
-forbidden(Req, State = #state{method = <<"OPTIONS">>}) ->
- {false, Req, State};
-
-forbidden(Req, State = #state{token = undefined}) ->
- {true, Req, State};
+permission_required(#state{path = []}) ->
+ {ok, [<<"cloud">>, <<"datasets">>, <<"list">>]};
-forbidden(Req, State = #state{method = <<"POST">>, path = []}) ->
- {allowed(State#state.token, [<<"cloud">>, <<"datasets">>, <<"create">>]), Req, State};
+permission_required(#state{method = <<"GET">>, path = [Dataset]}) ->
+ {ok, [<<"datasets">>, Dataset, <<"get">>]};
-forbidden(Req, State = #state{path = []}) ->
- {allowed(State#state.token, [<<"cloud">>, <<"datasets">>, <<"list">>]), Req, State};
+permission_required(#state{method = <<"PUT">>, path = [Dataset]}) ->
+ {ok, [<<"datasets">>, Dataset, <<"edit">>]};
+permission_required(#state{method = <<"DELETE">>, path = [Dataset]}) ->
+ {ok, [<<"datasets">>, Dataset, <<"delete">>]};
-forbidden(Req, State = #state{method = <<"GET">>, path = [Dataset]}) ->
- {allowed(State#state.token, [<<"datasets">>, Dataset, <<"get">>]), Req, State};
+permission_required(#state{method = <<"PUT">>, path = [Dataset, <<"metadata">> | _]}) ->
+ {ok, [<<"datasets">>, Dataset, <<"edit">>]};
-forbidden(Req, State = #state{method = <<"PUT">>, path = [Dataset]}) ->
- {allowed(State#state.token, [<<"datasets">>, Dataset, <<"edit">>]), Req, State};
+permission_required(#state{method = <<"DELETE">>, path = [Dataset, <<"metadata">> | _]}) ->
+ {ok, [<<"datasets">>, Dataset, <<"edit">>]};
-forbidden(Req, State = #state{method = <<"DELETE">>, path = [Dataset]}) ->
- {allowed(State#state.token, [<<"datasets">>, Dataset, <<"delete">>]), Req, State};
-
-forbidden(Req, State = #state{method = <<"PUT">>, path = [Dataset, <<"metadata">> | _]}) ->
- {allowed(State#state.token, [<<"datasets">>, Dataset, <<"edit">>]), Req, State};
-
-forbidden(Req, State = #state{method = <<"DELETE">>, path = [Dataset, <<"metadata">> | _]}) ->
- {allowed(State#state.token, [<<"datasets">>, Dataset, <<"edit">>]), Req, State};
-
-forbidden(Req, State) ->
- {true, Req, State}.
+permission_required(_State) ->
+ undefined.
%%--------------------------------------------------------------------
%% GET
%%--------------------------------------------------------------------
-to_json(Req, State) ->
- {Reply, Req1, State1} = handle_request(Req, State),
- {jsx:encode(Reply), Req1, State1}.
-
-to_msgpack(Req, State) ->
- {Reply, Req1, State1} = handle_request(Req, State),
- {msgpack:pack(Reply, [jsx]), Req1, State1}.
-
handle_request(Req, State = #state{token = Token, path = []}) ->
+ Start = now(),
{ok, Permissions} = libsnarl:user_cache({token, Token}),
+ ?MSnarl(?P(State), Start),
+ Start1 = now(),
{ok, Res} = libsniffle:dataset_list([{must, 'allowed', [<<"datasets">>, {<<"res">>, <<"dataset">>}, <<"get">>], Permissions}]),
+ ?MSniffle(?P(State), Start1),
{lists:map(fun ({E, _}) -> E end, Res), Req, State};
handle_request(Req, State = #state{path = [_Dataset], obj = Obj}) ->
@@ -166,40 +81,32 @@ handle_request(Req, State = #state{path = [_Dataset], obj = Obj}) ->
%% PUT
%%--------------------------------------------------------------------
-create_path(Req, State = #state{path = [], version = Version}) ->
- {ok, Decoded, Req1} = wiggle_handler:decode(Req),
- {ok, URL} = jsxd:get(<<"url">>, Decoded),
- {ok, UUID} = libsniffle:dataset_import(URL),
- {<<"/api/", Version/binary, "/datasets/", UUID/binary>>, Req1, State#state{body = Decoded}}.
-
-from_json(Req, State) ->
- {ok, Body, Req1} = cowboy_req:body(Req),
- {Reply, Req2, State1} = case Body of
- <<>> ->
- handle_write(Req1, State, []);
- _ ->
- Decoded = jsx:decode(Body),
- handle_write(Req1, State, Decoded)
- end,
- {Reply, Req2, State1}.
-
-from_msgpack(Req, State) ->
- {ok, Body, Req1} = cowboy_req:body(Req),
- {Reply, Req2, State1} = case Body of
- <<>> ->
- handle_write(Req1, State, []);
- _ ->
- Decoded = msgpack:unpack(Body, [jsx]),
- handle_write(Req1, State, Decoded)
- end,
- {Reply, Req2, State1}.
+create_path(Req, State = #state{path = [], version = Version}, Decoded) ->
+ case jsxd:from_list(Decoded) of
+ [{<<"url">>, URL}] ->
+ Start = now(),
+ {ok, UUID} = libsniffle:dataset_import(URL),
+ ?MSniffle(?P(State), Start),
+ {<<"/api/", Version/binary, "/datasets/", UUID/binary>>, Req, State#state{body = Decoded}};
+ [{<<"config">>, Config},
+ {<<"snapshot">>, Snap},
+ {<<"vm">>, Vm}] ->
+ Start1 = now(),
+ {ok, UUID} = libsniffle:vm_promote_snapshot(Vm, Snap, Config),
+ ?MSniffle(?P(State), Start1),
+ {<<"/api/", Version/binary, "/datasets/", UUID/binary>>, Req, State#state{body = Decoded}}
+ end.
handle_write(Req, State = #state{path = [Dataset, <<"metadata">> | Path]}, [{K, V}]) ->
+ Start = now(),
libsniffle:dataset_set(Dataset, [<<"metadata">> | Path] ++ [K], jsxd:from_list(V)),
+ ?MSniffle(?P(State), Start),
{true, Req, State};
handle_write(Req, State = #state{path = [Dataset]}, [{K, V}]) ->
+ Start = now(),
libsniffle:dataset_set(Dataset, [K], jsxd:from_list(V)),
+ ?MSniffle(?P(State), Start),
{true, Req, State};
handle_write(Req, State = #state{path = []}, _Body) ->
@@ -213,23 +120,13 @@ handle_write(Req, State, _Body) ->
%%--------------------------------------------------------------------
delete_resource(Req, State = #state{path = [Dataset, <<"metadata">> | Path]}) ->
+ Start = now(),
libsniffle:dataset_set(Dataset, [<<"metadata">> | Path], delete),
+ ?MSniffle(?P(State), Start),
{true, Req, State};
delete_resource(Req, State = #state{path = [Dataset]}) ->
+ Start = now(),
ok = libsniffle:dataset_delete(Dataset),
+ ?MSniffle(?P(State), Start),
{true, Req, State}.
-
-%%--------------------------------------------------------------------
-%% Internal Functions
-%%--------------------------------------------------------------------
-
-allowed(Token, Perm) ->
- case libsnarl:allowed({token, Token}, Perm) of
- not_found ->
- true;
- true ->
- false;
- false ->
- true
- end.
229 apps/wiggle/src/wiggle_dtrace_handler.erl
View
@@ -1,87 +1,21 @@
-%% Feel free to use, reuse and abuse the code in this file.
-
-%% @doc Hello world handler.
-module(wiggle_dtrace_handler).
-
--export([init/3,
- rest_init/2]).
-
--export([content_types_provided/2,
- content_types_accepted/2,
- allowed_methods/2,
- resource_exists/2,
- service_available/2,
- delete_resource/2,
- forbidden/2,
- options/2,
- create_path/2,
- post_is_create/2,
- is_authorized/2]).
-
--export([to_json/2,
- from_json/2,
- to_msgpack/2,
- from_msgpack/2]).
-
--ignore_xref([to_json/2,
- from_json/2,
- from_msgpack/2,
- to_msgpack/2,
- allowed_methods/2,
- content_types_accepted/2,
- content_types_provided/2,
- delete_resource/2,
- forbidden/2,
- init/3,
- is_authorized/2,
- options/2,
- service_available/2,
- resource_exists/2,
- create_path/2,
- post_is_create/2,
- rest_init/2]).
-
--record(state, {path, method, version, token, content, reply, obj, body}).
-
-init(_Transport, _Req, []) ->
- {upgrade, protocol, cowboy_rest}.
-
-rest_init(Req, _) ->
- wiggle_handler:initial_state(Req).
-
-post_is_create(Req, State) ->
- {true, Req, State}.
-
-service_available(Req, State) ->
- case {libsniffle:servers(), libsnarl:servers()} of
- {[], _} ->
- {false, Req, State};
- {_, []} ->
- {false, Req, State};
- _ ->
- {true, Req, State}
- end.
-
-options(Req, State) ->
- Methods = allowed_methods(State#state.version, State#state.token, State#state.path),
- Req1 = cowboy_req:set_resp_header(
- <<"access-control-allow-methods">>,
- string:join(
- lists:map(fun erlang:binary_to_list/1,
- [<<"HEAD">>, <<"OPTIONS">> | Methods]), ", "), Req),
- {ok, Req1, State}.
-
-content_types_provided(Req, State) ->
- {[
- {<<"application/json">>, to_json},
- {<<"application/x-msgpack">>, to_msgpack}
- ], Req, State}.
-
-content_types_accepted(Req, State) ->
- {wiggle_handler:accepted(), Req, State}.
-
-allowed_methods(Req, State) ->
- {[<<"HEAD">>, <<"OPTIONS">> | allowed_methods(State#state.version, State#state.token, State#state.path)], Req, State}.
+-include("wiggle.hrl").
+
+-export([allowed_methods/3,
+ get/1,
+ permission_required/1,
+ handle_request/2,
+ create_path/3,
+ handle_write/3,
+ delete_resource/2]).
+
+-ignore_xref([allowed_methods/3,
+ get/1,
+ permission_required/1,
+ handle_request/2,
+ create_path/3,
+ handle_write/3,
+ delete_resource/2]).
allowed_methods(_Version, _Token, []) ->
[<<"GET">>, <<"POST">>];
@@ -92,71 +26,47 @@ allowed_methods(_Version, _Token, [_Dtrace, <<"metadata">>|_]) ->
allowed_methods(_Version, _Token, [_Dtrace]) ->
[<<"GET">>, <<"PUT">>, <<"DELETE">>].
-resource_exists(Req, State = #state{path = []}) ->
- {true, Req, State};
-
-resource_exists(Req, State = #state{path = [Dtrace | _]}) ->
- case libsniffle:dtrace_get(Dtrace) of
- not_found ->
- {false, Req, State};
- {ok, Obj} ->
- {true, Req, State#state{obj = Obj}}
- end.
-
-is_authorized(Req, State = #state{method = <<"OPTIONS">>}) ->
- {true, Req, State};
-
-is_authorized(Req, State = #state{token = undefined}) ->
- {{false, <<"x-snarl-token">>}, Req, State};
-
-is_authorized(Req, State) ->
- {true, Req, State}.
+get(State = #state{path = [Dtrace | _]}) ->
+ Start = now(),
+ R = libsniffle:dtrace_get(Dtrace),
+ ?MSniffle(?P(State), Start),
+ R.
-forbidden(Req, State = #state{method = <<"OPTIONS">>}) ->
- {false, Req, State};
+permission_required(#state{method= <<"GET">>, path = []}) ->
+ {ok, [<<"cloud">>, <<"dtraces">>, <<"list">>]};
-forbidden(Req, State = #state{token = undefined}) ->
- {true, Req, State};
+permission_required(#state{method= <<"POST">>, path = []}) ->
+ {ok, [<<"cloud">>, <<"dtraces">>, <<"create">>]};
-forbidden(Req, State = #state{method= <<"GET">>, path = []}) ->
- {allowed(State#state.token, [<<"cloud">>, <<"dtraces">>, <<"list">>]), Req, State};
+permission_required(#state{method = <<"GET">>, path = [Dtrace]}) ->
+ {ok, [<<"dtraces">>, Dtrace, <<"get">>]};
-forbidden(Req, State = #state{method= <<"POST">>, path = []}) ->
- {allowed(State#state.token, [<<"cloud">>, <<"dtraces">>, <<"create">>]), Req, State};
+permission_required(#state{method = <<"DELETE">>, path = [Dtrace]}) ->
+ {ok, [<<"dtraces">>, Dtrace, <<"delete">>]};
-forbidden(Req, State = #state{method = <<"GET">>, path = [Dtrace]}) ->
- {allowed(State#state.token, [<<"dtraces">>, Dtrace, <<"get">>]), Req, State};
+permission_required(#state{method = <<"PUT">>, path = [Dtrace]}) ->
+ {ok, [<<"dtraces">>, Dtrace, <<"edit">>]};
-forbidden(Req, State = #state{method = <<"DELETE">>, path = [Dtrace]}) ->
- {allowed(State#state.token, [<<"dtraces">>, Dtrace, <<"delete">>]), Req, State};
+permission_required(#state{method = <<"PUT">>, path = [Dtrace, <<"metadata">> | _]}) ->
+ {ok, [<<"dtraces">>, Dtrace, <<"edit">>]};
-forbidden(Req, State = #state{method = <<"PUT">>, path = [Dtrace]}) ->
- {allowed(State#state.token, [<<"dtraces">>, Dtrace, <<"edit">>]), Req, State};
+permission_required(#state{method = <<"DELETE">>, path = [Dtrace, <<"metadata">> | _]}) ->
+ {ok, [<<"dtraces">>, Dtrace, <<"edit">>]};
-forbidden(Req, State = #state{method = <<"PUT">>, path = [Dtrace, <<"metadata">> | _]}) ->
- {allowed(State#state.token, [<<"dtraces">>, Dtrace, <<"edit">>]), Req, State};
-
-forbidden(Req, State = #state{method = <<"DELETE">>, path = [Dtrace, <<"metadata">> | _]}) ->
- {allowed(State#state.token, [<<"dtraces">>, Dtrace, <<"edit">>]), Req, State};
-
-forbidden(Req, State) ->
- {true, Req, State}.
+permission_required(_State) ->
+ undefined.
%%--------------------------------------------------------------------
%% GET
%%--------------------------------------------------------------------
-to_json(Req, State) ->
- {Reply, Req1, State1} = handle_request(Req, State),
- {jsx:encode(Reply), Req1, State1}.
-
-to_msgpack(Req, State) ->
- {Reply, Req1, State1} = handle_request(Req, State),
- {msgpack:pack(Reply, [jsx]), Req1, State1}.
-
handle_request(Req, State = #state{token = Token, path = []}) ->
+ Start = now(),
{ok, Permissions} = libsnarl:user_cache({token, Token}),
+ ?MSnarl(?P(State), Start),
+ Start1 = now(),
{ok, Res} = libsniffle:dtrace_list([{must, 'allowed', [<<"dtraces">>, {<<"res">>, <<"uuid">>}, <<"get">>], Permissions}]),
+ ?MSniffle(?P(State), Start1),
{lists:map(fun ({E, _}) -> E end, Res), Req, State};
handle_request(Req, State = #state{path = [_Dtrace], obj = Obj}) ->
@@ -165,59 +75,40 @@ handle_request(Req, State = #state{path = [_Dtrace], obj = Obj}) ->
end, Obj),
{Obj1, Req, State}.
-
%%--------------------------------------------------------------------
%% PUT
%%--------------------------------------------------------------------
-create_path(Req, State = #state{path = [], version = Version}) ->
- {ok, Data, Req1} = wiggle_handler:decode(Req),
+create_path(Req, State = #state{path = [], version = Version}, Data) ->
{ok, Dtrace} = jsxd:get(<<"name">>, Data),
{ok, Script} = jsxd:get(<<"script">>, Data),
Script1 = binary_to_list(Script),
+ Start = now(),
case libsniffle:dtrace_add(Dtrace, Script1) of
{ok, UUID} ->
+ ?MSniffle(?P(State), Start),
case jsxd:get(<<"config">>, Data) of
{ok, Config} ->
- ok = libsniffle:dtrace_set(UUID, <<"config">>, Config);
+ Start1 = now(),
+ ok = libsniffle:dtrace_set(UUID, <<"config">>, Config),
+ ?MSniffle(?P(State), Start1);
_ ->
ok
end,
- {<<"/api/", Version/binary, "/dtrace/", UUID/binary>>, Req1, State#state{body = Data}};
+ {<<"/api/", Version/binary, "/dtrace/", UUID/binary>>, Req, State#state{body = Data}};
duplicate ->
- {ok, Req3} = cowboy_req:reply(409, Req1),
- {halt, Req3, State}
+ {ok, Req1} = cowboy_req:reply(409, Req),
+ {halt, Req1, State}
end.
-from_json(Req, State) ->
- {ok, Body, Req1} = cowboy_req:body(Req),
- {Reply, Req2, State1} = case Body of
- <<>> ->
- handle_write(Req1, State, null);
- _ ->
- Decoded = jsx:decode(Body),
- handle_write(Req1, State, Decoded)
- end,
- {Reply, Req2, State1}.
-
-from_msgpack(Req, State) ->
- {ok, Body, Req1} = cowboy_req:body(Req),
- {Reply, Req2, State1} = case Body of
- <<>> ->
- handle_write(Req1, State, null);
- _ ->
- Decoded = msgpack:unpack(Body, [jsx]),
- handle_write(Req1, State, Decoded)
- end,
- {Reply, Req2, State1}.
-
%% TODO : This is a icky case it is called after post.
-
handle_write(Req, State = #state{method = <<"POST">>, path = []}, _) ->
{true, Req, State};
handle_write(Req, State = #state{path = [Dtrace, <<"metadata">> | Path]}, [{K, V}]) ->
+ Start = now(),
libsniffle:dtrace_set(Dtrace, [<<"metadata">> | Path] ++ [K], jsxd:from_list(V)),
+ ?MSniffle(?P(State), Start),
{true, Req, State};
handle_write(Req, State, _Body) ->
@@ -228,19 +119,13 @@ handle_write(Req, State, _Body) ->
%%--------------------------------------------------------------------
delete_resource(Req, State = #state{path = [Dtrace, <<"metadata">> | Path]}) ->
+ Start = now(),
libsniffle:dtrace_set(Dtrace, [<<"metadata">> | Path], delete),
+ ?MSniffle(?P(State), Start),
{true, Req, State};
delete_resource(Req, State = #state{path = [Dtrace]}) ->
+ Start = now(),
ok = libsniffle:dtrace_delete(Dtrace),
+ ?MSniffle(?P(State), Start),
{true, Req, State}.
-
-allowed(Token, Perm) ->
- case libsnarl:allowed({token, Token}, Perm) of
- not_found ->
- true;
- true ->
- false;
- false ->
- true
- end.
259 apps/wiggle/src/wiggle_group_handler.erl
View
@@ -1,89 +1,25 @@
-%% Feel free to use, reuse and abuse the code in this file.
-
-%% @doc Hello world handler.
-module(wiggle_group_handler).
+-include("wiggle.hrl").
-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").
-endif.
--export([init/3,
- rest_init/2]).
--export([content_types_provided/2,
- content_types_accepted/2,
- allowed_methods/2,
- delete_resource/2,
- resource_exists/2,
- forbidden/2,
- service_available/2,
- options/2,
- create_path/2,
- post_is_create/2,
- is_authorized/2]).
-
--export([to_json/2,
- from_json/2,
- to_msgpack/2,
- from_msgpack/2]).
-
--ignore_xref([to_json/2,
- from_json/2,
- from_msgpack/2,
- to_msgpack/2,
- allowed_methods/2,
- content_types_accepted/2,
- content_types_provided/2,
- delete_resource/2,
- forbidden/2,
- init/3,
- is_authorized/2,
- service_available/2,
- options/2,
- create_path/2,
- post_is_create/2,
- resource_exists/2,
- rest_init/2]).
-
--record(state, {path, method, version, token, content, reply, obj, body}).
-
-init(_Transport, _Req, []) ->
- {upgrade, protocol, cowboy_rest}.
-
-rest_init(Req, _) ->
- wiggle_handler:initial_state(Req).
-
-post_is_create(Req, State) ->
- {true, Req, State}.
-
-service_available(Req, State) ->
- case libsnarl:servers() of
- [] ->
- {false, Req, State};
- _ ->
- {true, Req, State}
- end.
-
-options(Req, State) ->
- Methods = allowed_methods(State#state.version, State#state.token, State#state.path),
- Req1 = cowboy_req:set_resp_header(
- <<"access-control-allow-methods">>,
- string:join(
- lists:map(fun erlang:binary_to_list/1,
- [<<"HEAD">>, <<"OPTIONS">> | Methods]), ", "), Req),
- {ok, Req1, State}.
-
-
-content_types_provided(Req, State) ->
- {[
- {<<"application/json">>, to_json},
- {<<"application/x-msgpack">>, to_msgpack}
- ], Req, State}.
-
-content_types_accepted(Req, State) ->
- {wiggle_handler:accepted(), Req, State}.
-
-allowed_methods(Req, State) ->
- {[<<"HEAD">>, <<"OPTIONS">> | allowed_methods(State#state.version, State#state.token, State#state.path)], Req, State}.
+-export([allowed_methods/3,
+ get/1,
+ permission_required/1,
+ handle_request/2,
+ create_path/3,
+ handle_write/3,
+ delete_resource/2]).
+
+-ignore_xref([allowed_methods/3,
+ get/1,
+ permission_required/1,
+ handle_request/2,
+ create_path/3,
+ handle_write/3,
+ delete_resource/2]).
allowed_methods(_Version, _Token, []) ->
[<<"GET">>, <<"POST">>];
@@ -100,100 +36,72 @@ allowed_methods(_Version, _Token, [_Group, <<"metadata">> | _]) ->
allowed_methods(_Version, _Token, [_Group, <<"permissions">> | _Permission]) ->
[<<"PUT">>, <<"DELETE">>].
-resource_exists(Req, State = #state{path = [Group, <<"permissions">> | Permission]}) ->
- case {erlangify_permission(Permission), libsnarl:group_get(Group)} of
+get(State = #state{path = [Group, <<"permissions">> | Permission]}) ->
+ case {erlangify_permission(Permission), wiggle_group_handler:get(State#state{path = [Group]})} of
{_, not_found} ->
- {false, Req, State};
+ not_found;
{[], {ok, Obj}} ->
- {true, Req, State#state{obj=Obj}};
+ {ok, Obj};
{P, {ok, Obj}} ->
- {lists:member(P, jsxd:get(<<"permissions">>, [], Obj)), Req, State#state{obj=Obj}}
+ case lists:member(P, jsxd:get(<<"permissions">>, [], Obj)) of
+ true ->
+ {ok, Obj};
+ _ -> not_found
+ end
end;
-resource_exists(Req, State = #state{path = []}) ->
- {true, Req, State};
+get(State = #state{path = [Group | _]}) ->
+ Start = now(),
+ R = libsnarl:group_get(Group),
+ ?MSnarl(?P(State), Start),
+ R.
-resource_exists(Req, State = #state{path = [Group | _]}) ->
- case libsnarl:group_get(Group) of
- not_found ->
- {false, Req, State};
- {ok, Obj} ->
- {true, Req, State#state{obj=Obj}}
- end.
+permission_required(#state{method = <<"GET">>, path = []}) ->
+ {ok, [<<"cloud">>, <<"groups">>, <<"list">>]};
-is_authorized(Req, State = #state{path = [_, <<"sessions">>]}) ->
- {true, Req, State};
+permission_required(#state{method = <<"POST">>, path = []}) ->
+ {ok, [<<"cloud">>, <<"groups">>, <<"create">>]};
-is_authorized(Req, State = #state{method = <<"OPTIONS">>}) ->
- {true, Req, State};
+permission_required(#state{method = <<"GET">>, path = [Group]}) ->
+ {ok, [<<"groups">>, Group, <<"get">>]};
-is_authorized(Req, State = #state{token = undefined}) ->
- {{false, <<"x-snarl-token">>}, Req, State};
+permission_required(#state{method = <<"PUT">>, path = [Group]}) ->
+ {ok, [<<"groups">>, Group, <<"create">>]};
-is_authorized(Req, State) ->
- {true, Req, State}.
-
-forbidden(Req, State = #state{path = [_, <<"sessions">>]}) ->
- {false, Req, State};
+permission_required(#state{method = <<"DELETE">>, path = [Group]}) ->
+ {ok, [<<"groups">>, Group, <<"delete">>]};
-forbidden(Req, State = #state{method = <<"OPTIONS">>}) ->
- {false, Req, State};
+permission_required(#state{method = <<"GET">>, path = [Group, <<"permissions">>]}) ->
+ {ok, [<<"groups">>, Group, <<"get">>]};
-forbidden(Req, State = #state{token = undefined}) ->
- {true, Req, State};
-
-forbidden(Req, State = #state{method = <<"GET">>, path = []}) ->
- {allowed(State#state.token, [<<"cloud">>, <<"groups">>, <<"list">>]), Req, State};
-
-forbidden(Req, State = #state{method = <<"POST">>, path = []}) ->
- {allowed(State#state.token, [<<"cloud">>, <<"groups">>, <<"create">>]), Req, State};
-
-forbidden(Req, State = #state{method = <<"GET">>, path = [Group]}) ->
- {allowed(State#state.token, [<<"groups">>, Group, <<"get">>]), Req, State};
-
-forbidden(Req, State = #state{method = <<"PUT">>, path = [Group]}) ->
- {allowed(State#state.token, [<<"groups">>, Group, <<"create">>]), Req, State};
-
-forbidden(Req, State = #state{method = <<"DELETE">>, path = [Group]}) ->
- {allowed(State#state.token, [<<"groups">>, Group, <<"delete">>]), Req, State};
-
-forbidden(Req, State = #state{method = <<"GET">>, path = [Group, <<"permissions">>]}) ->
- {allowed(State#state.token, [<<"groups">>, Group, <<"get">>]), Req, State};
-
-forbidden(Req, State = #state{method = <<"PUT">>, path = [Group, <<"permissions">> | Permission]}) ->
+permission_required(#state{method = <<"PUT">>, path = [Group, <<"permissions">> | Permission]}) ->
P = erlangify_permission(Permission),
- {allowed(State#state.token, [<<"groups">>, Group, <<"grant">>])
- andalso allowed(State#state.token, [<<"permissions">>, P, <<"grant">>]), Req, State};
+ {multiple, [[<<"groups">>, Group, <<"grant">>],
+ [<<"permissions">>, P, <<"revoke">>]]};
-forbidden(Req, State = #state{method = <<"DELETE">>, path = [Group, <<"permissions">> | Permission]}) ->
+permission_required(#state{method = <<"DELETE">>, path = [Group, <<"permissions">> | Permission]}) ->
P = erlangify_permission(Permission),
- {allowed(State#state.token, [<<"groups">>, Group, <<"revoke">>])
- andalso allowed(State#state.token, [<<"permissions">>, P, <<"revoke">>]), Req, State};
+ {multiple, [[<<"groups">>, Group, <<"revoke">>],
+ [<<"permissions">>, P, <<"revoke">>]]};
-forbidden(Req, State = #state{method = <<"PUT">>, path = [Group, <<"metadata">> | _]}) ->
- {allowed(State#state.token, [<<"groups">>, Group, <<"edit">>]), Req, State};
+permission_required(#state{method = <<"PUT">>, path = [Group, <<"metadata">> | _]}) ->
+ {ok, [<<"groups">>, Group, <<"edit">>]};
-forbidden(Req, State = #state{method = <<"DELETE">>, path = [Group, <<"metadata">> | _]}) ->
- {allowed(State#state.token, [<<"groups">>, Group, <<"edit">>]), Req, State};
+permission_required(#state{method = <<"DELETE">>, path = [Group, <<"metadata">> | _]}) ->
+ {ok, [<<"groups">>, Group, <<"edit">>]};
-forbidden(Req, State) ->
- {true, Req, State}.
+permission_required(_State) ->
+ undefined.
%%--------------------------------------------------------------------
%% GET
%%--------------------------------------------------------------------
-to_json(Req, State) ->
- {Reply, Req1, State1} = handle_request(Req, State),
- {jsx:encode(Reply), Req1, State1}.
-
-to_msgpack(Req, State) ->
- {Reply, Req1, State1} = handle_request(Req, State),
- {msgpack:pack(Reply, [jsx]), Req1, State1}.
-
handle_request(Req, State = #state{path = []}) ->
- % {ok, Permissions} = libsnarl:user_cache({token, Token}),
+ Start = now(),
+ %% {ok, Permissions} = libsnarl:user_cache({token, Token}),
{ok, Res} = libsnarl:group_list(), %{must, 'allowed', [<<"vm">>, {<<"res">>, <<"uuid">>}, <<"get">>], Permissions}),
+ ?MSnarl(?P(State), Start),
{Res, Req, State};
handle_request(Req, State = #state{path = [_Group], obj = GroupObj}) ->
@@ -210,67 +118,57 @@ handle_request(Req, State = #state{path = [_Group, <<"permissions">>], obj = Gro
%% PUT
%%--------------------------------------------------------------------
-create_path(Req, State = #state{path = [], version = Version}) ->
- {ok, Decoded, Req1} = wiggle_handler:decode(Req),
+create_path(Req, State = #state{path = [], version = Version}, Decoded) ->
{ok, Group} = jsxd:get(<<"name">>, Decoded),
+ Start = now(),
{ok, UUID} = libsnarl:group_add(Group),
- {<<"/api/", Version/binary, "/groups/", UUID/binary>>, Req1, State#state{body = Decoded}}.
-
-from_json(Req, State) ->
- {ok, Body, Req1} = cowboy_req:body(Req),
- {Reply, Req2, State1} = case Body of
- <<>> ->
- handle_write(Req1, State, []);
- _ ->
- Decoded = jsx:decode(Body),
- handle_write(Req1, State, Decoded)
- end,
- {Reply, Req2, State1}.
-
-from_msgpack(Req, State) ->
- {ok, Body, Req1} = cowboy_req:body(Req),
- {Reply, Req2, State1} = case Body of
- <<>> ->
- handle_write(Req1, State, []);
- _ ->
- Decoded = msgpack:unpack(Body, [jsx]),
- handle_write(Req1, State, Decoded)
- end,
- {Reply, Req2, State1}.
+ ?MSnarl(?P(State), Start),
+ {<<"/api/", Version/binary, "/groups/", UUID/binary>>, Req, State#state{body = Decoded}}.
%% TODO : This is a icky case it is called after post.
handle_write(Req, State = #state{method = <<"POST">>, path = []}, _) ->
{true, Req, State};
handle_write(Req, State = #state{path = [Group, <<"metadata">> | Path]}, [{K, V}]) ->
+ Start = now(),
libsnarl:group_set(Group, [<<"metadata">> | Path] ++ [K], jsxd:from_list(V)),
+ ?MSnarl(?P(State), Start),
{true, Req, State};
handle_write(Req, State = #state{path = [Group]}, _Body) ->
+ Start = now(),
ok = libsnarl:group_add(Group),
+ ?MSnarl(?P(State), Start),
{true, Req, State};
handle_write(Req, State = #state{path = [Group, <<"permissions">> | Permission]}, _Body) ->
P = erlangify_permission(Permission),
+ Start = now(),
ok = libsnarl:group_grant(Group, P),
+ ?MSnarl(?P(State), Start),
{true, Req, State}.
-
%%--------------------------------------------------------------------
%% DEETE
%%--------------------------------------------------------------------
delete_resource(Req, State = #state{path = [Group, <<"metadata">> | Path]}) ->
+ Start = now(),
libsnarl:group_set(Group, [<<"metadata">> | Path], delete),
+ ?MSnarl(?P(State), Start),
{true, Req, State};
delete_resource(Req, State = #state{path = [Group, <<"permissions">> | Permission]}) ->
P = erlangify_permission(Permission),
+ Start = now(),
ok = libsnarl:group_revoke(Group, P),
+ ?MSnarl(?P(State), Start),
{true, Req, State};
delete_resource(Req, State = #state{path = [Group]}) ->
+ Start = now(),
ok = libsnarl:group_delete(Group),
+ ?MSnarl(?P(State), Start),
{true, Req, State}.
%% Internal Functions
@@ -279,6 +177,7 @@ erlangify_permission(P) ->
lists:map(fun(E) ->
E
end, P).
+
jsonify_permissions(P) ->
lists:map(fun('...') ->
<<"...">>;
@@ -289,16 +188,6 @@ jsonify_permissions(P) ->
end, P).
-allowed(Token, Perm) ->
- case libsnarl:allowed({token, Token}, Perm) of
- not_found ->
- true;
- true ->
- false;
- false ->
- true
- end.
-
-ifdef(TEST).
jsonify_permission_test() ->
68 apps/wiggle/src/wiggle_handler.erl
View
@@ -1,28 +1,34 @@
-module(wiggle_handler).
+-include("wiggle.hrl").
+
-export([
initial_state/1,
+ provided/0,
accepted/0,
decode/1,
get_token/1,
- set_access_header/1
+ set_access_header/1,
+ allowed/2,
+ options/3,
+ service_available/0
]).
-
-
--record(state, {path, method, version, token, content, reply, obj, body}).
-
initial_state(Req) ->
{Method, Req0} = cowboy_req:method(Req),
{Version, Req1} = cowboy_req:binding(version, Req0),
{Path, Req2} = cowboy_req:path_info(Req1),
{Token, Req3} = get_token(Req2),
- io:format("[~p] - ~p~n", [Method, Path]),
- State = #state{version = Version,
- method = Method,
- token = Token,
- path = Path},
- {ok, set_access_header(Req3), State}.
+ {PathB, Req4} = cowboy_req:path(Req3),
+ State = #state{
+ version = Version,
+ method = Method,
+ token = Token,
+ path = Path,