diff --git a/.gitbook/assets/Screen Shot 2020-11-29 at 4.25.44 PM.png b/.gitbook/assets/Screen Shot 2020-11-29 at 4.25.44 PM.png new file mode 100644 index 0000000..a9cca39 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2020-11-29 at 4.25.44 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-02-07 at 2.42.10 PM.png b/.gitbook/assets/Screen Shot 2021-02-07 at 2.42.10 PM.png new file mode 100644 index 0000000..89e0257 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-02-07 at 2.42.10 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-03-28 at 1.25.04 PM.png b/.gitbook/assets/Screen Shot 2021-03-28 at 1.25.04 PM.png new file mode 100644 index 0000000..fe34de5 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-03-28 at 1.25.04 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-03-28 at 1.32.36 PM.png b/.gitbook/assets/Screen Shot 2021-03-28 at 1.32.36 PM.png new file mode 100644 index 0000000..abce94e Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-03-28 at 1.32.36 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-03-28 at 1.39.40 PM.png b/.gitbook/assets/Screen Shot 2021-03-28 at 1.39.40 PM.png new file mode 100644 index 0000000..a39ca42 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-03-28 at 1.39.40 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-03-28 at 12.49.50 PM.png b/.gitbook/assets/Screen Shot 2021-03-28 at 12.49.50 PM.png new file mode 100644 index 0000000..36db39f Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-03-28 at 12.49.50 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-03-28 at 12.50.28 PM.png b/.gitbook/assets/Screen Shot 2021-03-28 at 12.50.28 PM.png new file mode 100644 index 0000000..348ad60 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-03-28 at 12.50.28 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-03-28 at 4.40.46 PM.png b/.gitbook/assets/Screen Shot 2021-03-28 at 4.40.46 PM.png new file mode 100644 index 0000000..fdd099e Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-03-28 at 4.40.46 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-03-28 at 4.44.28 PM.png b/.gitbook/assets/Screen Shot 2021-03-28 at 4.44.28 PM.png new file mode 100644 index 0000000..be5afbc Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-03-28 at 4.44.28 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-03-28 at 4.48.02 PM.png b/.gitbook/assets/Screen Shot 2021-03-28 at 4.48.02 PM.png new file mode 100644 index 0000000..b1c338d Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-03-28 at 4.48.02 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-03-28 at 4.53.55 PM.png b/.gitbook/assets/Screen Shot 2021-03-28 at 4.53.55 PM.png new file mode 100644 index 0000000..33929c6 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-03-28 at 4.53.55 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-03-28 at 5.24.34 PM.png b/.gitbook/assets/Screen Shot 2021-03-28 at 5.24.34 PM.png new file mode 100644 index 0000000..dddf45c Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-03-28 at 5.24.34 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-03-28 at 5.38.28 PM.png b/.gitbook/assets/Screen Shot 2021-03-28 at 5.38.28 PM.png new file mode 100644 index 0000000..808531f Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-03-28 at 5.38.28 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-03-28 at 5.40.35 PM.png b/.gitbook/assets/Screen Shot 2021-03-28 at 5.40.35 PM.png new file mode 100644 index 0000000..5a9ba99 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-03-28 at 5.40.35 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-03-29 at 9.07.55 AM.png b/.gitbook/assets/Screen Shot 2021-03-29 at 9.07.55 AM.png new file mode 100644 index 0000000..0a76cd3 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-03-29 at 9.07.55 AM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-03-29 at 9.23.14 AM.png b/.gitbook/assets/Screen Shot 2021-03-29 at 9.23.14 AM.png new file mode 100644 index 0000000..550e529 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-03-29 at 9.23.14 AM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-04-25 at 2.31.58 PM.png b/.gitbook/assets/Screen Shot 2021-04-25 at 2.31.58 PM.png new file mode 100644 index 0000000..a061b95 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-04-25 at 2.31.58 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-04-25 at 2.38.51 PM.png b/.gitbook/assets/Screen Shot 2021-04-25 at 2.38.51 PM.png new file mode 100644 index 0000000..5c01448 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-04-25 at 2.38.51 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-04-25 at 2.39.11 PM.png b/.gitbook/assets/Screen Shot 2021-04-25 at 2.39.11 PM.png new file mode 100644 index 0000000..9fca727 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-04-25 at 2.39.11 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-04-25 at 2.45.19 PM.png b/.gitbook/assets/Screen Shot 2021-04-25 at 2.45.19 PM.png new file mode 100644 index 0000000..90fa66c Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-04-25 at 2.45.19 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-04-25 at 2.52.34 PM.png b/.gitbook/assets/Screen Shot 2021-04-25 at 2.52.34 PM.png new file mode 100644 index 0000000..a1b00b5 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-04-25 at 2.52.34 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-04-25 at 2.54.30 PM.png b/.gitbook/assets/Screen Shot 2021-04-25 at 2.54.30 PM.png new file mode 100644 index 0000000..2f4bfc1 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-04-25 at 2.54.30 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-04-25 at 2.55.26 PM.png b/.gitbook/assets/Screen Shot 2021-04-25 at 2.55.26 PM.png new file mode 100644 index 0000000..e16bf3b Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-04-25 at 2.55.26 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-04-25 at 2.59.35 PM.png b/.gitbook/assets/Screen Shot 2021-04-25 at 2.59.35 PM.png new file mode 100644 index 0000000..4e3a1b6 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-04-25 at 2.59.35 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-04-25 at 3.04.50 PM.png b/.gitbook/assets/Screen Shot 2021-04-25 at 3.04.50 PM.png new file mode 100644 index 0000000..19ee8b5 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-04-25 at 3.04.50 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-04-25 at 3.07.54 PM.png b/.gitbook/assets/Screen Shot 2021-04-25 at 3.07.54 PM.png new file mode 100644 index 0000000..54f79d6 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-04-25 at 3.07.54 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-05-11 at 3.59.32 PM.png b/.gitbook/assets/Screen Shot 2021-05-11 at 3.59.32 PM.png new file mode 100644 index 0000000..9dfb9b0 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-05-11 at 3.59.32 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-05-11 at 4.04.24 PM.png b/.gitbook/assets/Screen Shot 2021-05-11 at 4.04.24 PM.png new file mode 100644 index 0000000..bea1dba Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-05-11 at 4.04.24 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-05-11 at 4.05.00 PM.png b/.gitbook/assets/Screen Shot 2021-05-11 at 4.05.00 PM.png new file mode 100644 index 0000000..6008e18 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-05-11 at 4.05.00 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-05-11 at 4.06.43 PM.png b/.gitbook/assets/Screen Shot 2021-05-11 at 4.06.43 PM.png new file mode 100644 index 0000000..02fffc7 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-05-11 at 4.06.43 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-05-11 at 4.09.35 PM.png b/.gitbook/assets/Screen Shot 2021-05-11 at 4.09.35 PM.png new file mode 100644 index 0000000..af5df26 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-05-11 at 4.09.35 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-05-11 at 4.11.26 PM.png b/.gitbook/assets/Screen Shot 2021-05-11 at 4.11.26 PM.png new file mode 100644 index 0000000..35a8644 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-05-11 at 4.11.26 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-05-11 at 4.19.21 PM.png b/.gitbook/assets/Screen Shot 2021-05-11 at 4.19.21 PM.png new file mode 100644 index 0000000..4f793ae Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-05-11 at 4.19.21 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-05-11 at 4.23.15 PM.png b/.gitbook/assets/Screen Shot 2021-05-11 at 4.23.15 PM.png new file mode 100644 index 0000000..b8cf6e4 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-05-11 at 4.23.15 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-05-11 at 4.24.04 PM.png b/.gitbook/assets/Screen Shot 2021-05-11 at 4.24.04 PM.png new file mode 100644 index 0000000..f9b98cd Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-05-11 at 4.24.04 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-05-11 at 6.35.43 PM.png b/.gitbook/assets/Screen Shot 2021-05-11 at 6.35.43 PM.png new file mode 100644 index 0000000..098f3aa Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-05-11 at 6.35.43 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-05-11 at 6.42.28 PM.png b/.gitbook/assets/Screen Shot 2021-05-11 at 6.42.28 PM.png new file mode 100644 index 0000000..16b8bf9 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-05-11 at 6.42.28 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-05-11 at 6.48.25 PM.png b/.gitbook/assets/Screen Shot 2021-05-11 at 6.48.25 PM.png new file mode 100644 index 0000000..df21f88 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-05-11 at 6.48.25 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-05-11 at 6.52.04 PM.png b/.gitbook/assets/Screen Shot 2021-05-11 at 6.52.04 PM.png new file mode 100644 index 0000000..4ef718c Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-05-11 at 6.52.04 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-05-11 at 6.52.34 PM.png b/.gitbook/assets/Screen Shot 2021-05-11 at 6.52.34 PM.png new file mode 100644 index 0000000..934afcc Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-05-11 at 6.52.34 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-05-11 at 6.54.38 PM.png b/.gitbook/assets/Screen Shot 2021-05-11 at 6.54.38 PM.png new file mode 100644 index 0000000..df8871c Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-05-11 at 6.54.38 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-05-11 at 6.54.53 PM.png b/.gitbook/assets/Screen Shot 2021-05-11 at 6.54.53 PM.png new file mode 100644 index 0000000..3523639 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-05-11 at 6.54.53 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-05-11 at 6.55.25 PM.png b/.gitbook/assets/Screen Shot 2021-05-11 at 6.55.25 PM.png new file mode 100644 index 0000000..22d7339 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-05-11 at 6.55.25 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-05-11 at 6.58.08 PM.png b/.gitbook/assets/Screen Shot 2021-05-11 at 6.58.08 PM.png new file mode 100644 index 0000000..7627f85 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-05-11 at 6.58.08 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-05-11 at 6.58.53 PM.png b/.gitbook/assets/Screen Shot 2021-05-11 at 6.58.53 PM.png new file mode 100644 index 0000000..c76aed4 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-05-11 at 6.58.53 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-05-11 at 6.59.32 PM.png b/.gitbook/assets/Screen Shot 2021-05-11 at 6.59.32 PM.png new file mode 100644 index 0000000..b9fb705 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-05-11 at 6.59.32 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-05-11 at 7.00.11 PM.png b/.gitbook/assets/Screen Shot 2021-05-11 at 7.00.11 PM.png new file mode 100644 index 0000000..4d1390b Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-05-11 at 7.00.11 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-05-11 at 7.01.38 PM.png b/.gitbook/assets/Screen Shot 2021-05-11 at 7.01.38 PM.png new file mode 100644 index 0000000..2bd6e7d Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-05-11 at 7.01.38 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-05-11 at 7.03.17 PM.png b/.gitbook/assets/Screen Shot 2021-05-11 at 7.03.17 PM.png new file mode 100644 index 0000000..87dc7fe Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-05-11 at 7.03.17 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-05-11 at 7.04.40 PM.png b/.gitbook/assets/Screen Shot 2021-05-11 at 7.04.40 PM.png new file mode 100644 index 0000000..9592532 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-05-11 at 7.04.40 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-28 at 4.40.17 PM.png b/.gitbook/assets/Screen Shot 2021-07-28 at 4.40.17 PM.png new file mode 100644 index 0000000..400de28 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-28 at 4.40.17 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-28 at 4.42.14 PM.png b/.gitbook/assets/Screen Shot 2021-07-28 at 4.42.14 PM.png new file mode 100644 index 0000000..ce3d21c Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-28 at 4.42.14 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-28 at 4.54.43 PM.png b/.gitbook/assets/Screen Shot 2021-07-28 at 4.54.43 PM.png new file mode 100644 index 0000000..e2c564f Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-28 at 4.54.43 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-28 at 4.58.03 PM.png b/.gitbook/assets/Screen Shot 2021-07-28 at 4.58.03 PM.png new file mode 100644 index 0000000..cbafc96 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-28 at 4.58.03 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-28 at 5.15.03 PM.png b/.gitbook/assets/Screen Shot 2021-07-28 at 5.15.03 PM.png new file mode 100644 index 0000000..a76aeb9 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-28 at 5.15.03 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-28 at 5.17.59 PM.png b/.gitbook/assets/Screen Shot 2021-07-28 at 5.17.59 PM.png new file mode 100644 index 0000000..67c619f Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-28 at 5.17.59 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-28 at 5.21.07 PM.png b/.gitbook/assets/Screen Shot 2021-07-28 at 5.21.07 PM.png new file mode 100644 index 0000000..a152fce Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-28 at 5.21.07 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-28 at 5.24.00 PM.png b/.gitbook/assets/Screen Shot 2021-07-28 at 5.24.00 PM.png new file mode 100644 index 0000000..35457c9 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-28 at 5.24.00 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-28 at 5.25.29 PM.png b/.gitbook/assets/Screen Shot 2021-07-28 at 5.25.29 PM.png new file mode 100644 index 0000000..cd783bd Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-28 at 5.25.29 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-28 at 5.25.50 PM.png b/.gitbook/assets/Screen Shot 2021-07-28 at 5.25.50 PM.png new file mode 100644 index 0000000..b4d612b Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-28 at 5.25.50 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 2.25.03 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 2.25.03 PM.png new file mode 100644 index 0000000..9a2ca7c Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 2.25.03 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 2.25.59 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 2.25.59 PM.png new file mode 100644 index 0000000..8d13c56 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 2.25.59 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 2.26.31 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 2.26.31 PM.png new file mode 100644 index 0000000..28598e1 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 2.26.31 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 2.28.44 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 2.28.44 PM.png new file mode 100644 index 0000000..f6ef379 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 2.28.44 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 2.31.03 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 2.31.03 PM.png new file mode 100644 index 0000000..6c90d14 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 2.31.03 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 2.31.47 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 2.31.47 PM.png new file mode 100644 index 0000000..ecae95a Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 2.31.47 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 2.33.58 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 2.33.58 PM.png new file mode 100644 index 0000000..4764c88 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 2.33.58 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 2.35.48 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 2.35.48 PM.png new file mode 100644 index 0000000..a69fe44 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 2.35.48 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 2.37.30 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 2.37.30 PM.png new file mode 100644 index 0000000..f34e594 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 2.37.30 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 2.39.24 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 2.39.24 PM.png new file mode 100644 index 0000000..b5e1f72 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 2.39.24 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 2.46.29 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 2.46.29 PM.png new file mode 100644 index 0000000..76a702c Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 2.46.29 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 2.48.31 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 2.48.31 PM.png new file mode 100644 index 0000000..e1ed60e Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 2.48.31 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 2.52.10 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 2.52.10 PM.png new file mode 100644 index 0000000..82e3daa Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 2.52.10 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 2.53.14 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 2.53.14 PM.png new file mode 100644 index 0000000..905c682 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 2.53.14 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 2.57.34 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 2.57.34 PM.png new file mode 100644 index 0000000..cfc7561 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 2.57.34 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 3.04.42 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 3.04.42 PM.png new file mode 100644 index 0000000..df9590c Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 3.04.42 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 3.06.20 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 3.06.20 PM.png new file mode 100644 index 0000000..0d56120 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 3.06.20 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 3.10.22 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 3.10.22 PM.png new file mode 100644 index 0000000..a582cb5 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 3.10.22 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 3.12.02 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 3.12.02 PM.png new file mode 100644 index 0000000..6edc5ee Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 3.12.02 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 3.12.27 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 3.12.27 PM.png new file mode 100644 index 0000000..98754f2 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 3.12.27 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 3.16.52 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 3.16.52 PM.png new file mode 100644 index 0000000..fbd9afb Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 3.16.52 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 3.18.12 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 3.18.12 PM.png new file mode 100644 index 0000000..6292c51 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 3.18.12 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 3.21.37 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 3.21.37 PM.png new file mode 100644 index 0000000..7a6c07d Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 3.21.37 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 3.26.35 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 3.26.35 PM.png new file mode 100644 index 0000000..e058d1a Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 3.26.35 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 4.36.31 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 4.36.31 PM.png new file mode 100644 index 0000000..a8b91a2 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 4.36.31 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 4.38.04 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 4.38.04 PM.png new file mode 100644 index 0000000..786b1cb Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 4.38.04 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 4.43.57 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 4.43.57 PM.png new file mode 100644 index 0000000..d5bfe3f Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 4.43.57 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 4.46.01 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 4.46.01 PM.png new file mode 100644 index 0000000..21728cb Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 4.46.01 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 5.04.23 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 5.04.23 PM.png new file mode 100644 index 0000000..57dc9da Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 5.04.23 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 5.06.35 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 5.06.35 PM.png new file mode 100644 index 0000000..d55a056 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 5.06.35 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 5.07.50 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 5.07.50 PM.png new file mode 100644 index 0000000..a78783c Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 5.07.50 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 5.09.14 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 5.09.14 PM.png new file mode 100644 index 0000000..e7f04fb Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 5.09.14 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 5.11.05 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 5.11.05 PM.png new file mode 100644 index 0000000..a4e87fd Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 5.11.05 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 5.12.39 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 5.12.39 PM.png new file mode 100644 index 0000000..921f7d8 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 5.12.39 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 5.13.40 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 5.13.40 PM.png new file mode 100644 index 0000000..7b21946 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 5.13.40 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 5.16.01 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 5.16.01 PM.png new file mode 100644 index 0000000..c7ac63a Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 5.16.01 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-29 at 5.17.13 PM.png b/.gitbook/assets/Screen Shot 2021-07-29 at 5.17.13 PM.png new file mode 100644 index 0000000..7a2bec3 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-29 at 5.17.13 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-30 at 12.06.28 AM.png b/.gitbook/assets/Screen Shot 2021-07-30 at 12.06.28 AM.png new file mode 100644 index 0000000..b506a38 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-30 at 12.06.28 AM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-30 at 12.09.27 AM.png b/.gitbook/assets/Screen Shot 2021-07-30 at 12.09.27 AM.png new file mode 100644 index 0000000..2fbfcc9 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-30 at 12.09.27 AM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-07-30 at 12.12.02 AM.png b/.gitbook/assets/Screen Shot 2021-07-30 at 12.12.02 AM.png new file mode 100644 index 0000000..5c6d485 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-07-30 at 12.12.02 AM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-08-01 at 12.04.01 PM.png b/.gitbook/assets/Screen Shot 2021-08-01 at 12.04.01 PM.png new file mode 100644 index 0000000..3f8f512 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-08-01 at 12.04.01 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-08-01 at 12.04.36 PM.png b/.gitbook/assets/Screen Shot 2021-08-01 at 12.04.36 PM.png new file mode 100644 index 0000000..40547e9 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-08-01 at 12.04.36 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-08-01 at 12.06.15 PM.png b/.gitbook/assets/Screen Shot 2021-08-01 at 12.06.15 PM.png new file mode 100644 index 0000000..6e0d020 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-08-01 at 12.06.15 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-08-01 at 12.07.27 PM.png b/.gitbook/assets/Screen Shot 2021-08-01 at 12.07.27 PM.png new file mode 100644 index 0000000..35855ea Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-08-01 at 12.07.27 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-08-01 at 12.08.45 PM.png b/.gitbook/assets/Screen Shot 2021-08-01 at 12.08.45 PM.png new file mode 100644 index 0000000..9a3bcf8 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-08-01 at 12.08.45 PM.png differ diff --git a/.gitbook/assets/Screen Shot 2021-12-08 at 2.14.02 PM.png b/.gitbook/assets/Screen Shot 2021-12-08 at 2.14.02 PM.png new file mode 100644 index 0000000..3385675 Binary files /dev/null and b/.gitbook/assets/Screen Shot 2021-12-08 at 2.14.02 PM.png differ diff --git a/.gitbook/assets/SimpleConfig_OpenWiFidocs.json b/.gitbook/assets/SimpleConfig_OpenWiFidocs.json new file mode 100644 index 0000000..629f71c --- /dev/null +++ b/.gitbook/assets/SimpleConfig_OpenWiFidocs.json @@ -0,0 +1,113 @@ +{ + "uuid": 2, + "unit": { + "location": "TIP Lab Network", + "timezone": "EST+5EDT,M3.2.0/2,M11.1.0/2" + }, + "radios": [ + { + "band": "5G", + "country": "CA", + "channel": "auto", + "channel-mode": "HE", + "channel-width": 80, + "require-mode": "HT", + "rates": { + "beacon": 6000, + "multicast": 24000 + } + }, + { + "band": "2G", + "country": "CA", + "channel": 11, + "channel-mode": "HE", + "channel-width": 80, + "require-mode": "HT", + "rates": { + "beacon": 6000, + "multicast": 24000 + } + } + ], + "interfaces": [ + { + "name": "WAN", + "role": "upstream", + "services": [ "lldp", "dhcp-snooping" ], + "ethernet": [ + { + "select-ports": [ + "WAN*" + ] + } + ], + "ipv4": { + "addressing": "dynamic" + } + }, + { + "name": "WAN100", + "role": "upstream", + "services": [ "lldp", "dhcp-snooping" ], + "vlan": { + "id": 100 + }, + "ethernet": [ + { + "select-ports": [ + "WAN*" + ] + } + ], + "ssids": [ + { + "name": "TIP OpenWiFi", + "wifi-bands": [ + "2G", "5G" + ], + "bss-mode": "ap", + "encryption": { + "proto": "psk2", + "key": "OpenWiFi", + "ieee80211w": "optional" + }, + "services": [ "wifi-frames"] + } + ] + } + ], + "metrics": { + "statistics": { + "interval": 120, + "types": [ "ssids", "lldp", "clients" ] + }, + "health": { + "interval": 120 + }, + "wifi-frames": { + "filters": [ "probe", + "auth", + "assoc", + "disassoc", + "deauth", + "local-deauth", + "inactive-deauth", + "key-mismatch", + "beacon-report", + "radar-detected"] + }, + "dhcp-snooping": { + "filters": [ "ack", "discover", "offer", "request", "solicit", "reply", "renew" ] + } + }, + "services": { + "lldp": { + "describe": "TIP OpenWiFi", + "location": "LivingLab" + }, + "ssh": { + "port": 22 + } + } +} \ No newline at end of file diff --git a/.gitbook/assets/image (1).png b/.gitbook/assets/image (1).png index d434a7c..5910ba4 100644 Binary files a/.gitbook/assets/image (1).png and b/.gitbook/assets/image (1).png differ diff --git a/.gitbook/assets/image (10).png b/.gitbook/assets/image (10).png index 0883de4..fea4588 100644 Binary files a/.gitbook/assets/image (10).png and b/.gitbook/assets/image (10).png differ diff --git a/.gitbook/assets/image (11).png b/.gitbook/assets/image (11).png index ae13925..0883de4 100644 Binary files a/.gitbook/assets/image (11).png and b/.gitbook/assets/image (11).png differ diff --git a/.gitbook/assets/image (12).png b/.gitbook/assets/image (12).png index b77c2a6..fce85e2 100644 Binary files a/.gitbook/assets/image (12).png and b/.gitbook/assets/image (12).png differ diff --git a/.gitbook/assets/image (13).png b/.gitbook/assets/image (13).png index fce85e2..b77c2a6 100644 Binary files a/.gitbook/assets/image (13).png and b/.gitbook/assets/image (13).png differ diff --git a/.gitbook/assets/image (14).png b/.gitbook/assets/image (14).png index 3d85439..ae13925 100644 Binary files a/.gitbook/assets/image (14).png and b/.gitbook/assets/image (14).png differ diff --git a/.gitbook/assets/image (16).png b/.gitbook/assets/image (16).png index fea4588..3d85439 100644 Binary files a/.gitbook/assets/image (16).png and b/.gitbook/assets/image (16).png differ diff --git a/.gitbook/assets/image (17).png b/.gitbook/assets/image (17).png index f0e7c34..a882953 100644 Binary files a/.gitbook/assets/image (17).png and b/.gitbook/assets/image (17).png differ diff --git a/.gitbook/assets/image (18).png b/.gitbook/assets/image (18).png index 108e68a..f0e7c34 100644 Binary files a/.gitbook/assets/image (18).png and b/.gitbook/assets/image (18).png differ diff --git a/.gitbook/assets/image (19).png b/.gitbook/assets/image (19).png index b9e507d..9338d90 100644 Binary files a/.gitbook/assets/image (19).png and b/.gitbook/assets/image (19).png differ diff --git a/.gitbook/assets/image (20).png b/.gitbook/assets/image (20).png index 9338d90..d2086a3 100644 Binary files a/.gitbook/assets/image (20).png and b/.gitbook/assets/image (20).png differ diff --git a/.gitbook/assets/image (21).png b/.gitbook/assets/image (21).png index d2086a3..b9e507d 100644 Binary files a/.gitbook/assets/image (21).png and b/.gitbook/assets/image (21).png differ diff --git a/.gitbook/assets/image (22) (3).png b/.gitbook/assets/image (22) (3).png new file mode 100644 index 0000000..69ddbdf Binary files /dev/null and b/.gitbook/assets/image (22) (3).png differ diff --git a/.gitbook/assets/image (22).png b/.gitbook/assets/image (22).png index 69ddbdf..96972e4 100644 Binary files a/.gitbook/assets/image (22).png and b/.gitbook/assets/image (22).png differ diff --git a/.gitbook/assets/image (23).png b/.gitbook/assets/image (23).png index b96313e..9a83ab8 100644 Binary files a/.gitbook/assets/image (23).png and b/.gitbook/assets/image (23).png differ diff --git a/.gitbook/assets/image (24).png b/.gitbook/assets/image (24).png index 96972e4..b96313e 100644 Binary files a/.gitbook/assets/image (24).png and b/.gitbook/assets/image (24).png differ diff --git a/.gitbook/assets/image (25).png b/.gitbook/assets/image (25).png index 9a83ab8..23eb5fe 100644 Binary files a/.gitbook/assets/image (25).png and b/.gitbook/assets/image (25).png differ diff --git a/.gitbook/assets/image (27).png b/.gitbook/assets/image (27).png index 23eb5fe..ba3f20c 100644 Binary files a/.gitbook/assets/image (27).png and b/.gitbook/assets/image (27).png differ diff --git a/.gitbook/assets/image (29).png b/.gitbook/assets/image (29).png index ba3f20c..29e791a 100644 Binary files a/.gitbook/assets/image (29).png and b/.gitbook/assets/image (29).png differ diff --git a/.gitbook/assets/image (3).png b/.gitbook/assets/image (3).png index 586a7b8..d434a7c 100644 Binary files a/.gitbook/assets/image (3).png and b/.gitbook/assets/image (3).png differ diff --git a/.gitbook/assets/image (30) (1).png b/.gitbook/assets/image (30) (1).png new file mode 100644 index 0000000..69ddbdf Binary files /dev/null and b/.gitbook/assets/image (30) (1).png differ diff --git a/.gitbook/assets/image (30).png b/.gitbook/assets/image (30).png index 69ddbdf..9d2f308 100644 Binary files a/.gitbook/assets/image (30).png and b/.gitbook/assets/image (30).png differ diff --git a/.gitbook/assets/image (31).png b/.gitbook/assets/image (31).png index 29e791a..4777e74 100644 Binary files a/.gitbook/assets/image (31).png and b/.gitbook/assets/image (31).png differ diff --git a/.gitbook/assets/image (32).png b/.gitbook/assets/image (32).png new file mode 100644 index 0000000..c2ed39c Binary files /dev/null and b/.gitbook/assets/image (32).png differ diff --git a/.gitbook/assets/image (33).png b/.gitbook/assets/image (33).png new file mode 100644 index 0000000..186b914 Binary files /dev/null and b/.gitbook/assets/image (33).png differ diff --git a/.gitbook/assets/image (35).png b/.gitbook/assets/image (35).png index 4777e74..67f87c2 100644 Binary files a/.gitbook/assets/image (35).png and b/.gitbook/assets/image (35).png differ diff --git a/.gitbook/assets/image (36).png b/.gitbook/assets/image (36).png new file mode 100644 index 0000000..c129761 Binary files /dev/null and b/.gitbook/assets/image (36).png differ diff --git a/.gitbook/assets/image (4).png b/.gitbook/assets/image (4).png index 0aed34d..5d30c77 100644 Binary files a/.gitbook/assets/image (4).png and b/.gitbook/assets/image (4).png differ diff --git a/.gitbook/assets/image (5).png b/.gitbook/assets/image (5).png index 979e650..586a7b8 100644 Binary files a/.gitbook/assets/image (5).png and b/.gitbook/assets/image (5).png differ diff --git a/.gitbook/assets/image (6).png b/.gitbook/assets/image (6).png index 5910ba4..0aed34d 100644 Binary files a/.gitbook/assets/image (6).png and b/.gitbook/assets/image (6).png differ diff --git a/.gitbook/assets/image (7).png b/.gitbook/assets/image (7).png index 5d30c77..979e650 100644 Binary files a/.gitbook/assets/image (7).png and b/.gitbook/assets/image (7).png differ diff --git a/.gitbook/assets/image (8).png b/.gitbook/assets/image (8).png index 9cfc73c..108e68a 100644 Binary files a/.gitbook/assets/image (8).png and b/.gitbook/assets/image (8).png differ diff --git a/.gitbook/assets/image (9).png b/.gitbook/assets/image (9).png index a882953..9cfc73c 100644 Binary files a/.gitbook/assets/image (9).png and b/.gitbook/assets/image (9).png differ diff --git a/.gitbook/assets/kafka-ELK-pipeline.png b/.gitbook/assets/kafka-ELK-pipeline.png new file mode 100644 index 0000000..37b3e95 Binary files /dev/null and b/.gitbook/assets/kafka-ELK-pipeline.png differ diff --git a/.gitbook/assets/owfms.yaml b/.gitbook/assets/owfms.yaml new file mode 100644 index 0000000..592c04e --- /dev/null +++ b/.gitbook/assets/owfms.yaml @@ -0,0 +1,848 @@ +openapi: 3.0.1 +info: + title: uCentral Firmware Service API + description: A process to manage new uCentral firmware distribution. + version: 2.0.0 + license: + name: BSD3 + url: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE + contact: + name: Arilia Support + url: https://www.ucentral.info/support + +servers: + - url: 'https://localhost:16003/api/v1' + +security: + - ApiKeyAuth: [] + - bearerAuth: [] + +components: + securitySchemes: + ApiKeyAuth: + type: apiKey + in: header + name: X-API-KEY + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT + + responses: + NotFound: + description: The specified resource was not found. + content: + application/json: + schema: + properties: + ErrorCode: + type: integer + ErrorDetails: + type: string + ErrorDescription: + type: string + + Unauthorized: + description: The requested does not have sufficient rights to perform the operation. + content: + application/json: + schema: + properties: + ErrorCode: + type: integer + enum: + - 0 # Success + - 1 # PASSWORD_CHANGE_REQUIRED, + - 2 # INVALID_CREDENTIALS, + - 3 # PASSWORD_ALREADY_USED, + - 4 # USERNAME_PENDING_VERIFICATION, + - 5 # PASSWORD_INVALID, + - 6 # INTERNAL_ERROR, + - 7 # ACCESS_DENIED, + - 8 # INVALID_TOKEN + ErrorDetails: + type: string + ErrorDescription: + type: string + + Success: + description: The requested operation was performed. + content: + application/json: + schema: + properties: + Operation: + type: string + Details: + type: string + Code: + type: integer + + schemas: + FirmwareDetails: + type: object + description: Definition of a firmware release + properties: + id: + type: string + format: uuid + deviceType: + type: string + description: + type: string + revision: + type: string + uri: + type: string + format: uri + image: + type: string + imageDate: + type: integer + format: int64 + size: + type: integer + format: int64 + downloadCount: + type: integer + format: int64 + firmwareHash: + type: string + owner: + type: string + location: + type: string + format: uri + uploader: + type: string + digest: + type: string + latest: + type: boolean + notes: + type: array + items: + $ref: '#/components/schemas/NoteInfo' + created: + type: integer + format: int64 + + FirmwareDetailsList: + type: object + properties: + firmwares: + type: array + items: + $ref: '#/components/schemas/FirmwareDetails' + + RevisionHistoryEntry: + type: object + properties: + id: + type: string + format: uuid + serialNumber: + type: string + revisionId: + type: string + format: uuid + upgraded: + type: integer + format: int64 + fromRelease: + type: string + toRelease: + type: string + commandUUID: + type: string + format: uuid + + RevisionHistoryEntryList: + type: object + properties: + history: + type: array + items: + $ref: '#/components/schemas/RevisionHistoryEntry' + + + FirmwareAgeDetails: + type: object + properties: + latestId: + type: string + image: + type: string + imageDate: + type: integer + format: uint64 + revision: + type: string + uri: + type: string + format: uri + age: + type: integer + format: int64 + example: this is in seconds. a 0 means we cannot determine the age. something like 'unknown' should be shown to the user. + latest: + type: boolean + + FirmwareAgeDetailsList: + type: object + properties: + ages: + type: array + items: + $ref: '#/components/schemas/FirmwareAgeDetails' + + DeviceConnectionInformation: + type: object + properties: + serialNumber: + type: string + revision: + type: string + deviceType: + type: string + endPoint: + type: string + format: uri + lastUpdate: + type: integer + format: uint64 + status: + type: string + enum: + - connected + - disconnected + - unknown + + DeviceConnectionInformationList: + type: object + properties: + devices: + type: array + items: + $ref: '#/components/schemas/DeviceConnectionInformation' + + DeviceReport: + type: object + properties: + snapshot: + type: integer + format: int64 + numberOfDevices: + type: integer + format: int64 + ouis: + $ref: '#/components/schemas/TagIntPairList' + revisions: + $ref: '#/components/schemas/TagIntPairList' + deviceTypes: + $ref: '#/components/schemas/TagIntPairList' + status: + $ref: '#/components/schemas/TagIntPairList' + endPoints: + $ref: '#/components/schemas/TagIntPairList' + unknownFirmwares: + $ref: '#/components/schemas/TagIntPairList' + usingLatest: + $ref: '#/components/schemas/TagIntPairList' + totalSecondsOld: + $ref: '#/components/schemas/TagIntPairList' + + ######################################################################################### + ## + ## These are endpoints that all services in the uCentral stack must provide + ## + ######################################################################################### + AnyPayload: + type: object + properties: + Document: + type: string + + StringList: + type: object + properties: + list: + type: array + items: + type: string + + TagValuePair: + type: object + properties: + tag: + type: string + value: + type: string + + TagValuePairList: + type: object + properties: + tagList: + type: array + items: + $ref: '#/components/schemas/TagValuePair' + + TagIntPair: + type: object + properties: + tag: + type: string + value: + type: integer + format: int64 + + TagIntPairList: + type: object + properties: + tagList: + type: array + items: + $ref: '#/components/schemas/TagIntPair' + + NoteInfo: + type: object + properties: + created: + type: integer + format: int64 + createdBy: + type: string + note: + type: string + + SystemInfoResults: + type: object + properties: + version: + type: string + uptime: + type: integer + format: integer64 + start: + type: integer + format: integer64 + os: + type: string + processors: + type: integer + hostname: + type: string + certificates: + type: array + items: + type: object + properties: + filename: + type: string + expires: + type: integer + format: int64 + + SystemCommandSetLogLevel: + type: object + properties: + command: + type: string + enum: + - setloglevel + subsystems: + type: array + items: + $ref: '#/components/schemas/TagValuePair' + + SystemCommandReload: + type: object + properties: + command: + type: string + enum: + - reload + subsystems: + type: array + items: + type: string + example: these are the SubSystems names retrieve with the GetSubSystemsNamesResult. + + SystemCommandGetLogLevels: + type: object + properties: + command: + type: string + enum: + - getloglevels + + SystemGetLogLevelsResult: + type: object + properties: + taglist: + type: array + items: + $ref: '#/components/schemas/TagValuePair' + + SystemCommandGetLogLevelNames: + type: object + properties: + command: + type: string + enum: + - getloglevelnames + + SystemCommandGetSubsystemNames: + type: object + properties: + command: + type: string + enum: + - getsubsystemnames + + SystemCommandGetLogLevelNamesResult: + type: object + properties: + list: + type: array + items: + type: string + + SystemGetSubSystemNemesResult: + type: object + properties: + taglist: + type: array + items: + $ref: '#/components/schemas/TagValuePair' + +######################################################################################### +## +## End of uCentral system-wide values +## +######################################################################################### +paths: + /firmwares: + get: + tags: + - Firmware + summary: Returns a list of firmwares. + description: Get a list of firmwares. + operationId: getFirmwareList + parameters: + - in: query + description: Pagination start (starts at 1. If not specified, 1 is assumed) + name: offset + schema: + type: integer + required: false + - in: query + description: Maximum number of entries to return (if absent, no limit is assumed) + name: limit + schema: + type: integer + required: false + - in: query + description: Filter the results + name: filter + schema: + type: string + required: false + - in: query + name: latestOnly + description: Return only the latest firwares + schema: + type: boolean + required: false + - in: query + name: deviceType + schema: + type: string + required: false + - in: query + name: revisionSet + schema: + type: boolean + required: false + - in: query + name: deviceSet + schema: + type: boolean + required: false + responses: + 200: + description: List firmwares + content: + application/json: + schema: + $ref: '#/components/schemas/FirmwareDetailsList' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /firmware/{id}: + get: + tags: + - Firmware + summary: Returns a Firmware + description: Get a Firmware. + operationId: getFirmware + parameters: + - in: path + name: id + schema: + type: string + format: uuid + required: true + responses: + 200: + description: A Firmware definition + content: + application/json: + schema: + $ref: '#/components/schemas/FirmwareDetails' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + post: + tags: + - Firmware + summary: Create A New firmware + operationId: createFirmware + parameters: + - in: path + name: id + schema: + type: string + format: uuid + required: true + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/FirmwareDetails' + responses: + 200: + description: Created a firmware entry. + content: + application/json: + schema: + $ref: '#/components/schemas/FirmwareDetails' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + put: + tags: + - Firmware + summary: Update A New firmware + operationId: upodateFirmware + parameters: + - in: path + name: id + schema: + type: string + format: uuid + required: true + requestBody: + description: Firmware details + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/FirmwareDetails' + responses: + 200: + description: Successfully updated firmware + content: + application/json: + schema: + $ref: '#/components/schemas/FirmwareDetails' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + delete: + tags: + - Firmware + summary: Delete some Firmware + operationId: deleteFirmware + parameters: + - in: path + name: id + schema: + type: string + format: uuid + required: true + responses: + 204: + description: Successfully deleted Firmware for the device. + content: + application/json: + schema: + $ref: '#/components/responses/Success' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /revisionHistory/{serialNumber}: + get: + tags: + - RevisionHistory + summary: List all the defined device revision history + operationId: getRevisionHistory + parameters: + - in: path + name: serialNumber + schema: + type: string + required: true + - in: query + description: Pagination start (starts at 1. If not specified, 1 is assumed) + name: offset + schema: + type: integer + required: false + - in: query + description: Maximum number of entries to return (if absent, no limit is assumed) + name: limit + schema: + type: integer + required: false + - in: query + description: Filter the results + name: filter + schema: + type: string + required: false + responses: + 200: + description: List of device history upgrade. + content: + application/json: + schema: + $ref: '#/components/schemas/RevisionHistoryEntryList' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + delete: + tags: + - RevisionHistory + summary: Delete specific hostory elements for a device + operationId: deleteRevisionHistory + parameters: + - in: path + name: serialNumber + schema: + type: string + required: true + - in: query + description: Pagination start (starts at 1. If not specified, 1 is assumed) + name: id + schema: + type: string + format: uuid + required: true + responses: + 204: + description: Success. + content: + application/json: + schema: + $ref: '#/components/responses/Success' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /firmwareAge: + get: + tags: + - Firmware + summary: Calculate how old a version of firmware is. + operationId: getFirmwareAge + parameters: + - in: query + description: The exact current verion of the firmware on that device. + name: revision + schema: + type: string + required: true + - in: query + description: The exact current verion of the firmware on that device. + name: deviceType + schema: + type: string + required: true + - in: query + description: Specify lits of serial numbers to retrive age for + name: select + schema: + type: string + example: select=serial1,serial2,serial4,serial5. + required: false + responses: + 200: + description: The recommended latest version to update to. + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/FirmwareAgeDetails' + - $ref: '#/components/schemas/FirmwareAgeDetailsList' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /connectedDevices: + get: + tags: + - ConnectedDevices + summary: Get a list of connected devices and some values. + operationId: getConnectedDevices + parameters: + - in: query + description: Pagination start (starts at 1. If not specified, 1 is assumed) + name: offset + schema: + type: integer + required: false + - in: query + description: Maximum number of entries to return (if absent, no limit is assumed) + name: limit + schema: + type: integer + required: false + - in: query + description: Filter the results + name: filter + schema: + type: string + required: false + responses: + 200: + description: List firmwares + content: + application/json: + schema: + $ref: '#/components/schemas/DeviceConnectionInformationList' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /connectedDevice/{serialNumber}: + get: + tags: + - ConnectedDevices + summary: Get status of a connected device. + operationId: getConnectedDevice + parameters: + - in: path + description: SerialNumber of the device + name: serialNumber + schema: + type: string + required: true + responses: + 200: + description: Get information about a connected device. + content: + application/json: + schema: + $ref: '#/components/schemas/DeviceConnectionInformation' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /deviceReport: + get: + tags: + - DeviceInfo + summary: get an analysis of the existing devices we know about. + responses: + 200: + description: A full analysis report + content: + application/json: + schema: + $ref: '#/components/schemas/DeviceReport' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + ######################################################################################### + ## + ## These are endpoints that all services in the uCentral stack must provide + ## + ######################################################################################### + /system: + post: + tags: + - System Commands + summary: Perform some system wide commands + operationId: systemCommand + requestBody: + description: Command details + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/SystemCommandSetLogLevel' + - $ref: '#/components/schemas/SystemCommandReload' + - $ref: '#/components/schemas/SystemCommandGetLogLevels' + - $ref: '#/components/schemas/SystemCommandGetLogLevelNames' + - $ref: '#/components/schemas/SystemCommandGetSubsystemNames' + responses: + 200: + description: Successfull command execution + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/SystemGetLogLevelsResult' + - $ref: '#/components/schemas/SystemCommandGetLogLevelNamesResult' + - $ref: '#/components/schemas/SystemGetSubSystemNemesResult' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + get: + tags: + - System Commands + summary: Retrieve different values from the running service. + operationId: getSystemCommand + parameters: + - in: query + description: Get a value + name: command + schema: + type: string + enum: + - info + required: true + + responses: + 200: + description: Successfull command execution + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/SystemInfoResults' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' diff --git a/.gitbook/assets/owgw.yaml b/.gitbook/assets/owgw.yaml new file mode 100644 index 0000000..ea81f3a --- /dev/null +++ b/.gitbook/assets/owgw.yaml @@ -0,0 +1,2413 @@ +openapi: 3.0.1 +info: + title: uCentral gateway API + description: A process to manage configuration for devices. + version: 2.0.0 + license: + name: BSD3 + url: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE + contact: + name: Arilia Support + email: ucentralsupport@arilia.com + url: https://www.ucentral.info/support + +servers: + - url: 'https://localhost:16001/api/v1' + +security: + - bearerAuth: [] + - ApiKeyAuth: [] + +components: + securitySchemes: + ApiKeyAuth: + type: apiKey + in: header + name: X-API-KEY + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT + + responses: + NotFound: + description: The specified resource was not found. + content: + application/json: + schema: + properties: + ErrorCode: + type: integer + ErrorDetails: + type: string + ErrorDescription: + type: string + + Unauthorized: + description: The requested does not have sufficient rights to perform the operation. + content: + application/json: + schema: + properties: + ErrorCode: + type: integer + enum: + - 0 # Success + - 1 # PASSWORD_CHANGE_REQUIRED, + - 2 # INVALID_CREDENTIALS, + - 3 # PASSWORD_ALREADY_USED, + - 4 # USERNAME_PENDING_VERIFICATION, + - 5 # PASSWORD_INVALID, + - 6 # INTERNAL_ERROR, + - 7 # ACCESS_DENIED, + - 8 # INVALID_TOKEN + ErrorDetails: + type: string + ErrorDescription: + type: string + + Success: + description: The requested operation was performed. + content: + application/json: + schema: + properties: + Operation: + type: string + Details: + type: string + Code: + type: integer + + schemas: + DeviceType: + type: string + default: AP + enum: + - AP + - SWITCH + - IOT + - MESH + + Device: + type: object + description: Definition of uCentral device + required: + - deviceType + properties: + owner: + type: string + format: uuid + location: + type: string + format: uuid + venue: + type: string + format: uuid + serialNumber: + type: string + deviceType: + $ref: '#/components/schemas/DeviceType' + macAddress: + type: string + manufacturer: + type: string + UUID: + type: integer + format: int64 + configuration: + type: string + notes: + type: array + items: + $ref: '#/components/schemas/NoteInfo' + createdTimestamp: + type: integer + format: int64 + lastConfigurationChange: + type: integer + format: int64 + lastConfigurationDownload: + type: integer + format: int64 + firmware: + type: string + devicePassword: + type: string + + DeviceWithStatus: + type: object + description: Definition of uCentral device + required: + - deviceType + properties: + owner: + type: string + format: uuid + location: + type: string + format: uuid + venue: + type: string + format: uuid + serialNumber: + type: string + deviceType: + $ref: '#/components/schemas/DeviceType' + macAddress: + type: string + manufacturer: + type: string + UUID: + type: integer + format: int64 + configuration: + type: string + compatible: + type: string + fwUpdatePolicy: + type: string + notes: + type: string + createdTimestamp: + type: integer + format: int64 + lastConfigurationChange: + type: integer + format: int64 + lastConfigurationDownload: + type: integer + format: int64 + lastFWUpdate: + type: integer + format: int64 + firmware: + type: string + connected: + type: boolean + ipAddress: + type: string + txBytes: + type: integer + format: int64 + rxBytes: + type: integer + format: int64 + associations_2G: + type: integer + format: int64 + associations_5G: + type: integer + format: int64 + devicePassword: + type: string + lastContact: + type: integer + format: int64 + + DeviceList: + type: object + description: Definition of uCentral device list + properties: + devices: + type: array + items: + $ref : '#/components/schemas/Device' + + DeviceListWithStatus: + type: object + description: Definition of uCentral device list including device status. + properties: + devicesWithStatus: + type: array + items: + $ref : '#/components/schemas/DeviceWithStatus' + + SerialNumberList: + type: object + description: List of serial numbers. + properties: + serialNumbers: + type: array + items: + type: string + + DeviceCount: + type: object + description: The number of devices in the DB. + properties: + count: + type: integer + format: int64 + + DeviceStatus: + type: object + description: Current device status. + properties: + serialNumber: + type: string + ipAddress: + type: string + txBytes: + type: integer + format: int64 + rxBytes: + type: integer + format: int64 + messageCount: + type: integer + format: int64 + UUID: + type: integer + format: int64 + connected: + type: boolean + lastContact: + type: integer + format: int64 + firmware: + type: string + associations_2G: + type: integer + format: int64 + associations_5G: + type: integer + format: int64 + verifiedCertificate: + type: string + enum: + - NO_CERTIFICATE, + - VALID_CERTIFICATE, + - MISMATCH_SERIAL, + - VERIFIED + + DeviceCapabilities: + type: object + description: Describes the capabilities a device can support. + properties: + serialNumber: + type: string + capabilities: + type: string + lastUpdate: + type: integer + format: int64 + firstUpdate: + type: integer + format: int64 + + StatisticsDetails: + type: object + properties: + serialNumber: + type: string + recorded: + type: integer + format: int64 + UUID: + type: integer + format: int64 + data: + type: string + + StatisticsRecords: + type: object + properties: + serialNumber: + type: string + values: + type: array + items: + $ref: '#/components/schemas/StatisticsDetails' + + NameValuePair: + type: object + properties: + name: + type: string + value: + type: integer + format: int64 + + InterfaceStatistics: + type: object + properties: + name: + type: string + values: + type: array + items: + $ref: '#/components/schemas/NameValuePair' + + LifetimeStatistics: + type: object + properties: + serialNumber: + type: string + interfaces: + type: array + items: + $ref: '#/components/schemas/InterfaceStatistics' + + CommandDetails: + type: object + properties: + command: + type: string + payload: + type: string + when: + type: integer + format: int64 + serialNumber: + type: string + + CommandSubmitSuccess: + description: The command was submitted succesfully. + properties: + serialNumber: + type: string + UUID: + type: string + format: uuid + + DeviceConfigureRequest: + type: object + properties: + serialNumber: + type: string + UUID: + type: integer + format: int64 + configuration: + type: string + when: + type: integer + format: int64 + + DeviceLog: + type: object + properties: + log: + type: string + recorded: + type: integer + format: int64 + severity: + type: integer + format: int64 + data: + type: string + logType: + type: integer + format: int64 + UUID: + type: integer + format: int64 + + DeviceLogList: + type: object + properties: + serialNumber: + type: string + values: + type: array + items: + $ref: '#/components/schemas/DeviceLog' + + HealthCheck: + type: object + properties: + UUID: + type: integer + format: int64 + sanity: + type: integer + format: int64 + data: + type: string + recorded: + type: integer + format: int64 + + HealthCheckList: + type: object + properties: + serialNumber: + type: string + values: + type: array + items: + $ref: '#/components/schemas/HealthCheck' + + DefaultConfiguration: + type: object + properties: + name: + type: string + modelIds: + type: string + description: + type: string + configuration: + type: string + created: + type: integer + format: int64 + lastModified: + type: integer + format: int64 + + DefaultConfigurationList: + properties: + configurations: + type: array + items: + $ref : '#/components/schemas/DefaultConfiguration' + + UpgradeRequest: + type: object + properties: + uri: + type: string + serialNumber: + type: string + when: + type: integer + format: int64 + + RebootRequest: + type: object + properties: + serialNumber: + type: string + when: + type: integer + format: int64 + + FactoryRequest: + type: object + properties: + serialNumber: + type: string + when: + type: integer + format: int64 + keepRedirector: + type: boolean + + LEDsRequest: + type: object + properties: + serialNumber: + type: string + when: + type: integer + format: int64 + duration: + description: only applies to the blink pattern + type: integer + format: int64 + pattern: + type: string + enum: + - on + - off + - blink + + MessageRequest: + type: object + properties: + serialNumber: + type: string + when: + type: integer + format: int64 + message: + type: string + enum: + - state + - healthcheck + + TraceRequest: + type: object + properties: + serialNumber: + type: string + when: + type: integer + format: int64 + duration: + type: integer + format: int64 + numberOfPackets: + type: integer + format: int64 + network: + type: string + interface: + type: string + + CommandInfo: + type: object + properties: + UUID: + type: string + format: uuid + command: + type: string + details: + type: string + serialNumber: + type: string + submitted: + type: integer + format: int64 + executed: + type: integer + format: int64 + completed: + type: integer + format: int64 + when: + type: integer + format: int64 + errorText: + type: string + results: + type: string + errorCode: + type: integer + format: int64 + submittedBy: + type: string + status: + type: string + custom: + type: integer + format: int64 + waitingForFile: + type: integer + format: int64 + attachFile: + type: integer + format: int64 + attachSize: + type: integer + format: int64 + attachType: + type: string + + CommandInfoList: + type: object + properties: + commands: + type: array + items: + $ref: '#/components/schemas/CommandInfo' + + DeviceDashboard: + type: object + properties: + snapshot: + type: integer + format: int64 + numberOfDevices: + type: integer + format: int64 + commands: + $ref: '#/components/schemas/TagIntPairList' + upTimes: + $ref: '#/components/schemas/TagIntPairList' + memoryUsed: + $ref: '#/components/schemas/TagIntPairList' + load1: + $ref: '#/components/schemas/TagIntPairList' + load5: + $ref: '#/components/schemas/TagIntPairList' + load15: + $ref: '#/components/schemas/TagIntPairList' + vendors: + $ref: '#/components/schemas/TagIntPairList' + status: + $ref: '#/components/schemas/TagIntPairList' + type: + $ref: '#/components/schemas/TagIntPairList' + deviceType: + $ref: '#/components/schemas/TagIntPairList' + healths: + $ref: '#/components/schemas/TagIntPairList' + certificates: + $ref: '#/components/schemas/TagIntPairList' + lastContact: + $ref: '#/components/schemas/TagIntPairList' + associations: + $ref: '#/components/schemas/TagIntPairList' + + TelemetryStreamRequest: + type: object + properties: + serialNumber: + type: string + interval: + type: integer + example: + 0 - means to stop streaming, values 1-120 in seconds. + types: + type: array + items: + type: string + enum: + - dhcp-snooping + - wire-frames + - state + uuid: + type: string + example: + only valid when terminating a stream + + TelemetryStreamResponse: + type: object + properties: + serialNumber: + type: string + uuid: + type: string + format: uuid + uri: + type: string + format: uri + example: + wss://host.domain:port/endpoint + + ######################################################################################### + ## + ## These are endpoints that all services in the uCentral stack must provide + ## + ######################################################################################### + AnyPayload: + type: object + properties: + Document: + type: string + + StringList: + type: object + properties: + list: + type: array + items: + type: string + + TagValuePair: + type: object + properties: + tag: + type: string + value: + type: string + + TagValuePairList: + type: object + properties: + tagList: + type: array + items: + $ref: '#/components/schemas/TagValuePair' + + TagIntPair: + type: object + properties: + tag: + type: string + value: + type: integer + format: int64 + + TagIntPairList: + type: object + properties: + tagList: + type: array + items: + $ref: '#/components/schemas/TagIntPair' + + SystemCommandDetails: + type: object + properties: + command: + type: string + enum: + - setloglevels + - getloglevels + - getSubSystemNames + - getLogLevelNames + - stats + parameters: + oneOf: + - $ref: '#/components/schemas/StringList' + - $ref: '#/components/schemas/TagValuePairList' + + SystemCommandResults: + type: object + oneOf: + - $ref: '#/components/schemas/StringList' + - $ref: '#/components/schemas/TagValuePairList' + + NoteInfo: + type: object + properties: + created: + type: integer + format: int64 + createdBy: + type: string + note: + type: string + + SystemInfoResults: + type: object + properties: + version: + type: string + uptime: + type: integer + format: integer64 + start: + type: integer + format: integer64 + os: + type: string + processors: + type: integer + hostname: + type: string + certificates: + type: array + items: + type: object + properties: + filename: + type: string + expires: + type: integer + format: int64 + + SystemCommandSetLogLevel: + type: object + properties: + command: + type: string + enum: + - setloglevel + subsystems: + type: array + items: + $ref: '#/components/schemas/TagValuePair' + + SystemCommandReload: + type: object + properties: + command: + type: string + enum: + - reload + subsystems: + type: array + items: + type: string + example: these are the SubSystems names retrieve with the GetSubSystemsNamesResult. + + SystemCommandGetLogLevels: + type: object + properties: + command: + type: string + enum: + - getloglevels + + SystemGetLogLevelsResult: + type: object + properties: + taglist: + type: array + items: + $ref: '#/components/schemas/TagValuePair' + + SystemCommandGetLogLevelNames: + type: object + properties: + command: + type: string + enum: + - getloglevelnames + + SystemCommandGetSubsystemNames: + type: object + properties: + command: + type: string + enum: + - getsubsystemnames + + SystemCommandGetLogLevelNamesResult: + type: object + properties: + list: + type: array + items: + type: string + + SystemGetSubSystemNamesResult: + type: object + properties: + taglist: + type: array + items: + $ref: '#/components/schemas/TagValuePair' + + ######################################################################################### + ## + ## End of uCentral system wide values + ## + ######################################################################################### + BlackDeviceInfo: + type: object + properties: + serialNumber: + type: string + created: + type: integer + format: int64 + readOnly: true + author: + type: string + readOnly: true + reason: + type: string + + BlackDeviceList: + type: object + properties: + devices: + type: array + items: + $ref: '#/components/schemas/BlackDeviceInfo' + + WifiBands: + type: object + properties: + bands: + type: array + items: + type: string + enum: [ "2" , "5", "5l", "5u" , "6" ] + + WifiChannels: + type: object + properties: + channels: + type: array + items: + type: integer + + WifiScanRequest: + type: object + properties: + serialNumber: + type: string + verbose: + type: boolean + activeScan: + type: boolean + selector: + oneOf: + - $ref: '#/components/schemas/WifiBands' + - $ref: '#/components/schemas/WifiChannels' + required: + - serialNumber + + EventQueueRequest: + type: object + properties: + serialNumber: + type: string + types: + type: array + items: + type: string + enum: + - dhcp + - rrm + + EventQueueResponse: + type: object + properties: + serialNumber: + type: string + UUID: + type: string + format: uuid + result: + type: string + + RttySessionDetails: + type: object + properties: + serialNumber: + type: string + server: + type: string + port: + type: integer + format: int32 + token: + type: string + timeout: + type: integer + format: int32 + connectionId: + type: string + started: + type: integer + format: int64 + commandUUID: + type: string + viewport: + type: integer + format: int32 + password: + type: string + + CapabilitiesModel: + type: object + properties: + deviceType: + type: string + capabilities: + type: string + + CapabilitiesModelList: + type: object + properties: + devices: + type: array + items: + $ref: '#/components/schemas/CapabilitiesModel' + +paths: + /devices: + get: + tags: + - Devices + summary: Returns a list of devices. + description: Get a list of devices. + operationId: getDeviceList + parameters: + - in: query + description: Pagination start (starts at 1. If not specified, 1 is assumed) + name: offset + schema: + type: integer + required: false + - in: query + description: Maximum number of entries to return (if absent, no limit is assumed) + name: limit + schema: + type: integer + required: false + - in: query + description: Filter the results + name: filter + schema: + type: string + required: false + - in: query + description: Supply a list of devices comma separated + name: select + schema: + type: string + example: serial1,serial2,serial3 + - in: query + description: only serial numbers of full device details + name: serialOnly + schema: + type: boolean + - in: query + description: return the number of devices + name: countOnly + schema: + type: boolean + example: countOnly=true + - in: query + description: Return extra information with the device information + name: deviceWithStatus + schema: + type: boolean + responses: + 200: + description: List devices + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/DeviceList' + - $ref: '#/components/schemas/DeviceListWithStatus' + - $ref: '#/components/schemas/SerialNumberList' + - $ref: '#/components/schemas/DeviceCount' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /commands: + get: + tags: + - Commands + summary: Returns a list of commands. + description: Get a list of commands. + operationId: getCommandList + parameters: + - in: query + name: serialNumber + schema: + type: string + required: false + - in: query + name: startDate + schema: + type: integer + format: int64 + required: false + - in: query + name: endDate + schema: + type: integer + format: int64 + - in: query + name: offset + schema: + type: integer + format: int64 + - in: query + name: limit + schema: + type: integer + format: int64 + - in: query + description: Selecting this option means the newest record will be returned. Use limit to select how many. + name: newest + schema: + type: boolean + required: false + + responses: + 200: + description: List commands + content: + application/json: + schema: + $ref: '#/components/schemas/CommandInfoList' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + delete: + tags: + - Commands + summary: Delete some commands + operationId: deleteCommands + parameters: + - in: query + name: serialNumber + schema: + type: string + required: true + - in: query + name: startDate + schema: + type: integer + format: int64 + required: false + - in: query + name: endDate + schema: + type: integer + format: int64 + + responses: + 204: + description: Successfully deleted commands for the device. + content: + application/json: + schema: + $ref: '#/components/responses/Success' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /command/{commandUUID}: + get: + tags: + - Commands + summary: Returns a specific command. + description: Returns a specific command + operationId: getACommandDetails + parameters: + - in: path + name: commandUUID + schema: + type: string + format: uuid + required: true + responses: + 200: + description: List commands + content: + application/json: + schema: + $ref: '#/components/schemas/CommandInfo' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + delete: + tags: + - Commands + summary: Delete a specific command. + description: Delete a specific command + operationId: deleteACommand + parameters: + - in: path + name: commandUUID + schema: + type: string + format: uuid + required: true + responses: + 204: + description: Delete command success + content: + application/json: + schema: + $ref: '#/components/responses/Success' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /default_configurations: + get: + tags: + - Configurations + summary: Retrieve the lists of all default configurations. + description: Retrieve the lists of all default configurations. + operationId: getDefaultConfigurations + + responses: + 200: + description: List of defautl configurations included + content: + application/json: + schema: + $ref: '#/components/schemas/DefaultConfigurationList' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /default_configuration/{name}: + get: + tags: + - Configurations + summary: Retrieve a default configuration. + description: Retrieve a default configuration. + operationId: getDefaultConfiguration + parameters: + - in: path + name: name + schema: + type: string + required: true + responses: + 200: + description: Default configurations included + content: + application/json: + schema: + $ref: '#/components/schemas/DefaultConfiguration' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + post: + tags: + - Configurations + summary: Create a default configuration. + description: Create a default configuration. + operationId: createDefaultConfiguration + parameters: + - in: path + name: name + schema: + type: string + required: true + requestBody: + description: Information used to create the new device + content: + application/json: + schema: + $ref: '#/components/schemas/DefaultConfiguration' + responses: + 200: + $ref: '#/components/responses/Success' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + delete: + tags: + - Configurations + summary: Delete a default default configuration + description: Delete a default default configuration + operationId: deleteDefaultConfiguration + parameters: + - in: path + name: name + schema: + type: string + required: true + responses: + 204: + $ref: '#/components/responses/Success' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + put: + tags: + - Configurations + summary: Update a default configuration + description: Update a default configuration + operationId: updateDefaultConfiguration + parameters: + - in: path + name: name + schema: + type: string + required: true + requestBody: + description: Configuration details + content: + application/json: + schema: + $ref: '#/components/schemas/DefaultConfiguration' + responses: + 200: + $ref: '#/components/responses/Success' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /device/{serialNumber}: + get: + tags: + - Devices + summary: Retrieve information for a single device. + description: Retrieve all the inforamtion about a single device + operationId: getDeviceInformation + parameters: + - in: path + name: serialNumber + schema: + type: string + required: true + responses: + 200: + description: Device information + content: + application/json: + schema: + $ref: '#/components/schemas/Device' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + post: + tags: + - Devices + summary: Create a new device. + operationId: createNewDevice + parameters: + - in: path + name: serialNumber + schema: + type: string + required: true + - in: query + name: validateOnly + schema: + type: boolean + required: false + requestBody: + description: Information used to create the new device + content: + application/json: + schema: + $ref: '#/components/schemas/Device' + responses: + 200: + description: Successful device creation will return the device record with the proper device ID + content: + application/json: + schema: + $ref: '#/components/schemas/Device' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + put: + tags: + - Devices + summary: Update a device. + operationId: updateNewDevice + parameters: + - in: path + name: serialNumber + schema: + type: string + required: true + requestBody: + description: Information used to create the new device + content: + application/json: + schema: + $ref: '#/components/schemas/Device' + responses: + 200: + description: Successful device creation will return the device record with the proper device ID + content: + application/json: + schema: + $ref: '#/components/schemas/Device' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + delete: + tags: + - Devices + summary: Delete a single device. + operationId: deleteDevice + parameters: + - in: path + name: serialNumber + schema: + type: string + required: true + responses: + 204: + $ref: '#/components/responses/Success' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /device/{serialNumber}/logs: + get: + tags: + - Commands + summary: Get the latest logs for a given device + operationId: getDeviceLogs + parameters: + - in: path + name: serialNumber + schema: + type: string + required: true + - in: query + name: startDate + schema: + type: integer + format: int64 + required: false + - in: query + name: endDate + schema: + type: integer + format: int64 + - in: query + name: offset + schema: + type: integer + format: int64 + - in: query + name: limit + schema: + type: integer + format: int64 + - in: query + name: logType + description: 0=any kind of logs (default) 0=normal logs only 1=crash logs only + schema: + type: integer + format: int64 + - in: query + description: Selecting this option means the newest record will be returned. Use limit to select how many. + name: newest + schema: + type: boolean + required: false + + responses: + 200: + description: Array of device logs for this device + content: + application/json: + schema: + $ref: '#/components/schemas/DeviceLogList' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + delete: + tags: + - Commands + summary: Delete some device logs. + operationId: deleteDeviceLogs + parameters: + - in: path + name: serialNumber + schema: + type: string + required: true + - in: query + name: startDate + schema: + type: integer + format: int64 + required: false + - in: query + name: endDate + schema: + type: integer + format: int64 + - in: query + name: logType + description: 0=any kind of logs (default) 1=normal logs only 2=crash logs only + schema: + type: integer + format: int64 + + responses: + 204: + description: Successfully deleted logs for the device. + content: + application/json: + schema: + $ref: '#/components/responses/Success' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /device/{serialNumber}/healthchecks: + get: + tags: + - Commands + summary: Get the latest health checks for a given device. + operationId: getDeviceHealthChecks + parameters: + - in: path + name: serialNumber + schema: + type: string + required: true + - in: query + name: startDate + schema: + type: integer + format: int64 + required: false + - in: query + name: endDate + schema: + type: integer + format: int64 + required: false + - in: query + name: offset + schema: + type: integer + format: int64 + required: false + - in: query + name: limit + schema: + type: integer + format: int64 + required: false + - in: query + description: Selecting this option means the newest record will be returned. Use limit to select how many. + name: newest + schema: + type: boolean + required: false + - in: query + description: Selecting this option means the last healthcheck will be returned. All other parameters will be ignored. + name: lastOnly + schema: + type: boolean + required: false + + responses: + 200: + description: Array of device health checks for this device + content: + application/json: + schema: + $ref: '#/components/schemas/HealthCheckList' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + delete: + tags: + - Commands + summary: Delete some device health checks. + operationId: deleteDeviceHealthChecks + parameters: + - in: path + name: serialNumber + schema: + type: string + required: true + - in: query + name: startDate + schema: + type: integer + format: int64 + required: false + - in: query + name: endDate + schema: + type: integer + format: int64 + required: false + + responses: + 204: + description: Successfully deleted health checks for the device. + content: + application/json: + schema: + $ref: '#/components/responses/Success' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /device/{serialNumber}/capabilities: + get: + tags: + - Commands + summary: Get the latest capabilities for a given device. + operationId: getDeviceCapabilities + parameters: + - in: path + name: serialNumber + schema: + type: string + required: true + responses: + 200: + description: List of logs for this device + content: + application/json: + schema: + $ref: '#/components/schemas/DeviceCapabilities' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + delete: + tags: + - Commands + summary: Delete the capabilities for a given device. + operationId: deleteDeviceCapabilities + parameters: + - in: path + name: serialNumber + schema: + type: string + required: true + responses: + 204: + description: List of logs for this device + content: + application/json: + schema: + $ref: '#/components/responses/Success' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /device/{serialNumber}/statistics: + get: + tags: + - Commands + summary: Get the latest statistics for a given device. + operationId: getDeviceStats + parameters: + - in: path + name: serialNumber + schema: + type: string + required: true + - in: query + name: startDate + schema: + type: integer + format: int64 + required: false + - in: query + name: endDate + schema: + type: integer + format: int64 + required: false + - in: query + name: offset + schema: + type: integer + format: int64 + required: false + - in: query + name: limit + schema: + type: integer + format: int64 + required: false + - in: query + description: Selecting this option means the LifetimeStatistics will be returned. All other parameters will be ignored. + name: lifetime + schema: + type: boolean + required: false + - in: query + description: Selecting this option means the LifetimeStatistics will be returned. All other parameters will be ignored. + name: lastOnly + schema: + type: boolean + required: false + - in: query + description: Selecting this option means the newest record will be returned. Use limit to select how many. + name: newest + schema: + type: boolean + required: false + + responses: + 200: + description: Array of statistics for this device + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/StatisticsRecords' + - $ref: '#/components/schemas/LifetimeStatistics' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + delete: + tags: + - Commands + summary: Get the latest statistics for a given device. + operationId: deleteDeviceStats + parameters: + - in: path + name: serialNumber + schema: + type: string + required: true + - in: query + name: startDate + schema: + type: integer + format: int64 + required: false + - in: query + name: endDate + schema: + type: integer + format: int64 + required: false + + responses: + 204: + description: Array of statistics for this device + content: + application/json: + schema: + $ref: '#/components/responses/Success' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /device/{serialNumber}/status: + get: + tags: + - Commands + summary: Get the latest status for a given device. + operationId: getDeviceStatus + parameters: + - in: path + name: serialNumber + schema: + type: string + required: true + responses: + 200: + description: Status for the given device + content: + application/json: + schema: + $ref: '#/components/schemas/DeviceStatus' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /device/{serialNumber}/command: + post: + tags: + - Commands + summary: Post a command to a device + operationId: executeCommand + parameters: + - in: path + name: serialNumber + schema: + type: string + required: true + requestBody: + description: Command details + content: + application/json: + schema: + $ref: '#/components/schemas/CommandDetails' + responses: + 200: + $ref: '#/components/schemas/CommandInfo' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /device/{serialNumber}/configure: + post: + tags: + - Commands + summary: Configure a device. + operationId: updateConfigurationForADevice + parameters: + - in: path + name: serialNumber + schema: + type: string + required: true + requestBody: + description: Command details + content: + application/json: + schema: + $ref: '#/components/schemas/DeviceConfigureRequest' + responses: + 200: + $ref: '#/components/schemas/CommandInfo' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /device/{serialNumber}/upgrade: + post: + tags: + - Commands + summary: Upgrade a device. + operationId: UpgradeDeviceFirmware + parameters: + - in: path + name: serialNumber + schema: + type: string + required: true + requestBody: + description: Command details + content: + application/json: + schema: + $ref: '#/components/schemas/UpgradeRequest' + responses: + 200: + $ref: '#/components/schemas/CommandInfo' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /device/{serialNumber}/reboot: + post: + tags: + - Commands + summary: Reboot a device. + operationId: rebootDevice + parameters: + - in: path + name: serialNumber + schema: + type: string + required: true + requestBody: + description: Command details + content: + application/json: + schema: + $ref: '#/components/schemas/RebootRequest' + responses: + 200: + $ref: '#/components/schemas/CommandInfo' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /device/{serialNumber}/factory: + post: + tags: + - Commands + summary: Factory reset a device. + operationId: factoryReset + parameters: + - in: path + name: serialNumber + schema: + type: string + required: true + requestBody: + description: Command details + content: + application/json: + schema: + $ref: '#/components/schemas/FactoryRequest' + responses: + 200: + $ref: '#/components/schemas/CommandInfo' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /device/{serialNumber}/leds: + post: + tags: + - Commands + summary: Blink the LEDs on a device. + operationId: ledsRequest + parameters: + - in: path + name: serialNumber + schema: + type: string + required: true + requestBody: + description: Command details + content: + application/json: + schema: + $ref: '#/components/schemas/LEDsRequest' + responses: + 200: + $ref: '#/components/schemas/CommandInfo' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /device/{serialNumber}/trace: + post: + tags: + - Commands + summary: Launch a trace for a device. + operationId: traceRequest + parameters: + - in: path + name: serialNumber + schema: + type: string + required: true + requestBody: + description: Command details + content: + application/json: + schema: + $ref: '#/components/schemas/TraceRequest' + responses: + 200: + $ref: '#/components/schemas/CommandInfo' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /device/{serialNumber}/wifiscan: + post: + tags: + - Commands + summary: Launch a wifi scan for a device. + operationId: wifiscanRequest + parameters: + - in: path + name: serialNumber + schema: + type: string + required: true + requestBody: + description: Scan details + content: + application/json: + schema: + $ref: '#/components/schemas/WifiScanRequest' + responses: + 200: + $ref: '#/components/schemas/CommandInfo' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /device/{serialNumber}/request: + post: + tags: + - Commands + summary: Request a specific message + operationId: messageRequest + parameters: + - in: path + name: serialNumber + schema: + type: string + required: true + requestBody: + description: Message request details + content: + application/json: + schema: + $ref: '#/components/schemas/MessageRequest' + responses: + 200: + $ref: '#/components/schemas/CommandSubmitSuccess' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /device/{serialNumber}/eventqueue: + post: + tags: + - Commands + summary: Request a list of queued events. + operationId: eventQueueRequest + parameters: + - in: path + name: serialNumber + schema: + type: string + required: true + requestBody: + description: Message request details + content: + application/json: + schema: + $ref: '#/components/schemas/EventQueueRequest' + responses: + 200: + $ref: '#/components/schemas/EventQueueResponse' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /device/{serialNumber}/telemetry: + post: + tags: + - Commands + summary: Request a telemetry stream. + operationId: eventTelemetryStreamRequest + parameters: + - in: path + name: serialNumber + schema: + type: string + required: true + requestBody: + description: Message request details + content: + application/json: + schema: + $ref: '#/components/schemas/TelemetryStreamRequest' + responses: + 200: + $ref: '#/components/schemas/TelemetryStreamResponse' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /ouis: + get: + tags: + - OUIs + operationId: getOUIs + summary: Get a list of OUIs. + parameters: + - in: query + name: macList + schema: + type: string + required: true + responses: + 200: + $ref: '#/components/schemas/TagValuePairList' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /device/{serialNumber}/rtty: + get: + tags: + - Commands + summary: Get the rtty parameters to initiate a session. + operationId: getRttySessionInfo + parameters: + - in: path + name: serialNumber + schema: + type: string + required: true + responses: + 200: + description: Session information + content: + application/json: + schema: + $ref: '#/components/schemas/RttySessionDetails' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /file/{uuid}: + get: + tags: + - Files + summary: Get a file from the upload directory. + operationId: getUploadFile + parameters: + - in: path + name: uuid + schema: + type: string + format: uuid + required: true + - in: query + name: serialNumber + schema: + type: string + required: true + responses: + 200: + description: Succesfull file retrieval + content: + application/octet-stream: + schema: + type: string + format: binary + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + delete: + tags: + - Files + summary: Delete a file from the upload directory. + operationId: deleteUploadFidelete + parameters: + - in: path + name: uuid + schema: + type: string + format: uuid + required: true + - in: query + name: serialNumber + schema: + type: string + required: true + responses: + 204: + $ref: '#/components/responses/Success' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /blacklist: + get: + tags: + - Blacklist + summary: Returns a list blacklisted devices. + description: Get a list of blacklisted devices. + operationId: getBlacklistDeviceList + parameters: + - in: query + description: Pagination start (starts at 1. If not specified, 1 is assumed) + name: offset + schema: + type: integer + required: false + - in: query + description: Maximum number of entries to return (if absent, no limit is assumed) + name: limit + schema: + type: integer + required: false + - in: query + description: Filter the results + name: filter + schema: + type: string + required: false + responses: + 200: + description: List blacklisted devices + content: + application/json: + schema: + $ref: '#/components/schemas/BlackDeviceList' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /blacklist/{serialNumber}: + get: + tags: + - Blacklist + summary: Returns a blacklist entry. + description: Get a list of blacklisted devices. + operationId: getBlacklistDevice + parameters: + - in: path + description: Pagination start (starts at 1. If not specified, 1 is assumed) + name: serialNumber + schema: + type: string + required: true + responses: + 200: + description: List blacklisted devices + content: + application/json: + schema: + $ref: '#/components/schemas/BlackDeviceInfo' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + post: + tags: + - Blacklist + summary: Create to the blacklist. + operationId: createBlackListDevice + parameters: + - in: path + description: Pagination start (starts at 1. If not specified, 1 is assumed) + name: serialNumber + schema: + type: string + required: true + requestBody: + description: Add blacklisted device + content: + application/json: + schema: + $ref: '#/components/schemas/BlackDeviceInfo' + responses: + 200: + $ref: '#/components/responses/Success' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + put: + tags: + - Blacklist + summary: Modify to the blacklist. + operationId: modifyBlackList + parameters: + - in: path + description: Pagination start (starts at 1. If not specified, 1 is assumed) + name: serialNumber + schema: + type: string + required: true + requestBody: + description: Add blacklisted devices + content: + application/json: + schema: + $ref: '#/components/schemas/BlackDeviceInfo' + responses: + 200: + $ref: '#/components/responses/Success' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + delete: + tags: + - Blacklist + summary: Delete from the blacklist. + operationId: deleteFromBlackList + parameters: + - in: path + name: serialNumber + schema: + type: string + required: true + responses: + 204: + $ref: '#/components/responses/Success' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /capabilities: + get: + tags: + - Devices + summary: Get the list of device types and capabilities. + operationId: getCapabilitiesList + responses: + 200: + description: Successful command execution + content: + application/json: + schema: + $ref: '#/components/schemas/CapabilitiesModelList' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /deviceDashboard: + get: + tags: + - Dashboards + summary: Get the last version of the dashboard. + operationId: getDeviceDashboard + responses: + 200: + $ref: '#/components/schemas/DeviceDashboard' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + ######################################################################################### + ## + ## These are endpoints that all services in the uCentral stack must provide + ## + ######################################################################################### + /system: + post: + tags: + - System Commands + summary: Perform some system wide commands. + operationId: systemCommand + requestBody: + description: Command details + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/SystemCommandSetLogLevel' + - $ref: '#/components/schemas/SystemCommandReload' + - $ref: '#/components/schemas/SystemCommandGetLogLevels' + - $ref: '#/components/schemas/SystemCommandGetLogLevelNames' + - $ref: '#/components/schemas/SystemCommandGetSubsystemNames' + responses: + 200: + description: Successful command execution + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/SystemGetLogLevelsResult' + - $ref: '#/components/schemas/SystemCommandGetLogLevelNamesResult' + - $ref: '#/components/schemas/SystemGetSubSystemNamesResult' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + get: + tags: + - System Commands + summary: Retrieve different values from the running service. + operationId: getSystemCommand + parameters: + - in: query + description: Get a value + name: command + schema: + type: string + enum: + - info + required: true + + responses: + 200: + description: Successful command execution + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/SystemInfoResults' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' \ No newline at end of file diff --git a/.gitbook/assets/owprov.yaml b/.gitbook/assets/owprov.yaml new file mode 100644 index 0000000..7f55715 --- /dev/null +++ b/.gitbook/assets/owprov.yaml @@ -0,0 +1,3081 @@ +openapi: 3.0.1 +info: + title: OpenWiFi Provisioning Model + description: Definitions and APIs to manages an OpenWiFi network. + version: 2.5.0 + license: + name: BSD3 + url: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE + +servers: + - url: 'https://localhost:16005/api/v1' + +security: + - bearerAuth: [] + - ApiKeyAuth: [] + +components: + securitySchemes: + ApiKeyAuth: + type: apiKey + in: header + name: X-API-KEY + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT + + responses: + NotFound: + description: The specified resource was not found. + content: + application/json: + schema: + properties: + ErrorCode: + type: integer + ErrorDetails: + type: string + ErrorDescription: + type: string + + Unauthorized: + description: The requested does not have sufficient rights to perform the operation. + content: + application/json: + schema: + properties: + ErrorCode: + type: integer + enum: + - 0 # Success + - 1 # PASSWORD_CHANGE_REQUIRED, + - 2 # INVALID_CREDENTIALS, + - 3 # PASSWORD_ALREADY_USED, + - 4 # USERNAME_PENDING_VERIFICATION, + - 5 # PASSWORD_INVALID, + - 6 # INTERNAL_ERROR, + - 7 # ACCESS_DENIED, + - 8 # INVALID_TOKEN + - 9 # EXPIRED_TOKEN + - 10 # RATE_LIMIT_EXCEEDED + - 11 # BAD_MFA_TRANSACTION + - 12 # MFA_FAILURE + - 13 # SECURITY_SERVICE_UNREACHABLE + ErrorDetails: + type: string + ErrorDescription: + type: string + + Success: + description: The requested operation was performed. + content: + application/json: + schema: + properties: + Operation: + type: string + Details: + type: string + Code: + type: integer + + BadRequest: + description: The requested operation failed. + content: + application/json: + schema: + properties: + ErrorCode: + type: integer + ErrorDetails: + type: string + ErrorDescription: + type: integer + + schemas: + + ObjectInfo: + type: object + properties: + id: + type: string + format: uuid + name: + type: string + description: + type: string + notes: + type: array + items: + $ref: '#/components/schemas/NoteInfo' + created: + type: integer + format: int64 + modified: + type: integer + format: int64 + tags: + type: array + items: + type: integer + format: int64 + + # uuids: mpe: + ManagementPolicyEntry: + type: object + properties: + users: + type: array + items: + type: string + resources: + description: this is a list of UUID and UUID Patterns to control by this policy + type: array + items: + type: string + access: + type: array + items: + type: string + enum: + - NOACCESS + - READ + - MODIFY + - DELETE + - LIST + - CREATE + - FULL + policy: + description: A JSON document describing the policy + type: string + + # uuids: mpp: + ManagementPolicy: + type: object + properties: + allOf: + $ref: '#/components/schemas/ObjectInfo' + entries: + type: array + items: + $ref: '#/components/schemas/ManagementPolicyEntry' + inUse: + type: array + items: + type: string + format: uuid + example: each uuid is preceded by ent, or ven to say that the elemenet is entity or venue + entity: + type: string + format: uuid + venue: + type: string + format: uuid + + ManagementPolicyList: + type: object + properties: + policies: + type: array + items: + $ref: '#/components/schemas/ManagementPolicy' + + # uuids: ent: + Entity: + type: object + properties: + allOf: + $ref: '#/components/schemas/ObjectInfo' + parent: + description: If empty, then this is the root entity, otherwise this points to a parent entity + type: string + format: uuid + children: + type: array + items: + type: string + format: uuid + venues: + description: The list of UUID of the venues for this entity + type: array + items: + type: string + format: uuid + contacts: + description: The list of UUID of the contacts for the entity + type: array + items: + type: string + format: uuid + locations: + description: The list of UUID of the locations associated with thit entiry + type: array + items: + type: string + format: uuid + managementPolicy: + type: string + format: uuid + deviceConfiguration: + type: string + format: uuid + devices: + type: array + items: + type: string + format: uuid + managementPolicies: + description: The list of UUID of the venues for this entity + type: array + items: + type: string + format: uuid + variables: + description: The list of UUID of the venues for this entity + type: array + items: + type: string + format: uuid + managementRoles: + description: The list of UUID of the venues for this entity + type: array + items: + type: string + format: uuid + maps: + description: The list of UUID of the venues for this entity + type: array + items: + type: string + format: uuid + configurations: + description: The list of UUID of the venues for this entity + type: array + items: + type: string + format: uuid + rrm: + type: string + enum: + - off + - on + - inherit + sourceIP: + $ref: '#/components/schemas/StringList' + + EntityList: + type: object + properties: + entities: + type: array + items: + $ref: '#/components/schemas/Entity' + + DiGraphEntry: + type: object + properties: + parent: + type: string + format: uuid + child: + type: string + format: uuid + + DiGraph: + type: array + items: + $ref: '#/components/schemas/DiGraphEntry' + + # uuids: ven: + Venue: + type: object + properties: + allOf: + $ref: '#/components/schemas/ObjectInfo' + entity: + type: string + format: uuid + parent: + type: string + format: uuid + children: + type: array + items: + type: string + format: uuid + managementPolicy: + type: string + format: uuid + devices: + type: array + items: + type: string + format: uuid + topology: + $ref: '#/components/schemas/DiGraph' + design: + type: string + deviceConfiguration: + type: string + format: uuid + contacts: + type: array + items: + type: string + format: uuid + location: + type: string + format: uuid + rrm: + type: string + enum: + - off + - on + - inherit + sourceIP: + $ref: '#/components/schemas/StringList' + managementPolicies: + description: The list of UUID of the venues for this entity + type: array + items: + type: string + format: uuid + managementRoles: + description: The list of UUID of the venues for this entity + type: array + items: + type: string + format: uuid + variables: + description: The list of UUID of the venues for this entity + type: array + items: + type: string + format: uuid + maps: + description: The list of UUID of the venues for this entity + type: array + items: + type: string + format: uuid + configurations: + description: The list of UUID of the venues for this entity + type: array + items: + type: string + format: uuid + + VenueList: + type: object + properties: + venues: + type: array + items: + $ref: '#/components/schemas/Venue' + + UserInfoDigest: + type: object + properties: + id: + type: string + format: uuid + loginId: + type: string + type: + type: string + + # uuids: mgg: + ManagementRole: + type: object + properties: + allOf: + $ref: '#/components/schemas/ObjectInfo' + managementPolicy: + type: string + format: uuid + users: + type: array + items: + type: string + format: uuid + inUse: + type: array + items: + type: string + format: uuid + example: each uuid is preceded by ent, or ven to say that the elemenet is entity or venue + entity: + type: string + format: uuid + venue: + type: string + format: uuid + + ManagementRoleList: + type: object + properties: + roles: + type: array + items: + $ref: '#/components/schemas/ManagementRole' + + # uuids: loc: + Location: + type: object + properties: + allOf: + $ref: '#/components/schemas/ObjectInfo' + type: + type: string + enum: + - SERVICE + - EQUIPMENT + - AUTO + - MANUAL + - SPECIAL + - UNKNOWN + - CORPORATE + buildingName: + type: string + addressLines: + type: array + items: + type: string + city: + type: string + state: + type: string + postal: + type: string + country: + type: string + phones: + type: array + items: + type: string + mobiles: + type: array + items: + type: string + inUse: + type: array + items: + type: string + format: uuid + example: each uuid is preceded by ent, or ven to say that the elemenet is entity or venue + entity: + type: string + format: uuid + managementPolicy: + type: string + format: uuid + geoCode: + type: string + + LocationList: + type: object + properties: + locations: + type: array + items: + $ref: '#/components/schemas/Location' + + # uuids: con: + Contact: + type: object + properties: + allOf: + $ref: '#/components/schemas/ObjectInfo' + type: + type: string + enum: + - SUBSCRIBER + - USER + - INSTALLER + - CSR + - MANAGER + - BUSINESSOWNER + - TECHNICIAN + - CORPORATE + title: + type: string + salutation: + type: string + firstname: + type: string + lastname: + type: string + initials: + type: string + visual: + type: string + phones: + type: array + items: + type: string + mobiles: + type: array + items: + type: string + primaryEmail: + type: string + secondaryEmail: + type: string + accessPIN: + type: string + inUse: + type: array + items: + type: string + format: uuid + entity: + type: string + format: uuid + managementPolicy: + type: string + format: uuid + + ContactList: + type: object + properties: + contacts: + type: array + items: + $ref: '#/components/schemas/Contact' + + DeviceConfigurationElement: + type: object + properties: + name: + type: string + description: + type: string + weight: + type: integer + configuration: + type: string + + DeviceConfiguration: + type: object + properties: + allOf: + $ref: '#/components/schemas/ObjectInfo' + managementPolicy: + type: string + format: uuid + deviceTypes: + type: array + items: + type: string + configuration: + type: array + items: + $ref: '#/components/schemas/DeviceConfigurationElement' + variables: + type: array + items: + type: string + format: uuid + inUse: + type: array + items: + type: string + format: uuid + subscriberOnly: + type: boolean + default: false + rrm: + type: string + enum: + - off + - on + - inherit + firmwareUpgrade: + type: string + example: auto or a time string of the format DOW-HH:MM + firmwareRCOnly: + type: boolean + venue: + type: string + format: uuid + entity: + type: string + format: uuid + subscriber: + type: string + format: uuid + + DeviceConfigurationList: + type: object + properties: + configurations: + type: array + items: + $ref: '#/components/schemas/DeviceConfiguration' + + InventoryTag: + type: object + properties: + allOf: + $ref: '#/components/schemas/ObjectInfo' + serialNumber: + type: string + deviceType: + type: string + venue: + type: string + format: uuid + entity: + type: string + format: uuid + subscriber: + type: string + format: uuid + qrCode: + type: string + geoCode: + type: string + location: + type: string + format: uuid + contact: + type: string + format: uuid + deviceConfiguration: + type: string + format: uuid + rrm: + type: string + enum: + - off + - on + - inherit + managementPolicy: + type: string + format: uuid + state: + type: string + devClass: + type: string + enum: + - any + - venue + - entity + - subscriber + locale: + type: string + minLength: 2 + maxLength: 2 + + InventoryTagList: + type: object + properties: + taglist: + type: array + items: + $ref: '#/components/schemas/InventoryTag' + + SerialNumberList: + type: object + properties: + serialNumbers: + type: array + items: + type: string + + CountAnswer: + type: object + properties: + count: + type: integer + format: int64 + + ExpandedUseEntry: + type: object + properties: + uuid: + type: string + format: uuid + name: + type: string + description: + type: string + + ExpandedUseEntryMap: + type: object + properties: + type: + type: string + entries: + type: array + items: + $ref: '#/components/schemas/ExpandedUseEntry' + + ExpandedUseEntryMapList: + type: object + properties: + entries: + type: array + items: + $ref: '#/components/schemas/ExpandedUseEntryMap' + + FirmwareOptions: + type: object + properties: + firmwareUpgrade: + type: string + example: auto or a time string of the format DOW-HH:MM + firmwareRCOnly: + type: boolean + from: + type: string + + InventoryConfigApplyResult: + type: object + properties: + appliedConfiguration: + type: string + errors: + type: array + items: + type: string + warnings: + type: array + items: + type: string + errorCode: + type: integer + + uuidList: + type: object + properties: + list: + type: array + items: + type: string + format: uuid + + ObjectACL: + type: object + properties: + users: + $ref: '#/components/schemas/uuidList' + roles: + $ref: '#/components/schemas/uuidList' + access: + type: string + enum: + - none + - read + - modify + - delete + - create + + ObjectACLList: + type: object + properties: + list: + type: array + items: + $ref: '#/components/schemas/ObjectACL' + + Map: + type: object + properties: + allOf: + $ref: '#/components/schemas/ObjectInfo' + entity: + type: string + format: uuid + venue: + type: string + format: uuid + managementPolicy: + type: string + format: uuid + data: + type: string + visibility: + type: string + enum: + - private + - public + - select + creator: + type: string + format: uuid + access: + $ref: '#/components/schemas/ObjectACLList' + + MapList: + type: object + properties: + list: + type: array + items: + $ref: '#/components/schemas/Map' + + + SignupEntry: + type: object + properties: + allOf: + $ref: '#/components/schemas/ObjectInfo' + email: + type: string + format: email + userId: + type: string + format: uuid + macAddress: + type: string + serialNumber: + type: string + created: + type: integer + format: int64 + completed: + type: integer + format: int64 + error: + type: integer + format: int64 + status: + type: string + statusCode: + type: integer + format: int64 + + Variable: + type: object + properties: + type: + type: string + enum: + - integer + - string + - float + - boolean + - variable + - json + weight: + type: integer + format: int64 + prefix: + type: string + value: + type: string + + VariableList: + type: object + properties: + variables: + type: array + items: + $ref: '#/components/schemas/Variable' + + VariableBlock: + type: object + properties: + allOf: + $ref: '#/components/schemas/ObjectInfo' + variables: + type: array + items: + $ref: '#/components/schemas/Variable' + entity: + type: string + format: uuid + venue: + type: string + format: uuid + subscriber: + type: string + format: uuid + inventory: + type: string + format: uuid + inUse: + type: array + items: + type: string + format: uuid + + VariableBlockList: + type: object + properties: + variableBlocks: + type: array + items: + $ref: '#/components/schemas/VariableBlock' + + ######################################################################################### + ## + ## These are endpoints that all services in the OPenWiFI stack must provide + ## + ######################################################################################### + AnyPayload: + type: object + properties: + Document: + type: string + + StringList: + type: object + properties: + list: + type: array + items: + type: string + + TagValuePair: + type: object + properties: + tag: + type: string + value: + type: string + + TagValuePairList: + type: object + properties: + tagList: + type: array + items: + $ref: '#/components/schemas/TagValuePair' + + TagIntPair: + type: object + properties: + tag: + type: string + value: + type: integer + format: int64 + + TagIntPairList: + type: object + properties: + tagList: + type: array + items: + $ref: '#/components/schemas/TagIntPair' + + SystemCommandDetails: + type: object + properties: + command: + type: string + enum: + - setloglevels + - getloglevels + - getSubSystemNames + - getLogLevelNames + - stats + parameters: + oneOf: + - $ref: '#/components/schemas/StringList' + - $ref: '#/components/schemas/TagValuePairList' + + SystemCommandResults: + type: object + oneOf: + - $ref: '#/components/schemas/StringList' + - $ref: '#/components/schemas/TagValuePairList' + + NoteInfo: + type: object + properties: + created: + type: integer + format: int64 + createdBy: + type: string + note: + type: string + + SystemInfoResults: + type: object + properties: + version: + type: string + uptime: + type: integer + format: integer64 + start: + type: integer + format: integer64 + os: + type: string + processors: + type: integer + hostname: + type: string + certificates: + type: array + items: + type: object + properties: + filename: + type: string + expires: + type: integer + format: int64 + + Dashboard: + type: object + properties: + snapshot: + type: integer + format: int64 + tenants: + $ref: '#/components/schemas/TagIntPairList' + + SystemCommandSetLogLevel: + type: object + properties: + command: + type: string + enum: + - setloglevel + subsystems: + type: array + items: + $ref: '#/components/schemas/TagValuePair' + + SystemCommandReload: + type: object + properties: + command: + type: string + enum: + - reload + subsystems: + type: array + items: + type: string + example: these are the SubSystems names retrieve with the GetSubSystemsNamesResult. + + SystemCommandGetLogLevels: + type: object + properties: + command: + type: string + enum: + - getloglevels + + SystemGetLogLevelsResult: + type: object + properties: + taglist: + type: array + items: + $ref: '#/components/schemas/TagValuePair' + + SystemCommandGetLogLevelNames: + type: object + properties: + command: + type: string + enum: + - getloglevelnames + + SystemCommandGetSubsystemNames: + type: object + properties: + command: + type: string + enum: + - getsubsystemnames + + SystemCommandGetLogLevelNamesResult: + type: object + properties: + list: + type: array + items: + type: string + + SystemGetSubSystemNamesResult: + type: object + properties: + taglist: + type: array + items: + $ref: '#/components/schemas/TagValuePair' + +paths: + /entity: + get: + tags: + - Entities + operationId: getEntities + summary: Retrieve a list of entities. + parameters: + - in: query + description: Pagination start (starts at 1. If not specified, 1 is assumed) + name: offset + schema: + type: integer + required: false + - in: query + description: Maximum number of entries to return (if absent, no limit is assumed) + name: limit + schema: + type: integer + required: false + - in: query + description: Filter the results + name: filter + schema: + type: string + required: false + - in: query + description: Supply a list of devices comma separated + name: select + schema: + type: string + example: serial1,serial2,serial3 + required: false + - in: query + description: return the number of devices + name: countOnly + schema: + type: boolean + required: false + + responses: + 200: + description: Return a list of elements + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/EntityList' + - $ref: '#/components/schemas/CountAnswer' + + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /entity/{uuid}: + get: + tags: + - Entities + operationId: getEntity + summary: Retrieve a specific entity. + parameters: + - in: path + name: uuid + schema: + type: string + format: uuid + example: When looking for the root entity, the uuid 0000-0000-0000 must be entered. + required: true + + responses: + 200: + $ref: '#/components/schemas/Entity' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + post: + tags: + - Entities + operationId: createEntity + summary: Create a specific entity. + parameters: + - in: path + name: uuid + schema: + type: string + format: uuid + example: When creating the root entity, the uuid 0000-0000-0000 must be entered. When creating a non-root entity, uuid must be 1 + required: true + requestBody: + description: Information used to create the new entity + content: + application/json: + schema: + $ref: '#/components/schemas/Entity' + + responses: + 200: + $ref: '#/components/schemas/Entity' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + put: + tags: + - Entities + operationId: modifyEntity + summary: Modify a specific entity. + parameters: + - in: path + name: uuid + schema: + type: string + format: uuid + example: When modifying the root entity, the uuid 0000-0000-0000 must be entered. + required: true + requestBody: + description: Information used to modify the new entity + content: + application/json: + schema: + $ref: '#/components/schemas/Entity' + + responses: + 200: + $ref: '#/components/schemas/Entity' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + delete: + tags: + - Entities + operationId: deleteEntity + summary: Delete a specific entity. + parameters: + - in: path + name: uuid + schema: + type: string + format: uuid + example: The root entity cannot be deleted. + required: true + + responses: + 204: + $ref: '#/components/responses/Success' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /contact: + get: + tags: + - Contacts + operationId: getContacts + summary: Retrieve a list of contacts. + parameters: + - in: query + description: Pagination start (starts at 1. If not specified, 1 is assumed) + name: offset + schema: + type: integer + required: false + - in: query + description: Maximum number of entries to return (if absent, no limit is assumed) + name: limit + schema: + type: integer + required: false + - in: query + description: Filter the results + name: filter + schema: + type: string + required: false + - in: query + description: Supply a list of contacts comma separated + name: select + schema: + type: string + example: uuid1,uuid2,uuid3 + required: false + - in: query + description: return the number of contacts + name: countOnly + schema: + type: boolean + required: false + - in: query + description: return only the UUIDs of contacts + name: uuidOnly + schema: + type: boolean + required: false + - in: query + name: venue + schema: + type: string + format: uuid + required: false + - in: query + name: entity + schema: + type: string + format: uuid + required: false + + responses: + 200: + description: Return a list of contacts + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/ContactList' + - $ref: '#/components/schemas/CountAnswer' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /contact/{uuid}: + get: + tags: + - Contacts + operationId: getContact + summary: Retrieve a specific contact. + parameters: + - in: path + name: uuid + schema: + type: string + format: uuid + required: true + - in: query + name: expandInUse + schema: + type: boolean + required: false + + responses: + 200: + description: Success + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/Contact' + - $ref: '#/components/schemas/ExpandedUseEntryMapList' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + post: + tags: + - Contacts + operationId: createContact + summary: Create a specific entity. + parameters: + - in: path + name: uuid + schema: + type: string + format: uuid + required: true + requestBody: + description: Information used to create the new entity + content: + application/json: + schema: + $ref: '#/components/schemas/Contact' + + responses: + 200: + $ref: '#/components/schemas/Contact' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + put: + tags: + - Contacts + operationId: modifyContact + summary: Modify a specific contact. + parameters: + - in: path + name: uuid + schema: + type: string + format: uuid + required: true + requestBody: + description: Information used to modify the new entity + content: + application/json: + schema: + $ref: '#/components/schemas/Contact' + + responses: + 200: + $ref: '#/components/schemas/Contact' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + delete: + tags: + - Contacts + operationId: deleteContact + summary: Delete a specific contact. + parameters: + - in: path + name: uuid + schema: + type: string + format: uuid + required: true + - in: query + name: force + schema: + type: boolean + required: true + + responses: + 204: + $ref: '#/components/responses/Success' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /location: + get: + tags: + - Locations + operationId: getLocations + summary: Retrieve a list of locations. + parameters: + - in: query + description: Pagination start (starts at 1. If not specified, 1 is assumed) + name: offset + schema: + type: integer + required: false + - in: query + description: Maximum number of entries to return (if absent, no limit is assumed) + name: limit + schema: + type: integer + required: false + - in: query + description: Filter the results + name: filter + schema: + type: string + required: false + - in: query + description: Supply a list of Locations comma separated + name: select + schema: + type: string + example: uuid1,uuid2,uuid3 + required: false + - in: query + description: return the number of Locations + name: countOnly + schema: + type: boolean + required: false + - in: query + description: return only the UUIDs of Locations + name: uuidOnly + schema: + type: boolean + required: false + + responses: + 200: + description: Return a list of Locations + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/LocationList' + - $ref: '#/components/schemas/CountAnswer' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /location/{uuid}: + get: + tags: + - Locations + operationId: getLocation + summary: Retrieve a specific location. + parameters: + - in: path + name: uuid + schema: + type: string + format: uuid + required: true + - in: query + name: expandInUse + schema: + type: boolean + required: false + + responses: + 200: + description: Success + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/Location' + - $ref: '#/components/schemas/ExpandedUseEntryMapList' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + post: + tags: + - Locations + operationId: createLocation + summary: Create a specific location. + parameters: + - in: path + name: uuid + schema: + type: string + format: uuid + required: true + requestBody: + description: Information used to create the new location + content: + application/json: + schema: + $ref: '#/components/schemas/Location' + + responses: + 200: + $ref: '#/components/schemas/Location' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + put: + tags: + - Locations + operationId: modifyLocation + summary: Modify a specific location. + parameters: + - in: path + name: uuid + schema: + type: string + format: uuid + required: true + requestBody: + description: Information used to modify the new location + content: + application/json: + schema: + $ref: '#/components/schemas/Location' + + responses: + 200: + $ref: '#/components/schemas/Location' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + delete: + tags: + - Locations + operationId: deleteLocation + summary: Delete a specific location. + parameters: + - in: path + name: uuid + schema: + type: string + format: uuid + required: true + - in: query + name: force + schema: + type: boolean + required: true + + responses: + 204: + $ref: '#/components/responses/Success' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /inventory: + get: + tags: + - Inventory + operationId: getInventoryTags + summary: Retrieve a list of inventory. + parameters: + - in: query + name: entity + schema: + type: string + format: uuid + required: false + - in: query + name: venue + schema: + type: string + format: uuid + required: false + - in: query + name: unassigned + schema: + type: boolean + required: false + - in: query + name: deviceType + schema: + type: string + required: false + - in: query + description: Pagination start (starts at 1. If not specified, 1 is assumed) + name: offset + schema: + type: integer + required: false + - in: query + description: Maximum number of entries to return (if absent, no limit is assumed) + name: limit + schema: + type: integer + required: false + - in: query + description: Filter the results + name: filter + schema: + type: string + required: false + - in: query + description: Supply a list of devices comma separated + name: select + schema: + type: string + example: serial1,serial2,serial3 + required: false + - in: query + description: only serial numbers of full device details + name: serialOnly + schema: + type: boolean + required: false + - in: query + description: return the number of devices + name: countOnly + schema: + type: boolean + required: false + - in: query + description: return extended information + name: withExtendedInfo + schema: + type: boolean + required: false + - in: query + description: return extended information + name: orderBy + schema: + type: string + example: serialNumber:a,created:d + required: false + - in: query + description: return the list of devices under RRM + name: rrmOnly + schema: + type: boolean + default: false + required: false + - in: query + description: return the list of devices under RRM + name: subscriber + schema: + type: string + format: uuid + required: false + responses: + 200: + description: Return a list of elements + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/SerialNumberList' + - $ref: '#/components/schemas/InventoryTagList' + - $ref: '#/components/schemas/CountAnswer' + 400: + $ref: '#/components/responses/BadRequest' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /inventory/{serialNumber}: + get: + tags: + - Inventory + operationId: getInventory + summary: Retrieve a specific inventory tag. + parameters: + - in: path + name: serialNumber + schema: + type: string + format: uuid + required: true + - in: query + name: config + schema: + type: boolean + required: false + - in: query + name: explain + schema: + type: boolean + required: false + - in: query + name: firmwareOptions + schema: + type: boolean + required: false + - in: query + name: applyConfiguration + schema: + type: boolean + required: false + responses: + 200: + description: Succesful retrieve configuratiopn or part of the configuration + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/InventoryTag' + - $ref: '#/components/schemas/FirmwareOptions' + - $ref: '#/components/schemas/InventoryConfigApplyResult' + 400: + $ref: '#/components/responses/BadRequest' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + post: + tags: + - Inventory + operationId: createInventory + summary: Create a specific Inventory. + parameters: + - in: path + name: serialNumber + schema: + type: string + format: uuid + required: true + requestBody: + description: Information used to create the new entity + content: + application/json: + schema: + $ref: '#/components/schemas/InventoryTag' + responses: + 200: + $ref: '#/components/schemas/InventoryTag' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + put: + tags: + - Inventory + operationId: modifyInventory + summary: Modify a specific inventory. + parameters: + - in: path + name: serialNumber + schema: + type: string + format: uuid + required: true + - in: query + name: unassign + schema: + type: boolean + required: false + - in: path + name: removeSubscriber + schema: + type: string + format: uuid + required: true + + requestBody: + description: Information used to modify the new entity + content: + application/json: + schema: + $ref: '#/components/schemas/InventoryTag' + + responses: + 200: + description: success + content: + application/json: + schema: + $ref: '#/components/schemas/InventoryTag' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + delete: + tags: + - Inventory + operationId: deleteInventory + summary: Delete a specific inventory. + parameters: + - in: path + name: serialNumber + schema: + type: string + format: uuid + required: true + + responses: + 204: + $ref: '#/components/responses/Success' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /venue: + get: + tags: + - Venues + operationId: getVenues + summary: Retrieve a list of venues. + parameters: + - in: query + name: entity + schema: + type: string + format: uuid + required: false + - in: query + name: venue + schema: + type: string + format: uuid + required: false + - in: query + name: unassigned + schema: + type: boolean + required: false + - in: query + name: deviceType + schema: + type: string + required: false + - in: query + description: Pagination start (starts at 1. If not specified, 1 is assumed) + name: offset + schema: + type: integer + required: false + - in: query + description: Maximum number of entries to return (if absent, no limit is assumed) + name: limit + schema: + type: integer + required: false + - in: query + description: Filter the results + name: filter + schema: + type: string + required: false + - in: query + description: Supply a list of Venues comma separated + name: select + schema: + type: string + example: serial1,serial2,serial3 + required: false + - in: query + description: only serial numbers of full device details + name: serialOnly + schema: + type: boolean + required: false + - in: query + description: return the number of devices + name: countOnly + schema: + type: boolean + required: false + + responses: + 200: + description: Return a list of venues. + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/VenueList' + - $ref: '#/components/schemas/CountAnswer' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /venue/{uuid}: + get: + tags: + - Venues + operationId: getVenue + summary: Retrieve a specific venue. + parameters: + - in: path + name: uuid + schema: + type: string + format: uuid + required: true + + responses: + 200: + $ref: '#/components/schemas/Venue' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + post: + tags: + - Venues + operationId: createVenue + summary: Create a specific venue. + parameters: + - in: path + name: uuid + schema: + type: string + format: uuid + required: true + - in: query + name: createObjects + schema: + type: object + properties: + objects: + type: array + items: + oneOf: + - type: object + properties: + location: + $ref: '#/components/schemas/Location' + - type: object + properties: + contact: + $ref: '#/components/schemas/Contact' + required: false + requestBody: + description: Information used to create the new venue + content: + application/json: + schema: + $ref: '#/components/schemas/Venue' + + responses: + 200: + $ref: '#/components/schemas/Venue' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + put: + tags: + - Venues + operationId: modifyVenue + summary: Modify a specific venue. + parameters: + - in: path + name: uuid + schema: + type: string + format: uuid + required: true + requestBody: + description: Information used to modify the new venue + content: + application/json: + schema: + $ref: '#/components/schemas/Venue' + + responses: + 200: + $ref: '#/components/schemas/Venue' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + delete: + tags: + - Venues + operationId: deleteVenue + summary: Delete a specific venue. + parameters: + - in: path + name: uuid + schema: + type: string + format: uuid + example: The root entity cannot be deleted. + required: true + + responses: + 204: + $ref: '#/components/responses/Success' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /map: + get: + tags: + - Maps + operationId: getMapList + summary: Retrieve the list of maps + parameters: + - in: query + description: Pagination start (starts at 1. If not specified, 1 is assumed) + name: offset + schema: + type: integer + required: false + - in: query + description: Maximum number of entries to return (if absent, no limit is assumed) + name: limit + schema: + type: integer + required: false + - in: query + description: Filter the results + name: filter + schema: + type: string + required: false + - in: query + description: Return only maps I created + name: myMaps + schema: + type: boolean + required: false + - in: query + description: Return only maps shared with Me + name: sharedWithMe + schema: + type: boolean + required: false + + responses: + 200: + description: Return a list of Venues + content: + application/json: + schema: + $ref: '#/components/schemas/MapList' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /map/{uuid}: + get: + tags: + - Maps + operationId: getMap + summary: Retrieve a specific map. + parameters: + - in: path + name: uuid + schema: + type: string + format: uuid + required: true + + responses: + 200: + description: Successfull retrieval of a map + content: + application/json: + schema: + $ref: '#/components/schemas/Map' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + post: + tags: + - Maps + operationId: createMap + summary: Create a specific map. + parameters: + - in: path + name: uuid + schema: + type: string + format: uuid + required: true + requestBody: + description: Information used to create the new policy + content: + application/json: + schema: + $ref: '#/components/schemas/Map' + + responses: + 200: + $ref: '#/components/schemas/Map' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + put: + tags: + - Maps + operationId: modifyMap + summary: Modify a specific map. + parameters: + - in: path + name: uuid + schema: + type: string + format: uuid + required: true + requestBody: + description: Information used to modify a map + content: + application/json: + schema: + $ref: '#/components/schemas/Map' + + responses: + 200: + $ref: '#/components/schemas/ManagementPolicy' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + delete: + tags: + - Maps + operationId: deleteMap + summary: Delete a specific map. + parameters: + - in: path + name: uuid + schema: + type: string + format: uuid + required: true + responses: + 204: + $ref: '#/components/responses/Success' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /managementPolicy: + get: + tags: + - Management Policies + operationId: getPolicies + summary: Get a list of policies. + parameters: + - in: query + name: entity + schema: + type: string + format: uuid + required: false + - in: query + name: venue + schema: + type: string + format: uuid + required: false + - in: query + name: unassigned + schema: + type: boolean + required: false + - in: query + description: Pagination start (starts at 1. If not specified, 1 is assumed) + name: offset + schema: + type: integer + required: false + - in: query + description: Maximum number of entries to return (if absent, no limit is assumed) + name: limit + schema: + type: integer + required: false + - in: query + description: Filter the results + name: filter + schema: + type: string + required: false + - in: query + description: Supply a list of policies comma separated + name: select + schema: + type: string + example: serial1,serial2,serial3 + required: false + - in: query + description: return the number of policies + name: countOnly + schema: + type: boolean + required: false + + responses: + 200: + description: Return a list of Venues + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/ManagementPolicyList' + - $ref: '#/components/schemas/CountAnswer' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /managementPolicy/{uuid}: + get: + tags: + - Management Policies + operationId: getManagementPolicy + summary: Retrieve a specific policy. + parameters: + - in: path + name: uuid + schema: + type: string + format: uuid + required: true + - in: query + name: expandInUse + schema: + type: boolean + required: false + + responses: + 200: + description: Succesful retrieve a management policy + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/ManagementPolicy' + - $ref: '#/components/schemas/ExpandedUseEntryMapList' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + post: + tags: + - Management Policies + operationId: createManagementPolicy + summary: Create a specific policy. + parameters: + - in: path + name: uuid + schema: + type: string + format: uuid + required: true + requestBody: + description: Information used to create the new policy + content: + application/json: + schema: + $ref: '#/components/schemas/ManagementPolicy' + + responses: + 200: + $ref: '#/components/schemas/ManagementPolicy' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + put: + tags: + - Management Policies + operationId: modifyManagementPolicy + summary: Modify a specific policy. + parameters: + - in: path + name: uuid + schema: + type: string + format: uuid + required: true + requestBody: + description: Information used to modify the new policy. + content: + application/json: + schema: + $ref: '#/components/schemas/ManagementPolicy' + + responses: + 200: + $ref: '#/components/schemas/ManagementPolicy' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + delete: + tags: + - Management Policies + operationId: deleteManagementPolicy + summary: Delete a specific policy. + parameters: + - in: path + name: uuid + schema: + type: string + format: uuid + example: The root entity cannot be deleted. + required: true + + responses: + 204: + $ref: '#/components/responses/Success' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /managementRole: + get: + tags: + - Management Roles + operationId: getManagementRoles + summary: Retrieve a list of management roles. + parameters: + - in: query + name: entity + schema: + type: string + format: uuid + required: false + - in: query + description: Pagination start (starts at 1. If not specified, 1 is assumed) + name: offset + schema: + type: integer + required: false + - in: query + description: Maximum number of entries to return (if absent, no limit is assumed) + name: limit + schema: + type: integer + required: false + - in: query + description: Filter the results + name: filter + schema: + type: string + required: false + - in: query + description: Supply a list of devices comma separated + name: select + schema: + type: string + example: serial1,serial2,serial3 + required: false + - in: query + description: return the number of roles + name: countOnly + schema: + type: boolean + required: false + + responses: + 200: + description: Return a list of elements + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/ManagementRoleList' + - $ref: '#/components/schemas/CountAnswer' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /managementRole/{uuid}: + get: + tags: + - Management Roles + operationId: getManagementRole + summary: Retrieve a specific management role. + parameters: + - in: path + name: uuid + required: true + schema: + type: string + format: uuid + - in: query + name: expandInUse + schema: + type: boolean + required: false + responses: + 200: + description: Success + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/ManagementRole' + - $ref: '#/components/schemas/ExpandedUseEntryMapList' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + post: + tags: + - Management Roles + operationId: createManagementRole + summary: Create a specific management role. + parameters: + - in: path + name: uuid + required: true + schema: + type: string + format: uuid + example: during creation, must be set to 1. The real uuid will be returned in the created object + requestBody: + description: Information used to create management role + content: + application/json: + schema: + $ref: '#/components/schemas/ManagementRole' + + responses: + 200: + $ref: '#/components/schemas/ManagementRole' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + put: + tags: + - Management Roles + operationId: modifyManagementRole + summary: Modify a specific management role. + parameters: + - in: path + name: uuid + required: true + schema: + type: string + format: uuid + requestBody: + description: Information used to modify management role + content: + application/json: + schema: + $ref: '#/components/schemas/ManagementRole' + + responses: + 200: + $ref: '#/components/schemas/ManagementRole' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + delete: + tags: + - Management Roles + operationId: deleteManagementRole + summary: Delete a specific management role. + parameters: + - in: path + name: uuid + required: true + schema: + type: string + format: uuid + responses: + 204: + $ref: '#/components/responses/Success' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /configurations: + get: + tags: + - Configurations + operationId: getConfigurations + summary: Retrieve a list of configurations. + parameters: + - in: query + description: Pagination start (starts at 1. If not specified, 1 is assumed) + name: offset + schema: + type: integer + required: false + - in: query + description: Maximum number of entries to return (if absent, no limit is assumed) + name: limit + schema: + type: integer + required: false + - in: query + description: Filter the results + name: filter + schema: + type: string + required: false + - in: query + description: Supply a list of devices comma separated + name: select + schema: + type: string + example: serial1,serial2,serial3 + required: false + - in: query + description: return the number of devices + name: countOnly + schema: + type: boolean + required: false + - in: query + name: venue + schema: + type: string + format: uuid + required: false + - in: query + name: entity + schema: + type: string + format: uuid + required: false + + responses: + 200: + description: Return a list of elements + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/DeviceConfigurationList' + - $ref: '#/components/schemas/CountAnswer' + + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /configurations/{uuid}: + get: + tags: + - Configurations + operationId: geConfiguration + summary: Retrieve a specific configuration. + parameters: + - in: path + name: uuid + schema: + type: string + format: uuid + example: When looking for the root entity, the uuid 0000-0000-0000 must be entered. + required: true + - in: query + name: expandInUse + schema: + type: boolean + required: false + + responses: + 200: + description: Success + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/DeviceConfiguration' + - $ref: '#/components/schemas/ExpandedUseEntryMapList' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + post: + tags: + - Configurations + operationId: createConfiguration + summary: Create a specific configuration. + parameters: + - in: path + name: uuid + schema: + type: string + format: uuid + example: When creating the root entity, the uuid 0000-0000-0000 must be entered. When creating a non-root entity, uuid must be 1 + required: true + - in: query + name: validateOnly + schema: + type: boolean + required: false + requestBody: + description: Information used to create the new entity + content: + application/json: + schema: + $ref: '#/components/schemas/DeviceConfiguration' + + responses: + 200: + $ref: '#/components/schemas/DeviceConfiguration' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + put: + tags: + - Configurations + operationId: modifyConfiguration + summary: Modify a specific configuration. + parameters: + - in: path + name: uuid + schema: + type: string + format: uuid + example: When modifying the root entity, the uuid 0000-0000-0000 must be entered. + required: true + requestBody: + description: Information used to modify the new entity + content: + application/json: + schema: + $ref: '#/components/schemas/DeviceConfiguration' + + responses: + 200: + $ref: '#/components/schemas/DeviceConfiguration' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + delete: + tags: + - Configurations + operationId: deleteConfiguration + summary: Delete a specific configuration. + parameters: + - in: path + name: uuid + schema: + type: string + format: uuid + example: The root entity cannot be deleted. + required: true + + responses: + 204: + $ref: '#/components/responses/Success' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /iptocountry: + get: + tags: + - Utility + summary: Get the country code for an IP address + operationId: getIpToCountry + parameters: + - in: query + name: iplist + schema: + type: string + example: + 10.2.2.2,10.3.4.3 + required: true + responses: + 200: + description: List of country codes. + content: + application/json: + schema: + type: object + properties: + enabled: + type: boolean + countryCodes: + type: array + items: + type: string + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /signup: + get: + tags: + - Subscriber Registration + summary: This call allows someone to get the status of a signup. + operationId: getSignup + parameters: + - in: query + name: email + schema: + type: string + format: email + required: false + - in: query + name: macAddress + schema: + type: string + required: false + - in: query + name: signupUUID + schema: + type: string + format: uuid + required: false + - in: query + name: dashboard + schema: + type: boolean + default: false + required: false + - in: query + name: deviceID + schema: + type: string + required: false + responses: + 200: + description: Successfull completion + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/SignupEntry' + - $ref: '#/components/schemas/Dashboard' + 400: + $ref: '#/components/responses/BadRequest' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + delete: + tags: + - Subscriber Registration + summary: This call allows someone to delete a specific signUp or all signups according to serialNumber of email address + operationId: deleteSignup + parameters: + - in: query + name: email + schema: + type: string + format: email + required: false + - in: query + name: macAddress + schema: + type: string + required: false + - in: query + name: signupUUID + schema: + type: string + format: uuid + required: false + - in: query + name: deviceID + schema: + type: string + required: false + responses: + 204: + $ref: '#/components/responses/Success' + 400: + $ref: '#/components/responses/BadRequest' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + post: + tags: + - Subscriber Registration + summary: This call allows a new subscriber to register themselves and their devices. + operationId: postSignup + parameters: + - in: query + name: email + schema: + type: string + format: email + required: true + - in: query + name: macAddress + schema: + type: string + required: true + - in: query + name: deviceID + schema: + type: string + required: false + responses: + 200: + $ref: '#/components/schemas/SignupEntry' + 400: + $ref: '#/components/responses/BadRequest' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + put: + tags: + - Subscriber Registration + summary: modify the signup command in play + operationId: modifySignup + parameters: + - in: query + name: signupUUID + schema: + type: string + format: uuid + required: true + - in: query + name: operation + schema: + type: string + enum: + - cancel + - emailVerified + - deviceVerified + required: true + requestBody: + content: + application/json: + schema: + type: object + properties: + reason: + type: string + time: + type: integer + format: int64 + errorCode: + type: integer + format: int32 + status: + type: string + required: false + + responses: + 200: + $ref: '#/components/schemas/SignupEntry' + 400: + $ref: '#/components/responses/BadRequest' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /variables: + get: + tags: + - Variable Configuration Blocks + summary: Retrieve lists of control blocks + operationId: getVariableList + parameters: + - in: query + name: venue + schema: + type: string + format: uuid + required: false + - in: query + name: entity + schema: + type: string + format: uuid + required: false + - in: query + description: Pagination start (starts at 1. If not specified, 1 is assumed) + name: offset + schema: + type: integer + required: false + - in: query + description: Maximum number of entries to return (if absent, no limit is assumed) + name: limit + schema: + type: integer + required: false + - in: query + description: Filter the results + name: filter + schema: + type: string + required: false + - in: query + description: Supply a list of devices comma separated + name: select + schema: + type: string + example: serial1,serial2,serial3 + required: false + - in: query + description: return the number of devices + name: countOnly + schema: + type: boolean + required: false + responses: + 200: + $ref: '#/components/schemas/VariableBlockList' + 400: + $ref: '#/components/responses/BadRequest' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + ######################################################################################### + ## + ## These are endpoints that all services in the OpenWiFi stack must provide + ## + ######################################################################################### + /dashboard: + get: + tags: + - Dashboards + summary: Get the last version of the dashboard. + operationId: getDeviceDashboard + responses: + 200: + $ref: '#/components/schemas/Dashboard' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /system: + post: + tags: + - System Commands + summary: Perform some system wide commands. + operationId: systemCommand + requestBody: + description: Command details + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/SystemCommandSetLogLevel' + - $ref: '#/components/schemas/SystemCommandReload' + - $ref: '#/components/schemas/SystemCommandGetLogLevels' + - $ref: '#/components/schemas/SystemCommandGetLogLevelNames' + - $ref: '#/components/schemas/SystemCommandGetSubsystemNames' + responses: + 200: + description: Successful command execution + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/SystemGetLogLevelsResult' + - $ref: '#/components/schemas/SystemCommandGetLogLevelNamesResult' + - $ref: '#/components/schemas/SystemGetSubSystemNamesResult' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + get: + tags: + - System Commands + summary: Retrieve different values from the running service. + operationId: getSystemCommand + parameters: + - in: query + description: Get a value + name: command + schema: + type: string + enum: + - info + required: true + + responses: + 200: + description: Successful command execution + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/SystemInfoResults' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' diff --git a/.gitbook/assets/owsec.yaml b/.gitbook/assets/owsec.yaml new file mode 100644 index 0000000..13f6f99 --- /dev/null +++ b/.gitbook/assets/owsec.yaml @@ -0,0 +1,1207 @@ +openapi: 3.0.1 +info: + title: uCentral Security API + description: A process to manage security logins. + version: 2.0.0 + license: + name: BSD3 + url: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE + contact: + name: Arilia Support + email: ucentralsupport@arilia.com + url: https://www.ucentral.info/support + +servers: + - url: 'https://localhost:16001/api/v1' + +security: + - bearerAuth: [] + - ApiKeyAuth: [] + +components: + securitySchemes: + ApiKeyAuth: + type: apiKey + in: header + name: X-API-KEY + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT + + responses: + NotFound: + description: The specified resource was not found. + content: + application/json: + schema: + properties: + ErrorCode: + type: integer + ErrorDetails: + type: string + ErrorDescription: + type: string + + Unauthorized: + description: The requested does not have sufficient rights to perform the operation. + content: + application/json: + schema: + properties: + ErrorCode: + type: integer + enum: + - 0 # Success + - 1 # PASSWORD_CHANGE_REQUIRED, + - 2 # INVALID_CREDENTIALS, + - 3 # PASSWORD_ALREADY_USED, + - 4 # USERNAME_PENDING_VERIFICATION, + - 5 # PASSWORD_INVALID, + - 6 # INTERNAL_ERROR, + - 7 # ACCESS_DENIED, + - 8 # INVALID_TOKEN + - 9 # expired token + - 10 # rate limit exceeded + ErrorDetails: + type: string + ErrorDescription: + type: string + + Success: + description: The requested operation was performed. + content: + application/json: + schema: + properties: + Operation: + type: string + Details: + type: string + Code: + type: integer + + schemas: + + WebTokenRequest: + description: User Id and password. + type: object + required: + - userId + - password + properties: + userId: + type: string + default: support@example.com + password: + type: string + default: support + newPassword: + type: string + default: support + refreshToken: + type: string + example: + userId: support@example.com + password: support + + WebTokenResult: + description: Login and Refresh Tokens to be used in subsequent API calls. + type: object + properties: + access_token: + type: string + refresh_token: + type: string + token_type: + type: string + expires_in: + type: integer + format: int32 + idle_timeout: + type: integer + format: int32 + username: + type: string + created: + type: integer + format: int64 + userMustChangePassword: + type: boolean + errorCode: + type: integer # 0 = no error, 1 = passwordAlreadyUsed, 2=invalidPassword + aclTemplate: + $ref: '#/components/schemas/WebTokenAclTemplate' + + WebTokenAclTemplate: + type: object + properties: + aclTemplate: + $ref: '#/components/schemas/AclTemplate' + + ApiKeyCreationRequest: + type: object + properties: + name: + type: string + description: + type: string + expiresOn: + type: integer + format: int64 + rights: + $ref: '#/components/schemas/AclTemplate' + + ApiKeyCreationAnswer: + type: object + properties: + UUID: + type: string + format: uuid + name: + type: string + created: + type: integer + format: int64 + expiresOn: + type: integer + format: int64 + apiKey: + type: string + rights: + $ref: '#/components/schemas/AclTemplate' + + AclTemplate: + type: object + properties: + Read: + type: boolean + ReadWrite: + type: boolean + ReadWriteCreate: + type: boolean + Delete: + type: boolean + PortalLogin: + type: boolean + + SystemEndpoint: + type: object + properties: + type: + type: string + id: + type: integer + vendor: + type: string + uri: + type: string + format: uri + authenticationType: + type: string + + SystemEndpointList: + type: object + properties: + endpoints: + type: array + items: + $ref: '#/components/schemas/SystemEndpoint' + + MobilePhoneNumber: + type: object + properties: + number: + type: string + verified: + type: boolean + primary: + type: boolean + + MfaAuthInfo: + type: object + properties: + enabled: + type: boolean + method: + type: string + enum: + - sms + - email + - voice + + UserLoginLoginExtensions: + type: object + properties: + mobiles: + type: array + items: + $ref: '#/components/schemas/MobilePhoneNumber' + mfa: + $ref: '#/components/schemas/MfaAuthInfo' + + UserInfo: + type: object + properties: + id: + type: string + format: uuid + name: + type: string + description: + type: string + avatar: + type: string + format: uri + email: + type: string + format: email + validated: + type: boolean + validationEmail: + type: string + format: email + validationDate: + type: integer + format: int64 + created: + type: integer + format: int64 + validationURI: + type: string + changePassword: + type: boolean + lastLogin: + type: integer + format: int64 + currentLoginURI: + type: string + lastPasswordChange: + type: integer + format: int64 + lastEmailCheck: + type: integer + format: int64 + currentPassword: + type: string + lastPasswords: + type: array + items: + type: string + waitingForEmailCheck: + type: boolean + notes: + type: array + items: + $ref: '#/components/schemas/NoteInfo' + location: + type: string + format: uuid + owner: + type: string + format: uuid + suspended: + type: boolean + blackListed: + type: boolean + locale: + type: string + userRole: + type: string + enum: + - root + - admin + - subscriber + - csr + - system + - installer + - noc + - accounting + oauthType: + type: string + enum: + - internal + - normal + - gmail + - facebook + - linkedin + - instagram + oauthUserInfo: + type: string + securityPolicy: + type: string + securityPolicyChange: + type: integer + format: int64 + userTypeProprietaryInfo: + $ref: '#/components/schemas/UserLoginLoginExtensions' + + UserList: + type: object + properties: + users: + type: array + items: + $ref: '#/components/schemas/UserInfo' + + EMailInfo: + type: object + properties: + from: + type: string + format: email + subject: + type: string + recipients: + type: array + items: + type: string + format: email + text: + type: string + + SMSInfo: + type: object + properties: + from: + type: string + to: + type: string + text: + type: string + + MFAChallengeRequest: + type: object + properties: + uuid: + type: string + format: uuid + question: + type: string + created: + type: integer + format: integer64 + method: + type: string + + MFAChallengeResponse: + type: object + properties: + uuid: + type: string + format: uuid + answer: + type: string + + ######################################################################################### + ## + ## These are endpoints that all services in the uCentral stack must provide + ## + ######################################################################################### + AnyPayload: + type: object + properties: + Document: + type: string + + StringList: + type: object + properties: + list: + type: array + items: + type: string + + TagValuePair: + type: object + properties: + tag: + type: string + value: + type: string + + TagValuePairList: + type: object + properties: + tagList: + type: array + items: + $ref: '#/components/schemas/TagValuePair' + + NoteInfo: + type: object + properties: + created: + type: integer + format: int64 + createdBy: + type: string + note: + type: string + + SystemCommandDetails: + type: object + properties: + command: + type: string + enum: + - setloglevels + - getloglevels + - getSubSystemNames + - getLogLevelNames + - stats + parameters: + oneOf: + - $ref: '#/components/schemas/StringList' + - $ref: '#/components/schemas/TagValuePairList' + + SystemCommandResults: + type: object + oneOf: + - $ref: '#/components/schemas/StringList' + - $ref: '#/components/schemas/TagValuePairList' + + SystemInfoResults: + type: object + properties: + version: + type: string + uptime: + type: integer + format: integer64 + start: + type: integer + format: integer64 + os: + type: string + processors: + type: integer + hostname: + type: string + certificates: + type: array + items: + type: object + properties: + filename: + type: string + expires: + type: integer + format: int64 + + ProfileAction: + type: object + properties: + resource: + type: string + access: + type: string + enum: + - NONE + - READ + - MODIFY + - DELETE + - CREATE + - TEST + - MOVE + + SecurityProfile: + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + description: + type: string + policy: + type: array + items: + $ref: '#/components/schemas/ProfileAction' + role: + type: string + notes: + type: array + items: + $ref: '#/components/schemas/NoteInfo' + + SecurityProfileList: + type: object + properties: + profiles: + type: array + items: + $ref: '#/components/schemas/SecurityProfile' + + InternalServiceInfo: + type: object + properties: + privateURI: + type: string + publicURI: + type: string + token: + type: string + + InternalSystemServices: + type: object + properties: + key: + type: string + version: + type: integer + services: + type: array + items: + $ref: '#/components/schemas/InternalServiceInfo' + + TokenValidationResult: + type: object + properties: + userInfo: + $ref: '#/components/schemas/UserInfo' + tokenInfo: + $ref: '#/components/schemas/WebTokenResult' + + SystemCommandSetLogLevel: + type: object + properties: + command: + type: string + enum: + - setloglevel + subsystems: + type: array + items: + $ref: '#/components/schemas/TagValuePair' + + SystemCommandReload: + type: object + properties: + command: + type: string + enum: + - reload + subsystems: + type: array + items: + type: string + example: these are the SubSystems names retrieve with the GetSubSystemsNamesResult. + + SystemCommandGetLogLevels: + type: object + properties: + command: + type: string + enum: + - getloglevels + + SystemGetLogLevelsResult: + type: object + properties: + taglist: + type: array + items: + $ref: '#/components/schemas/TagValuePair' + + SystemCommandGetLogLevelNames: + type: object + properties: + command: + type: string + enum: + - getloglevelnames + + SystemCommandGetSubsystemNames: + type: object + properties: + command: + type: string + enum: + - getsubsystemnames + + SystemCommandGetLogLevelNamesResult: + type: object + properties: + list: + type: array + items: + type: string + + SystemGetSubSystemNemesResult: + type: object + properties: + taglist: + type: array + items: + $ref: '#/components/schemas/TagValuePair' + + ######################################################################################### + ## + ## End of uCentral system wide values + ## + ######################################################################################### + +paths: + /oauth2: + post: + tags: + - Authentication + summary: Get access token - to be used as Bearer token header for all other API requests. + operationId: getAccessToken + parameters: + - in: query + name: newPassword + description: used when a user is trying to change her password. This will be the new password. + schema: + type: string + required: false + - in: query + name: forgotPassword + description: A user forgot her password. She needs to present her e-mail address in the userId and set this to true + schema: + type: boolean + required: false + - in: query + name: requirements + description: A user forgot her password. She needs to present her e-mail address in the userId and set this to true + schema: + type: boolean + required: false + - in: query + name: resendMFACode + schema: + type: boolean + required: false + - in: query + name: completeMFAChallenge + schema: + type: boolean + required: false + requestBody: + description: User id and password + required: true + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/WebTokenRequest' + - $ref: '#/components/schemas/MFAChallengeResponse' + responses: + 200: + description: successful operation + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/WebTokenResult' + - $ref: '#/components/schemas/MFAChallengeRequest' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /oauth2/{token}: + delete: + tags: + - Authentication + summary: Revoke a token. + operationId: removeAccessToken + parameters: + - in: path + name: token + schema: + type: + string + required: true + responses: + 204: + description: successful operation + content: + application/json: + schema: + $ref: '#/components/responses/Success' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /systemEndpoints: + get: + tags: + - Authentication + summary: Retrieve the system layout. + operationId: getSystemInfo + responses: + 200: + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/SystemEndpointList' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /users: + get: + tags: + - User Management + summary: Retrieve a list of existing users as well as some information about them. + operationId: getUsers + parameters: + - in: query + name: offset + schema: + type: integer + format: int64 + required: false + - in: query + name: limit + schema: + type: integer + format: int64 + required: false + - in: query + description: Selecting this option means the newest record will be returned. Use limit to select how many. + name: filter + schema: + type: string + required: false + - in: query + description: Return only the ids. + name: idOnly + schema: + type: boolean + required: false + - in: query + description: Return only the ids. + name: select + schema: + type: string + example: id1,id2,id3,id4,id5 + required: false + responses: + 200: + $ref: '#/components/schemas/UserList' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /user/{id}: + get: + tags: + - User Management + operationId: getUser + summary: Retrieve the information for a single user. + parameters: + - in: path + name: id + schema: + type: string + format: uuid + required: true + responses: + 200: + $ref: '#/components/schemas/UserInfo' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + delete: + tags: + - User Management + operationId: deleteUser + summary: Delete a single user. + parameters: + - in: path + name: id + schema: + type: integer + format: int64 + required: true + responses: + 204: + $ref: '#/components/responses/Success' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + post: + tags: + - User Management + operationId: createUser + summary: Create a single user. + parameters: + - in: path + name: id + #must be set to 0 for user creation + schema: + type: integer + format: int64 + required: true + - in: query + name: email_verification + schema: + type: boolean + required: false + requestBody: + description: User details (some fields are ignored during creation) + content: + application/json: + schema: + $ref: '#/components/schemas/UserInfo' + responses: + 200: + $ref: '#/components/schemas/UserInfo' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + put: + tags: + - User Management + operationId: updateUser + summary: Modify a single user. + parameters: + - in: path + name: id + schema: + type: integer + format: int64 + required: true + - in: query + name: email_verification + schema: + type: boolean + required: false + requestBody: + description: User details (some fields are ignored during update) + content: + application/json: + schema: + $ref: '#/components/schemas/UserInfo' + responses: + 200: + $ref: '#/components/schemas/UserInfo' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /avatar/{id}: + get: + tags: + - Avatar + operationId: getAvatar + summary: Retrieve the avatar associated with a user ID. + parameters: + - in: path + name: id + schema: + type: string + format: uuid + required: true + + responses: + 200: + description: Successfully retrieved the avatar + content: + image/jpeg: + schema: + type: string + format: binary + image/png: + schema: + type: string + format: binary + image/svg+xml: + schema: + type: string + format: binary + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + delete: + tags: + - Avatar + operationId: deleteAvatar + summary: Remove an avatar associated with a user ID. + parameters: + - in: path + name: id + schema: + type: string + format: uuid + required: true + responses: + 204: + $ref: '#/components/responses/Success' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + post: + tags: + - Avatar + operationId: createAvatar + summary: Create an avatar associated with a user ID. + parameters: + - in: path + name: id + schema: + type: string + format: uuid + required: true + requestBody: + description: User id and password + required: true + content: + image/jpeg: + schema: + type: string + format: binary + image/png: + schema: + type: string + format: binary + image/svg+xml: + schema: + type: string + format: binary + + responses: + 200: + $ref: '#/components/responses/Success' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /email: + post: + tags: + - Email + summary: Send test email with the system. + operationId: Send a test email + requestBody: + description: The requested message + content: + application/json: + schema: + $ref: '#/components/schemas/EMailInfo' + responses: + 200: + $ref: '#/components/responses/Success' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + 500: + description: Error description + content: + application/json: + schema: + type: object + properties: + errors: + type: array + items: + type: string + + /sms: + post: + tags: + - Email + summary: Send test email with the system. + operationId: Send a test SMS + parameters: + - in: query + name: validateNumber + schema: + type: boolean + required: false + - in: query + name: completeValidation + schema: + type: boolean + required: false + - in: query + name: validationCode + schema: + type: string + required: false + requestBody: + description: The requested message + content: + application/json: + schema: + $ref: '#/components/schemas/SMSInfo' + responses: + 200: + $ref: '#/components/responses/Success' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + 500: + description: Error description + content: + application/json: + schema: + type: object + properties: + errors: + type: array + items: + type: string + + ######################################################################################### + ## + ## These are endpoints that all services in the uCentral stack must provide + ## + ######################################################################################### + /securityProfiles: + get: + tags: + - Security + summary: Retrieve the list of security profiles for a specific service type. + operationId: getSecurituProfiles + parameters: + - in: query + description: Pagination start (starts at 1. If not specified, 1 is assumed) + name: offset + schema: + type: integer + required: false + - in: query + description: Maximum number of entries to return (if absent, no limit is assumed) + name: limit + schema: + type: integer + required: false + - in: query + description: Filter the results + name: filter + schema: + type: string + required: false + responses: + 200: + $ref: '#/components/schemas/SecurityProfileList' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + ######################################################################################### + ## The following calls are restricted to the private system side APIs + ######################################################################################### + /systemServices: + get: + tags: + - Security + summary: Retrieve the basic system information. This information is used between services only. + operationId: getSystemServices + responses: + 200: + $ref: '#/components/schemas/InternalSystemServices' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /validateToken: + get: + tags: + - Security + summary: Allows any microservice to validate a token and get security policy for a specific user. + operationId: validateToken + parameters: + - in: query + name: token + schema: + type: string + required: true + responses: + 200: + $ref: '#/components/schemas/TokenValidationResult' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /system: + post: + tags: + - System Commands + summary: Perform some system wide commands. + operationId: systemCommand + requestBody: + description: Command details + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/SystemCommandSetLogLevel' + - $ref: '#/components/schemas/SystemCommandReload' + - $ref: '#/components/schemas/SystemCommandGetLogLevels' + - $ref: '#/components/schemas/SystemCommandGetLogLevelNames' + - $ref: '#/components/schemas/SystemCommandGetSubsystemNames' + responses: + 200: + description: Successful command execution + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/SystemGetLogLevelsResult' + - $ref: '#/components/schemas/SystemCommandGetLogLevelNamesResult' + - $ref: '#/components/schemas/SystemGetSubSystemNemesResult' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + get: + tags: + - System Commands + summary: Retrieve different values from the running service. + operationId: getSystemCommand + parameters: + - in: query + description: Get a value + name: command + schema: + type: string + enum: + - info + required: true + + responses: + 200: + description: Successful command execution + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/SystemInfoResults' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + +######################################################################################### +## +## These are endpoints that all services in the uCentral stack must provide +## +######################################################################################### \ No newline at end of file diff --git a/README.md b/README.md index ffefe8a..da6139e 100644 --- a/README.md +++ b/README.md @@ -1,71 +1,130 @@ -# What is MyProduct? +--- +description: Telecom Infra Project OpenWiFi +--- -{% hint style="info" %} -**Good to know:** providing a brief overview of your product and its core use cases is a great place to start with product docs. Your product might seem obvious to you – you made it! However, to others, even folks who are trying your product after reading your site or getting a sales demo, it can still be unclear. This is your chance to clarify your product and set the right expectations! -{% endhint %} +# OpenWiFi Release 2.5 In Progress -Here are a couple of examples of succinct overviews from products with really great docs: +## What is OpenWiFi? -> Loom is a video messaging tool that helps you get your message across through instantly shareable videos. -> -> With Loom, you can record your camera, microphone, and desktop simultaneously. Your video is then instantly available to share through Loom's patented technology. -> -> — From the [Loom Docs](https://support.loom.com/hc/en-us/articles/360002158057-What-is-Loom-) +TIP OpenWiFi is an open source community project that believes in democratizing premium Wi-Fi experiences for multiple market use cases. The TIP approach to OpenWiFi creates an open source disaggregated technology stack without any vendor lock in. OpenWiFi offers premium managed Wi-Fi features, local break-out design, cloud native open source controller, and an open source AP firmware operating system tested nightly. -> The Mailchimp Marketing API provides programmatic access to Mailchimp data and functionality, allowing developers to build custom features to do things like sync email activity and campaign analytics with their database, manage audiences and campaigns, and more. -> -> — From the [Mailchimp Marketing API docs](https://mailchimp.com/developer/marketing/docs/fundamentals/) +![Open Technology Stack - Many Platforms - Many Service Options](<.gitbook/assets/image (5).png>) -## Getting Started +TIP OpenWiFi is the industry's first CI/CD open source Wi-Fi eco-system. Built nightly with a strong community of Wi-Fi leaders, new features are unit tested in automated RF chambers and checked from cloud to ground for Wi-Fi performance and conformance. -**Got 2 minutes?** Check out a video overview of our product: +OpenWiFi 2.0 introduces management and telemetry based on uCentral offering expanded selection of managed devices including smaller APs and PoE access switches. -{% embed url="https://www.loom.com/share/3bfa83acc9fd41b7b98b803ba9197d90" %} +### High Level Features -{% hint style="info" %} -**Good to know:** A succinct video overview is a great way to introduce folks to your product. Embed a Loom, Vimeo or YouTube video and you're good to go! We love this video from the fine folks at [Loom](https://loom.com) as a perfect example of a succinct feature overview. -{% endhint %} +#### Each OpenWiFi AP offers: -### Guides: Jump right in +* Multiple topologies including : + * Bridging, Virtual LAN, VxLAN, NAT Gateway, Local Breakout, Overlay (PPPoE, L2oGRE, L2TP), Mesh, WDS +* Multiple authentications including WPA, WPA2, WPA3, Enterprise Radius models, M-PSK +* Passpoint R1 and R2 Mobile Offload +* Encrypted Zero Touch Provisioning and Cloud Discovery +* Autonomous RRM and Channel Control +* Captive Portal & ExpressWiFi -Follow our handy guides to get started on the basics as quickly as possible: +#### Each OpenWiFi PoE Switch offers: -{% content-ref url="guides/sample.md" %} -[sample.md](guides/sample.md) -{% endcontent-ref %} +* IEEE802.1Q Virtual LAN +* VxLAN +* DHCP Snooping & Relay +* Multicast +* PoE +* IEEE802.1x Access Control -{% content-ref url="guides/sample-1.md" %} -[sample-1.md](guides/sample-1.md) -{% endcontent-ref %} +#### Cloud SDK in OpenWiFi offers: -{% content-ref url="guides/sample-2.md" %} -[sample-2.md](guides/sample-2.md) -{% endcontent-ref %} +* Zero Touch Provisioning +* Firmware Management +* Integration Northbound Interface (NBI) RESTful +* Data model driven API +* Enterprise Message Bus data access -{% hint style="info" %} -**Good to know:** your product docs aren't just a reference of all your features! use them to encourage folks to perform certain actions and discover the value in your product. -{% endhint %} +**OpenWiFi AP Detail List:** -### Fundamentals: Dive a little deeper +* Wi-Fi 4 (n) Wi-Fi 5 (ac) Wi-Fi 6 (ax) +* Dual Bank Bootloader +* Multi-SSID per Radio +* SSID Authentications: WPA/WPA2/WPA3 - Mixed, Personal, Enterprise +* 802.1Q VLAN per SSID +* 802.1d Bridge Mode per SSID +* RADIUS Accounting, Interim-Accounting, NAS-IP, CUI +* Network Address Translation Gateway Mode Operation +* Network Time Protocol Client +* Management VLAN +* Wi-Fi 6 (ax) Specific + * BSS Coloring + * UL/DL OFDMA sub-carrier allocation + * Channel Switch Announcement +* Wi-Fi General Features + * WMM® - Wi-Fi Multi Media + * UAPSD Procedures (Unscheduled Power Save) + * Upstream/Downstream Queues & L3 DSCP + * Over The Air QoS EDCH Procedures +* WMM-Admission Control (AC) +* WMM-Power Save (PS) +* Wi-Fi Optimized Connectivity + * (ai) Fast Initial Link Support +* Wi-Fi Agile Multiband + * (k) Client Radio Resource Management - Directed Steering + * (v) Network Assisted Roaming + * (r) Fast BSS Transition +* Protected Management Frames (PMF) + * (w) Management Frame Encryption +* Channel Switch Announcement (CSA) +* Dynamic Frequency Selection & Transmit Power Control (DFS/TPC) +* Beacon Rate +* Min Client Noise Immunity +* Basic Rate Control +* De-Auth RSSI Control +* Burst Beacon Support +* Per SSID Client Rate Limiting +* Promiscuous Mode Support +* **Additional TIP AP NOS Features** + * ISP WAN Profiles ( PPPoE, L2TP, L2oGRE ) + * Embedded Captive Portal (Local Splash non-auth) + * Link Layer Discovery Protocol (LLDP) + * Dynamic Airtime Fairness + * Service Flow QoS + * Wireline & Wireless Tracing (PCAP Cloud Remote Troubleshooting) + * Health Check Reports + * Local Provisioning over SSID (when Cloud or WAN down) + * Multimedia Heuristics (Detection of Unified Communication Sessions) + * SSID Rate Limiting + * GPS Reporting + * Autonomous RRM Client Steering + * Client / AP / Network Metric Telemetry -Learn the fundamentals of MyProduct to get a deeper understanding of our main features: +**Cloud SDK additional features** -{% content-ref url="fundamentals/projects.md" %} -[projects.md](fundamentals/projects.md) -{% endcontent-ref %} +* **Provisioning** + * Device Identity (Model, MAC, Serial Number) + * Device Software Upgrade + * Multiple SSID Configuration + * Bandwidth Rate Control per SSID + * Multi-Radio 2.4/5/6GHz control + * AP Network Mode Control (Bridge/NAT mode) + * Security (WPA-Personal/WPA & WPA2/3 Personal Mixed/WPA & WPA2/3 Enterprise Mixed/WPA2/3 Personal/WPA2/3 Enterprise/WEP) + * VLAN per SSID + * VxLAN port configuration + * NTP Enable/Disable + * RTLS (Location Services) Enable/Disable +* **RF Control** + * IEEE802.11r Fast BSS Transition per Radio Control + * IEEE802.11k RRM Radio Information per Radio Control + * IEEE802.11v Network Assisted Roaming per Radio Control + * RRM Location AP Channel (uChannel) Provisioning + * RRM Location Client Steering (uSteer) Threshold Provisioning +* **Remote Troubleshooting and Service Assurance** + * Syslog + * Health Check Reports + * Remote DHCP, RADIUS, UE Network Analysis + * Remote TTY Shell + * Remote Packet Capture Analysis -{% content-ref url="fundamentals/members.md" %} -[members.md](fundamentals/members.md) -{% endcontent-ref %} +### **How to contribute** -{% content-ref url="fundamentals/task-lists.md" %} -[task-lists.md](fundamentals/task-lists.md) -{% endcontent-ref %} - -{% content-ref url="fundamentals/tasks.md" %} -[tasks.md](fundamentals/tasks.md) -{% endcontent-ref %} - -{% hint style="info" %} -**Good to know:** Splitting your product into fundamental concepts, objects, or areas can be a great way to let readers deep dive into the concepts that matter most to them. Combine guides with this approach to 'fundamentals' and you're well on your way to great documentation! -{% endhint %} +If you or your company are interested in contributing to TIP Open Wi-Fi, please join the Wi-Fi Product Group by visiting [Telecom Infra Project](https://telecominfraproject.com/apply-for-membership/) to become a member. diff --git a/SUMMARY.md b/SUMMARY.md index 789a7c4..f02d57e 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -1,29 +1,80 @@ # Table of contents -* [What is MyProduct?](README.md) +* [OpenWiFi Release 2.5 GA](README.md) +* [Ordering OpenWiFi APs](ordering-open-wi-fi-aps.md) +* [Device Partner Information](device-partner-information.md) +* [Cloud Partner Information](cloud-partner-information.md) +* [Getting Started](getting-started/README.md) + * [Cloud Discovery](getting-started/cloud-discovery/README.md) + * [Discovery without Cloud](getting-started/cloud-discovery/discovery-without-cloud.md) + * [Release 2.0 SDK](getting-started/sdk.md) + * [Access Points](getting-started/access-points/README.md) + * [Local Device Settings](getting-started/access-points/local-device-settings.md) + * [Repositories](getting-started/repositories.md) +* [Provisioning](provisioning/README.md) + * [Data Model Introduction](provisioning/data-model-introduction.md) + * [Creating a Configuration](provisioning/creating-a-configuration.md) +* [User Interface](user-interface/README.md) + * [Devices](user-interface/devices-view/README.md) + * [Commands](user-interface/devices-view/commands.md) + * [Statistics](user-interface/devices-view/statistics.md) + * [Command History](user-interface/devices-view/command-history.md) + * [Firmware](user-interface/firmware.md) +* [API](api/README.md) + * [OpenAPI Definitions](api/openapi-definitions.md) + * [Security Service](api/security-service.md) + * [Gateway Service](api/gateway-service.md) + * [Firmware Management Service](api/firmware-management-service.md) + * [Provisioning Service](api/provisioning-service.md) +* [Monitoring](monitoring/README.md) + * [ELK Integration](monitoring/elk-integration.md) -## Guides +## SDK Installation -* [Sample1](guides/sample.md) -* [Sample2](guides/sample-1.md) -* [Sample3](guides/sample-2.md) +* [Overview](sdk-installation/overview.md) +* [Deploy using Docker Compose](sdk-installation/deploy-using-docker-compose.md) +* [Deploy using Helm](sdk-installation/deploy-using-helm.md) -## Fundamentals +## Configuration Examples -* [Projects](fundamentals/projects.md) -* [Members](fundamentals/members.md) -* [Task Lists](fundamentals/task-lists.md) -* [Tasks](fundamentals/tasks.md) +* [Basic Device Provisioning](configuration-examples/basic-device-provisioning/README.md) + * [Bridge Mode SSID](configuration-examples/basic-device-provisioning/bridge-mode-ssid.md) + * [NAT Gateway Mode SSID](configuration-examples/basic-device-provisioning/nat-gateway-mode-ssid.md) + * [Multi-VLAN SSID](configuration-examples/basic-device-provisioning/multi-vlan-ssid.md) +* [Device Feature Configuration Examples](configuration-examples/device-feature-configuration-examples/README.md) + * [Zero Touch Provisioning](configuration-examples/device-feature-configuration-examples/zero-touch-provisioning.md) + * [DHCP Relay](configuration-examples/device-feature-configuration-examples/dhcp-relay.md) + * [Services](configuration-examples/device-feature-configuration-examples/services.md) + * [Metrics](configuration-examples/device-feature-configuration-examples/metrics.md) + * [GRE](configuration-examples/device-feature-configuration-examples/gre.md) + * [L2TP](configuration-examples/device-feature-configuration-examples/l2tp.md) + * [VxLAN](configuration-examples/device-feature-configuration-examples/vxlan.md) + * [WDS](configuration-examples/device-feature-configuration-examples/wds-topologies.md) + * [Mesh](configuration-examples/device-feature-configuration-examples/mesh.md) + * [QoS](configuration-examples/device-feature-configuration-examples/qos.md) + * [Dynamic Air Time Fairness](configuration-examples/device-feature-configuration-examples/dynamic-air-time-fairness.md) + * [Dynamic Subscriber QoS](configuration-examples/device-feature-configuration-examples/dynamic-subscriber-qos.md) + * [Captive Portal](configuration-examples/device-feature-configuration-examples/captive-portal/README.md) + * [External Captive Portal](configuration-examples/device-feature-configuration-examples/captive-portal/external-captive-portal.md) + * [ExpressWiFi](configuration-examples/device-feature-configuration-examples/expresswifi.md) + * [Roaming RRM and SON](configuration-examples/device-feature-configuration-examples/roaming-rrm-and-son.md) + * [RADIUS Authenticated SSID](configuration-examples/device-feature-configuration-examples/radius-authenticated-ssid/README.md) + * [Dynamic VLANs with RADIUS](configuration-examples/device-feature-configuration-examples/radius-authenticated-ssid/dynamic-vlans-with-radius.md) + * [Multi-PSK (MDU Shared Key)](configuration-examples/device-feature-configuration-examples/multi-psk-mdu-multiple-shared-key.md) + * [Dynamic Air-Time Policy](configuration-examples/device-feature-configuration-examples/dynamic-air-time-policy.md) + * [Passpoint®](configuration-examples/device-feature-configuration-examples/passpoint-r1/README.md) + * [Configuration Introduction](configuration-examples/device-feature-configuration-examples/passpoint-r1/configuration-introduction.md) + * [Advertising Services](configuration-examples/device-feature-configuration-examples/passpoint-r1/advertising-services.md) + * [Passpoint® Configuration](configuration-examples/device-feature-configuration-examples/passpoint-r1/passpoint-r-configuration.md) + * [Switching](configuration-examples/device-feature-configuration-examples/switching/README.md) + * [Port Speed](configuration-examples/device-feature-configuration-examples/switching/port-speed.md) -## Use Cases +## Release Notes -* [For Designers](use-cases/for-designers/README.md) - * [Figma Integration](use-cases/for-designers/figma-integration.md) -* [For Engineers](use-cases/for-engineers/README.md) - * [GitHub Integration](use-cases/for-engineers/github-integration.md) -* [For Support](use-cases/for-support/README.md) - * [Intercom Integration](use-cases/for-support/intercom-integration.md) +* [Features](release-notes/features.md) +* [Security](release-notes/security.md) +* [Resolved Issues](release-notes/resolved-issues.md) -## Extras +## Test Automation Framework -* [Keyboard Shortcuts](extras/keyboard-shortcuts.md) +* [Overview](test-automation-framework/overview.md) diff --git a/api/README.md b/api/README.md index 850621a..6f33a49 100644 --- a/api/README.md +++ b/api/README.md @@ -1,46 +1,60 @@ +--- +description: OpenWiFi 2.0 SDK +--- + # API -TIP OpenWiFi project is a data-model driven design, meaning the features in the solution are designed as interfaces to be consumed either by micro-services, network devices, or other applications integrating with the solution. +OpenWiFi services follow the OpenAPI 3.0 definition.\ +The complete API is described here: [OpenWiFi SDK OpenAPI](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/openapi/owgw.yaml) -The most useful way to learn the TIP OpenWiFi API is to consume the Swagger interface that fully describes all implemented REST methods. +## Devices -TIP OpenWiFi controller uses OAuth for authentication. A bearer token must first be obtained for subsequent API calls to succeed. +OpenWiFi devices are Access Points or Switches (and other forms in the future), that support the uCentral configuration schema. Devices contact a controller using the uCentral protocol. -## Curl Request to controller for Bearer Token +## Communication -```text -curl -k --request POST --header "Content-Type: application/json; charset=utf-8" --data '{"userId":"support@example.com","password":"support"}' https://${portal-service-ip:port}/management/v1/oauth2/token -``` +The communication between the controller and the devices use the uCentral protocol. This protocol is defined in this [document](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/main/PROTOCOL.md). -## Successful Response +## Device Configuration -```text -{ - "model_type" : "WebTokenResult", - "twoFactorAuthenticationRequired" : false, - "resetPassword" : false, - "access_token" : "eyJpc3MiOiJ0aXAiLCJqdGkiOiI2OTM1NTg3OC1jOGVhLTRiMTItOWU3OS0zMTMyOGJlNWQ1NTEiLCJleHBpcnlUaW1lIjoxNjA2Njg5MjA2MjEyLCJjdXN0b21lcklkIjoyLCJ1c2VyTmFtZSI6InN1cHBvcnRAZXhhbXBsZS5jb20iLCJ1c2VySWQiOjAsInVzZXJSb2xlIjoiU3VwZXJVc2VyIn0=.UYKrayawxxtw9qLbqW70rgOcjSY7oUp8XpalyiGAwUF6zRRsXQ0ILJxvKZxpAwftU4nNosmSS3i2j/vRr5gtD.", - "refresh_token" : "eyJpc3MiOiJ0aXAiLCJqdGkiOiIwZWU2MjAzZi1iNWI0LTRlZGMtYTM1My0yZWUxZGMwOTUzMzMiLCJleHBpcnlUaW1lIjoxNjA2Njg5ODA2MjMyLCJjdXN0b21lcklkIjoyLCJ1c2VyTmFtZSI6InN1cHBvcnRAZXhhbXBsZS5jb20iLCJ1c2VySWQiOjAsInVzZXJSb2xlIjoiU3VwZXJVc2VyIiwicmVmcmVzaCI6dHJ1ZX0=.hiE1Pcb2O0wUNw/ySga6IqPtmgcAkeMAxrMOC85ZN1AJ2v/WLik6DCVoBk8VZXcJNoEc9Gr6WE7RrtMpJGSee1", - "id_token" : null, - "token_type" : "Bearer", - "expires_in" : 3000, - "idle_timeout" : 3600, - "aclTemplate" : { - "model_type" : "WebTokenAclTemplate", - "aclTemplate" : { - "Delete" : true, - "Read" : true, - "PortalLogin" : true, - "ReadWrite" : true, - "ReadWriteCreate" : true - }, - "alias" : 2, - "id" : "", - "name" : "Webtoken Portal Login", - "versionTimestamp" : 1551549825443000 - } -} -``` +A device is configured by ingesting a uCentral configuration. That configuration will be provided by the SDK Gateway as a result of a command through the API. Command processing occurs when the device's configuration is older than what is known in the SDK Gateway. The uCentral schema is a JSON document containing parameters to set on a particular device. -Use the value from access\_token for subsequent API calls into the controller +## SDK Gateway Communication +In order to speak to the Gateway, you must implement a client that uses the OpenAPI definition for the gateway. You can find its [definition here](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/main/openapi/ucentral/ucentral.yaml). You cannot talk to a device directly. + +## API Basics + +### Device `serialNumber` + +Throughout the API, the `serialNumber` of the device is used as the key. The `serialNumber` is actual the MAC address of the device, without its `:`. The `serialNumber` is guaranteed to be unique worldwide. The device uses its serial number to identify itself to the controller. + +### Device Configuration + +The configuration can be supplied when the device is created. After the device is created, the only way to modify the configuration is by using the `/device/{serialNumber}/configure` endpoint. The Gateway maintains the versioning of the configuration through the use of a `uuid`. The Gateway maintains that number and will ignore anything your supply. The controller also does minimum validation on the configuration: it must be a valid JSON document and must have a `uuid` field which will be ignored. + +### Device Capabilities + +Device capabilities are uploaded to the Gateway when the device performs its initial connection. Capabilities tell the Gateway what the device is able to support. The Gateway uses this information to provide a configuration matched to the device type. + +### Command Queue + +The Gateway will send commands to the devices. These commands are kept in a table and are sent at the appropriate time or immediately when the device connects.\ +For example, you could ask a device to change its configuration, however it might be unreachable. Upon next device connection, this configure command will be sent. The list of commands is retrieved using the `/commands` endpoint. + +### Commands + +Several commands maybe sent to a device: reboot, configure, factory reset, firmware upgrade, LEDs, trace, message request, etc. The API endpoint `/device/{serialNumber}/{command}` details all the available commands. + +### Device Specific Collections + +For each device, a number of collections are collected and kept in the database. Here's a brief list: + +* `logs`: device specific logs are kept. A device amy also send something it wants added into its own logs. `crashlogs` are a special type of logs created after a device has had a hard crash. +* `statistics`: statistics about the device. This is current la JSON document and will be documented at a later date. +* `healthchecks`: periodically, a device will run a self-test and report its results. These includes anything that maybe going wrong with the current device configuration. A `sanity` level is associated to the degree of health of the device. 100 meaning a properly operating device. +* `status`: tells you where the device is and how much data is used for protocol communication. + +## The API is for an operator + +This API is meant for an operator who would have to help a subscriber in configuring devices, reboot, manage firmware, etc. diff --git a/api/firmware-management-service.md b/api/firmware-management-service.md new file mode 100644 index 0000000..38eaf55 --- /dev/null +++ b/api/firmware-management-service.md @@ -0,0 +1,53 @@ +# Firmware Management Service + +{% swagger src="../.gitbook/assets/owfms.yaml" path="/firmwares" method="get" %} +[owfms.yaml](../.gitbook/assets/owfms.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owfms.yaml" path="/firmware/{id}" method="get" %} +[owfms.yaml](../.gitbook/assets/owfms.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owfms.yaml" path="/firmware/{id}" method="post" %} +[owfms.yaml](../.gitbook/assets/owfms.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owfms.yaml" path="/firmware/{id}" method="put" %} +[owfms.yaml](../.gitbook/assets/owfms.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owfms.yaml" path="/firmware/{id}" method="delete" %} +[owfms.yaml](../.gitbook/assets/owfms.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owfms.yaml" path="/revisionHistory/{serialNumber}" method="get" %} +[owfms.yaml](../.gitbook/assets/owfms.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owfms.yaml" path="/revisionHistory/{serialNumber}" method="delete" %} +[owfms.yaml](../.gitbook/assets/owfms.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owfms.yaml" path="/firmwareAge" method="get" %} +[owfms.yaml](../.gitbook/assets/owfms.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owfms.yaml" path="/connectedDevices" method="get" %} +[owfms.yaml](../.gitbook/assets/owfms.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owfms.yaml" path="/connectedDevice/{serialNumber}" method="get" %} +[owfms.yaml](../.gitbook/assets/owfms.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owfms.yaml" path="/deviceReport" method="get" %} +[owfms.yaml](../.gitbook/assets/owfms.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owfms.yaml" path="/system" method="get" %} +[owfms.yaml](../.gitbook/assets/owfms.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owfms.yaml" path="/system" method="post" %} +[owfms.yaml](../.gitbook/assets/owfms.yaml) +{% endswagger %} diff --git a/api/gateway-service.md b/api/gateway-service.md new file mode 100644 index 0000000..073351e --- /dev/null +++ b/api/gateway-service.md @@ -0,0 +1,189 @@ +# Gateway Service + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/devices" method="get" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/commands" method="get" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/commands" method="delete" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/command/{commandUUID}" method="get" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/command/{commandUUID}" method="delete" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/default_configurations" method="get" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/default_configuration/{name}" method="get" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/default_configuration/{name}" method="post" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/default_configuration/{name}" method="put" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/default_configuration/{name}" method="delete" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/device/{serialNumber}" method="get" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/device/{serialNumber}" method="post" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/device/{serialNumber}" method="put" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/device/{serialNumber}" method="delete" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/device/{serialNumber}/logs" method="get" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/device/{serialNumber}/logs" method="delete" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/device/{serialNumber}/healthchecks" method="get" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/device/{serialNumber}/healthchecks" method="delete" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/device/{serialNumber}/capabilities" method="get" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/device/{serialNumber}/capabilities" method="delete" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/device/{serialNumber}/statistics" method="get" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/device/{serialNumber}/statistics" method="delete" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/device/{serialNumber}/status" method="get" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/device/{serialNumber}/command" method="post" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/device/{serialNumber}/configure" method="post" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/device/{serialNumber}/upgrade" method="post" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/device/{serialNumber}/reboot" method="post" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/device/{serialNumber}/factory" method="post" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/device/{serialNumber}/leds" method="post" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/device/{serialNumber}/trace" method="post" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/device/{serialNumber}/wifiscan" method="post" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/device/{serialNumber}/request" method="post" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/device/{serialNumber}/eventqueue" method="post" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/device/{serialNumber}/telemetry" method="post" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/ouis" method="get" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/device/{serialNumber}/rtty" method="get" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/file/{uuid}" method="get" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/file/{uuid}" method="delete" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/blacklist" method="get" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/blacklist/{serialNumber}" method="get" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/blacklist/{serialNumber}" method="post" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/blacklist/{serialNumber}" method="put" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/blacklist/{serialNumber}" method="delete" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/capabilities" method="get" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/deviceDashboard" method="get" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/system" method="get" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owgw.yaml" path="/system" method="post" %} +[owgw.yaml](../.gitbook/assets/owgw.yaml) +{% endswagger %} diff --git a/api/openapi-definitions.md b/api/openapi-definitions.md new file mode 100644 index 0000000..790e657 --- /dev/null +++ b/api/openapi-definitions.md @@ -0,0 +1,66 @@ +--- +description: OpenWiFi 2.0 SDK +--- + +# OpenAPI Definitions + +## Where is the OpenAPI? + +This uses OpenAPI definition 3.0 and can be found [here](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/openapi/ucentral/owgw.yaml). All endpoints begin with `/api/v1`. + +## API Flow + +API endpoints are secured with bearer-token authentication using end-point `/oauth2`.\ +Once you obtain `access-token`, you will need to pass it in the headers under `Authorization: Bearer `. + +## Basic Entities + +The API revolves around `devices`, `commands`, and `default_configurations`.\ +To retrieve a list of `devices` to know what is available and then use the endpoint `device` to access all device specific information.\ +To retrieve `commands` and `default_configurations` follow those endpoints.\ +Most operations rely on the `serialNumber` of a device. That `serialNumber` is unique and generated on the device. Serial Number matches the device's MAC address. + +* `devices`: The list of all devices in the system. This maybe very large, pagination is recommended. +* `commands`: The list of commands issued by the system. This list could also be large. +* `default_configurations`: A list of default configurations used to supply existing devices. + +## Relationships + +A device is a physical (or potentially logical) entity using the ucentral protocol.\ +Currently, APs and Switches are the only devices used. A device has several attributes.\ +Additionally, other collections are supported for each device: + +* `logs`: Specific for a device. Logs originate from the device or associated with the device by some mechanism. +* `healthchecks`: Reports from the device coming periodically after device self tests. +* `statistics`: Periodically produced by the devices and document actual state data from each device. +* `capabilities`: This details the actual data model supported by the device. + +The `device` entry point is also used to query about the `status` of the device and used to inject certain commands for a specific device.\ +Commands supported for each device: + +* `reboot`: This will force the device to reboot. +* `configure`: Configure sends a new configuration to a device. +* `factory`: Forces the device to perform a factory-reset. +* `upgrade`: Forces the device to do a firmware upgrade. +* `leds`: Ask the device to flash its LEDs or turn them on or off. +* `trace`: Performs a remove LAN trace. Once the trace is completed, the produced file may be removed using the `file` endpoint. +* `command`: Performs a proprietary command. The meaning depends on the device. +* `request`: Request an immediate message of type `state` or `healthcheck`. + +The `file` end point is used to retrieve and remove files produced by the Gateway. Currently this is limited to the results of a `trace` command. The file name will always match the `uuid` of the command that produced it. If several files are needed, the files will be named `uuid`, `uuid.1`, `uuid.2`, etc. + +## Dates + +All dates should use the format defined in [RFC3339](https://tools.ietf.org/html/rfc3339). All times are UTC based. Here is an example: + +``` +1985-04-12T23:20:50.52Z +``` + +## Command `when` parameter + +Most commands use a `when` parameter to suggest to the device when to perform the command. This is a _suggestion_ only. The device may decide to perform the command when it is optimal for itself. It maybe busy doing something and decline to do a reboot for several minutes for example. The device may reply with the actual `when` it will perform the command. + +## Configuration UUID + +The gateway manages the configuration UUID. So if you set a UUID for a configuration, it will be ignored. The gateway uses UUID as versioning. The UUID is unique within a single device. The resulting UUID or a configuration change is returned as part of the `configure` command. diff --git a/api/provisioning-service.md b/api/provisioning-service.md new file mode 100644 index 0000000..c9b0988 --- /dev/null +++ b/api/provisioning-service.md @@ -0,0 +1,213 @@ +# Provisioning Service + +{% swagger src="../.gitbook/assets/owprov.yaml" path="undefined" method="undefined" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/entity/{uuid}" method="get" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/entity/{uuid}" method="post" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/entity/{uuid}" method="put" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/entity/{uuid}" method="delete" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/contact" method="get" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/contact/{uuid}" method="get" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/contact/{uuid}" method="post" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/contact/{uuid}" method="put" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/contact/{uuid}" method="delete" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/location" method="get" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/location/{uuid}" method="get" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/location/{uuid}" method="post" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/location/{uuid}" method="put" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/location/{uuid}" method="delete" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/inventory" method="get" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/inventory/{serialNumber}" method="get" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/inventory/{serialNumber}" method="post" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/inventory/{serialNumber}" method="put" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/inventory/{serialNumber}" method="delete" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/venue" method="get" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/venue/{uuid}" method="get" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/venue/{uuid}" method="post" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/venue/{uuid}" method="put" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/venue/{uuid}" method="delete" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/map" method="get" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/map/{uuid}" method="get" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/map/{uuid}" method="post" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/map/{uuid}" method="put" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/map/{uuid}" method="delete" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/managementPolicy" method="get" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/managementPolicy/{uuid}" method="get" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/managementPolicy/{uuid}" method="post" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/managementPolicy/{uuid}" method="put" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/managementPolicy/{uuid}" method="delete" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/managementRole" method="get" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/managementRole/{uuid}" method="post" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/managementRole/{uuid}" method="put" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/managementRole/{uuid}" method="delete" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/configurations" method="get" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/configurations/{uuid}" method="get" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/configurations/{uuid}" method="post" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/configurations/{uuid}" method="put" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/configurations/{uuid}" method="delete" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/iptocountry" method="get" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/signup" method="get" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/signup" method="post" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/signup" method="put" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/signup" method="delete" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/variables" method="get" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/dashboard" method="get" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/system" method="get" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owprov.yaml" path="/system" method="post" %} +[owprov.yaml](../.gitbook/assets/owprov.yaml) +{% endswagger %} diff --git a/api/security-service.md b/api/security-service.md new file mode 100644 index 0000000..8d650df --- /dev/null +++ b/api/security-service.md @@ -0,0 +1,73 @@ +# Security Service + +{% swagger src="../.gitbook/assets/owsec.yaml" path="/oauth2" method="post" %} +[owsec.yaml](../.gitbook/assets/owsec.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owsec.yaml" path="/oauth2/{token}" method="delete" %} +[owsec.yaml](../.gitbook/assets/owsec.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owsec.yaml" path="/systemEndpoints" method="get" %} +[owsec.yaml](../.gitbook/assets/owsec.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owsec.yaml" path="/users" method="get" %} +[owsec.yaml](../.gitbook/assets/owsec.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owsec.yaml" path="/user/{id}" method="get" %} +[owsec.yaml](../.gitbook/assets/owsec.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owsec.yaml" path="/user/{id}" method="post" %} +[owsec.yaml](../.gitbook/assets/owsec.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owsec.yaml" path="/user/{id}" method="put" %} +[owsec.yaml](../.gitbook/assets/owsec.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owsec.yaml" path="/user/{id}" method="delete" %} +[owsec.yaml](../.gitbook/assets/owsec.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owsec.yaml" path="/avatar/{id}" method="get" %} +[owsec.yaml](../.gitbook/assets/owsec.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owsec.yaml" path="/avatar/{id}" method="post" %} +[owsec.yaml](../.gitbook/assets/owsec.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owsec.yaml" path="/avatar/{id}" method="delete" %} +[owsec.yaml](../.gitbook/assets/owsec.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owsec.yaml" path="/email" method="post" %} +[owsec.yaml](../.gitbook/assets/owsec.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owsec.yaml" path="/sms" method="post" %} +[owsec.yaml](../.gitbook/assets/owsec.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owsec.yaml" path="/securityProfiles" method="get" %} +[owsec.yaml](../.gitbook/assets/owsec.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owsec.yaml" path="/systemServices" method="get" %} +[owsec.yaml](../.gitbook/assets/owsec.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owsec.yaml" path="/validateToken" method="get" %} +[owsec.yaml](../.gitbook/assets/owsec.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owsec.yaml" path="/system" method="get" %} +[owsec.yaml](../.gitbook/assets/owsec.yaml) +{% endswagger %} + +{% swagger src="../.gitbook/assets/owsec.yaml" path="/system" method="post" %} +[owsec.yaml](../.gitbook/assets/owsec.yaml) +{% endswagger %} diff --git a/cloud-partner-information.md b/cloud-partner-information.md new file mode 100644 index 0000000..2d93dc4 --- /dev/null +++ b/cloud-partner-information.md @@ -0,0 +1,51 @@ +--- +description: TIP OpenWiFi +--- + +# Cloud Partner Information + +TIP OpenWiFi enables integration by commercial controllers to the OpenWiFi Software Development Kit (SDK). + +\ +The OpenWiFi SDK is designed to enable cloud partners to consume basic southbound device management and device discovery at a minimum. This is similar to augmenting a southbound device adapter for many orchestration or automation systems. + +The OpenWiFi SDK also offers numerous micro services of incremental functionality for cloud partners to optionally consume including: + +* Firmware Management +* Device Provisioning +* Subscriber Portal +* Analytics +* User Interface + +This independent micro service approach has numerous advantages including ease of integration, ability to leverage more of the stack to accelerate product availability or support only device communication and discovery for partners who seek to maintain more functionality within their own application. + +### Step 1 : Join + +If your organization is not already a TIP Open Converged Wireless Project Group (OCW PG) member, consider signing up. Joining the OCW PG is free as a Software Participation Tier in TIP. + +For more information please visit:[ Becoming a Member](https://telecominfraproject.com/apply-for-membership/) + +### Step 2 : Slack, Keys & Atlassian Tools + +Introduce your organization to the Community on Slack. All Community members have access to Telecom Infra Project Slack. Send a message to "general" and "open-wifi-ucentral" channels. + +Send an email to licensekeys@telecominfraproject.com to request onboarding as a supplier for OpenWiFi Cloud. All OpenWiFi Gateway services in the SDK require a signed key to terminate incoming device connections in the southbound interface. + +Ensure your GitHub account was linked in your Telecom Infra Project user profile, this will enable write access to OpenWiFi repositories. Also confirm Atlassian link is also present in user profile. + +### Step 3 : Integration + +OpenWiFi SDK uses OpenAPI 3.0 compliant northbound Rest API and Kafka for message bus topics. Typical CRUD actions occur via the Rest API, Kafka will present topics for device discovery and all telemetry captured from the network edge. + +Please consult the [API topics](api/) to begin with integration work. + +### Summary + +Integrations that use the published interfaces are the easiest approach to starting with OpenWiFi SDK. + +If a cloud partner seeks to contribute a new SDK micro service, please announce the idea on "general" and "open-wifi-ucentral" slack channels for the Community to help further. \ +There is a skeleton micro service example to help developers build new services that inherit SDK service discovery and security design. + +Please find skeleton service [here](https://github.com/Telecominfraproject/wlan-cloud-tools). + + diff --git a/configuration-examples/basic-device-provisioning/README.md b/configuration-examples/basic-device-provisioning/README.md new file mode 100644 index 0000000..2cbc6f3 --- /dev/null +++ b/configuration-examples/basic-device-provisioning/README.md @@ -0,0 +1,13 @@ +--- +description: OpenWiFi 2.0 +--- + +# Basic Device Provisioning + +One of the benefits of the new data plane in OpenWiFi 2.0 is the flexibility of physical port to logical forwarding that is easily conveyed through configuration structures. + +New protocol support is both easily added to the system as well as associated with interfaces by their role in the device. + +The following sections offer feature configuration examples. + +For complete reference to the device data model please refer [here.](../../provisioning/data-model-introduction.md) diff --git a/configuration-examples/basic-device-provisioning/bridge-mode-ssid.md b/configuration-examples/basic-device-provisioning/bridge-mode-ssid.md new file mode 100644 index 0000000..3219d8a --- /dev/null +++ b/configuration-examples/basic-device-provisioning/bridge-mode-ssid.md @@ -0,0 +1,144 @@ +--- +description: OpenWiFi 2.0 +--- + +# Bridge Mode SSID + +Creating logical bridges may be done through association to named "interfaces".\ +To associate a logical SSID interface directly to the WAN, place SSID configuration within the interface have a "role" of upstream. + +{% tabs %} +{% tab title="SSID to WAN" %} +``` + "interfaces": [ + { + "name": "WAN", + "role": "upstream", + "services": [ "lldp" ], + "ethernet": [ + { + "select-ports": [ + "WAN*" + ] + } + ], + "ipv4": { + "addressing": "dynamic" + }, + "ssids": [ + { + "name": "OpenWifi", + "wifi-bands": [ + "2G", "5G" + ], + "bss-mode": "ap", + "encryption": { + "proto": "psk2", + "key": "OpenWifi", + "ieee80211w": "optional" + } + } + ] +``` +{% endtab %} + +{% tab title="Dual SSID to WAN" %} +``` +"interfaces": [ + { + "name": "WAN", + "role": "upstream", + "services": [ "lldp" ], + "ethernet": [ + { + "select-ports": [ + "WAN*" + ] + } + ], + "ipv4": { + "addressing": "dynamic" + }, + "ssids": [ + { + "name": "OpenWifi_2GHz", + "wifi-bands": [ + "2G" + ], + "bss-mode": "ap", + "encryption": { + "proto": "psk2", + "key": "OpenWifi", + "ieee80211w": "optional" + } + }, + { + "name": "OpenWifi_5GHz", + "wifi-bands": [ + "5G" + ], + "bss-mode": "ap", + "encryption": { + "proto": "psk2", + "key": "OpenWifi", + "ieee80211w": "optional" + } + } + ] +``` +{% endtab %} + +{% tab title="Dual SSID Bridge Rate-Limit to WAN" %} +``` + "interfaces": [ + { + "name": "WAN", + "role": "upstream", + "services": [ "lldp" ], + "ethernet": [ + { + "select-ports": [ + "WAN*" + ] + } + ], + "ipv4": { + "addressing": "dynamic" + }, + "ssids": [ + { + "name": "OpenWifi_2GHz", + "wifi-bands": [ + "2G" + ], + "bss-mode": "ap", + "encryption": { + "proto": "psk2", + "key": "OpenWifi", + "ieee80211w": "optional" + }, + "rate-limit": { + "ingress-rate": 100, + "egress-rate": 100 + } + }, + { + "name": "OpenWifi_5GHz", + "wifi-bands": [ + "5G" + ], + "bss-mode": "ap", + "encryption": { + "proto": "psk2", + "key": "OpenWifi", + "ieee80211w": "optional" + }, + "rate-limit": { + "ingress-rate": 250, + "egress-rate": 250 + } + } + ] +``` +{% endtab %} +{% endtabs %} diff --git a/configuration-examples/basic-device-provisioning/multi-vlan-ssid.md b/configuration-examples/basic-device-provisioning/multi-vlan-ssid.md new file mode 100644 index 0000000..5a41ee0 --- /dev/null +++ b/configuration-examples/basic-device-provisioning/multi-vlan-ssid.md @@ -0,0 +1,138 @@ +--- +description: OpenWiFi 2.0 +--- + +# Multi-VLAN SSID + +The most common use case for VLANs and Wi-Fi is likely the service provider, venue, enterprise where Wi-Fi traffic is not subject to address translation. This is the example that will be shown, however it is entirely possible to create multiple downstream VLANs with SSIDs as well. Simply replace the logic of upstream to downstream where desired. + +{% tabs %} +{% tab title="Single SSID VLAN" %} +``` + "interfaces": [ + { + "name": "WAN", + "role": "upstream", + "services": [ "lldp", "dhcp-snooping" ], + "ethernet": [ + { + "select-ports": [ + "WAN*" + ] + } + ], + "ipv4": { + "addressing": "dynamic" + } + }, + { + "name": "WAN100", + "role": "upstream", + "vlan": { + "id": 100 + }, + "ethernet": [ + { + "select-ports": [ + "WAN*" + ] + } + ], + "ssids": [ + { + "name": "VLAN 100 Wi-Fi", + "wifi-bands": [ + "2G", "5G" + ], + "bss-mode": "ap", + "encryption": { + "proto": "psk2", + "key": "OpenWifi", + "ieee80211w": "optional" + } + } + ] + }, +``` +{% endtab %} + +{% tab title="Dual SSID - Dual VLAN" %} +``` + "interfaces": [ + { + "name": "WAN", + "role": "upstream", + "services": [ "lldp", "dhcp-snooping" ], + "ethernet": [ + { + "select-ports": [ + "WAN*" + ] + } + ], + "ipv4": { + "addressing": "dynamic" + } + }, + { + "name": "WAN100", + "role": "upstream", + "vlan": { + "id": 100 + }, + "ethernet": [ + { + "select-ports": [ + "WAN*" + ] + } + ], + "ssids": [ + { + "name": "VLAN 100 Wi-Fi", + "wifi-bands": [ + "2G", "5G" + ], + "bss-mode": "ap", + "encryption": { + "proto": "psk2", + "key": "OpenWifi", + "ieee80211w": "optional" + } + } + ] + }, + { + "name": "WAN200", + "role": "upstream", + "vlan": { + "id": 200 + }, + "ethernet": [ + { + "select-ports": [ + "WAN*" + ] + } + ], + "ssids": [ + { + "name": "VLAN 200 Wi-Fi", + "wifi-bands": [ + "5G" + ], + "bss-mode": "ap", + "encryption": { + "proto": "psk2", + "key": "OpenWifi", + "ieee80211w": "optional" + } + } + ] + }, +``` +{% endtab %} +{% endtabs %} + +In all cases the WAN port without VLAN id is using DHCP to obtain a management IP address.\ +Each additional "upstream" role interface with an SSID associated have no IP configuration. diff --git a/configuration-examples/basic-device-provisioning/nat-gateway-mode-ssid.md b/configuration-examples/basic-device-provisioning/nat-gateway-mode-ssid.md new file mode 100644 index 0000000..6231e73 --- /dev/null +++ b/configuration-examples/basic-device-provisioning/nat-gateway-mode-ssid.md @@ -0,0 +1,84 @@ +--- +description: OpenWiFi 2.0 +--- + +# NAT Gateway Mode SSID + +Creating a NAT Gateway is easily done via association to an interface having a role of "downstream". + +{% tabs %} +{% tab title="Dual SSID NAT" %} +``` + "interfaces": [ + { + "name": "WAN", + "role": "upstream", + "services": [ "lldp" ], + "ethernet": [ + { + "select-ports": [ + "WAN*" + ] + } + ], + "ipv4": { + "addressing": "dynamic" + } + }, + { + "name": "LAN", + "role": "downstream", + "services": [ "ssh", "lldp" ], + "ethernet": [ + { + "select-ports": [ + "LAN*" + ] + } + ], + "ipv4": { + "addressing": "static", + "subnet": "192.168.1.1/24", + "dhcp": { + "lease-first": 10, + "lease-count": 100, + "lease-time": "6h" + } + }, + "ssids": [ + { + "name": "OpenWifi_2GHz", + "role": "downstream", + "wifi-bands": [ + "2G" + ], + "bss-mode": "ap", + "encryption": { + "proto": "psk2", + "key": "OpenWifi", + "ieee80211w": "optional" + } + }, + { + "name": "OpenWifi_5GHz", + "role": "downstream", + "wifi-bands": [ + "5G" + ], + "bss-mode": "ap", + "encryption": { + "proto": "psk2", + "key": "OpenWifi", + "ieee80211w": "optional" + } + } + ] + + } +``` +{% endtab %} +{% endtabs %} + +Based on the above Dual SSID NAT configuration, a unique 2GHz and 5GHz SSID are created and logically bound to the same NAT LAN side network. + +The NAT service is inherited by the downstream role with DHCP addressing defined according to the range set within the downstream "ipv4" configuration. diff --git a/configuration-examples/device-feature-configuration-examples/README.md b/configuration-examples/device-feature-configuration-examples/README.md new file mode 100644 index 0000000..3752833 --- /dev/null +++ b/configuration-examples/device-feature-configuration-examples/README.md @@ -0,0 +1,9 @@ +--- +description: TIP OpenWiFi 2.0 +--- + +# Device Feature Configuration Examples + +OpenWiFi devices have a number of features that may be configured. + +The following pages guide the user to understanding each of these features individually including example configuration information. diff --git a/configuration-examples/device-feature-configuration-examples/captive-portal/README.md b/configuration-examples/device-feature-configuration-examples/captive-portal/README.md new file mode 100644 index 0000000..1ec7580 --- /dev/null +++ b/configuration-examples/device-feature-configuration-examples/captive-portal/README.md @@ -0,0 +1,56 @@ +--- +description: TIP OpenWiFi 2.0 +--- + +# Captive Portal + +OpenWiFi supports multiple models for Captive Portal. A built-in captive portal is described below. With multiple overlay tunnel services such as GRE and L2TP in addition to VLAN features, OpenWiFi is also easily deployed with any number of Captive Portal appliance solutions in either in-band or out-of-band style deployments. + +## Local Captive Portal + +Creating a local captive portal involves associating the "captive" service with an interface. In the example below, "captive" is enabled on a downstream role interface. Any associated SSID on LAN side of this Access Point will be subject to configuration of the local captive portal. This would also apply to LAN interfaces if also associated with "captive". + +``` + { + "name": "captive", + "role": "downstream", + "captive": { + "max-clients": 32, + "gateway-name": "Lobby Wi-Fi Welcome", + "upload-rate": 10, + "download-rate": 20, + "upload-quota": 300, + "download-quota": 300 + }, + "ipv4": { + "addressing": "static", + "subnet": "192.168.2.1/24", + "dhcp": { + "lease-first": 10, + "lease-count": 100, + "lease-time": "6h" + } + }, + "ssids": [ + { + "name": "Office Lobby Wi-Fi", + "wifi-bands": [ + "5G", + "2G" + ], + "bss-mode": "ap", + "encryption": { + "proto": "none", + "ieee80211w": "optional" + }, + "roaming": { + "message-exchange": "ds", + "generate-psk": true + } + } + ] + } + ], +``` + +Local captive portal will redirect to a default landing page and display the name as configured in "gateway-name". Per associated user bandwidth and usage quota limits and total association limits may all be defined. diff --git a/configuration-examples/device-feature-configuration-examples/captive-portal/external-captive-portal.md b/configuration-examples/device-feature-configuration-examples/captive-portal/external-captive-portal.md new file mode 100644 index 0000000..938b63e --- /dev/null +++ b/configuration-examples/device-feature-configuration-examples/captive-portal/external-captive-portal.md @@ -0,0 +1,107 @@ +--- +description: TIP OpenWiFi 2.0 +--- + +# External Captive Portal + +When an external access controller, such as a captive portal appliance or a Universal Access Method (UAM) redirector is required to handle subscriber login, OpenWiFi optionally supports builds that include use of CoovaChili. This would be found in build profile chilli-redirect.yml. + +To configure a CoovaChilli service, OpenWiFi supports the `"third-party"` schema definition. + +Through the use of third-party, many configurations are possible, for external captive portal, third-party will process a services lookup of `"chilli-redirect"` applied to an interface. + +Within `"third-party"` will be the necessary CoovaChilli configuration parameters. + +``` +"third-party": { + "chilli-redirect": { + "uamport": 3990, + "radiusauthport": 1812, + "radiusacctport": 1813, + "radiusserver1": "radiusServerIP", + "radiusserver2": "radiusServerIP", + "radiusnasid": "nasID", + "uamallowed": "allowed.example.com,10.0.0.1,192.168.10.1", + "uamdomain": "exampleUAMdomain.com,otherExampleUAMdomain.com", + "defidletimeout": 900, + "definteriminterval": 600, + "acctupdate": 1, + "uamserver": "https://portal.example.com/portal/default/index.php?n=NAME&c=3&l=181", + "radiussecret": "radiusSecret", + "nasmac": "00:01:02:03:04:AA" + } + } +``` + +## NAT Mode + +Associate to an interface: + +``` +{ + "name": "LAN", + "role": "downstream", + "services": [ "ssh", "chilli-redirect" ], + "ethernet": [ + { + "select-ports": [ + "LAN*" + ] + } + ], + "ipv4": { + "addressing": "static", + "subnet": "192.168.1.1/24", + "dhcp": { + "lease-first": 10, + "lease-count": 100, + "lease-time": "6h" + } + }, + "ssids": [ + { + "name": "Hotspot SSID Name", + "wifi-bands": [ + "2G", "5G" + ], + "bss-mode": "ap" + } + ] + } +``` + +## Bridge Mode + +In the above example, captive portal redirection occurs via a NAT interface on LAN side or `"downstream"` role. + +When a direct to WAN presentation, or bridge mode operation is desired, associate the service to the `"upstream"` interface. + +Associate to an interface: + +``` +"interfaces": [ + { + "name": "WAN", + "role": "upstream", + "services": [ "chilli-redirect" ], + "ethernet": [ + { + "select-ports": [ + "WAN*" + ] + } + ], + "ipv4": { + "addressing": "dynamic" + }, + "ssids": [ + { + "name": "Hotspot SSID Name", + "wifi-bands": [ + "2G", "5G" + ], + "bss-mode": "ap" + } + ] + }, +``` diff --git a/configuration-examples/device-feature-configuration-examples/dhcp-relay.md b/configuration-examples/device-feature-configuration-examples/dhcp-relay.md new file mode 100644 index 0000000..24e504f --- /dev/null +++ b/configuration-examples/device-feature-configuration-examples/dhcp-relay.md @@ -0,0 +1,59 @@ +--- +description: TIP OpenWiFi 2.0 +--- + +# DHCP Relay + +When operators of enterprise or service provider networks seek to influence or control the allocation of dynamically assigned IP address, typically the network edge has been provisioned to encode information in DHCP Relay packets that help identify the access device through which a subscriber is attached, the logical sub-interface of that network edge or the subscriber directly. + +TIP OpenWiFi supports DHCP Relay with encoding of client Circuit-Id information containing any of: + +* Interface +* VLAN-Id +* SSID +* Encryption Mode +* Device Name +* Device Model +* Device Location +* Access Point MAC Address +* Access Point MAC in Hex +* Client MAC Address +* Client MAC Address in Hex + +TIP OpenWiFi Relay-Agent remote-id may be configured to contain any of the following: + +* VLAN-Id +* SSID +* AP-MAC +* AP-MAC-Hex +* Client MAC +* Client MAC Hex + +The remote-id originates from a configured IPv4 interface address. + +``` + { + "name": "LAN", + "role": "downstream", + "services": [ "ssh", "lldp" ], + "ethernet": [ + { + "select-ports": [ + "LAN*" + ] + } + ], + "ipv4": { + "addressing": "static", + "subnet": "192.168.1.1/24", + "dhcp": { + "relay-server" : "192.168.100.20", + "circuit-id-format": "{Interface}:{SSID}:{AP-MAC}:{Location}", + "remote-id-format": "{AP-MAC}:{SSID}" + } + } + } + ] +``` + +In the above example, when the IPv4 downstream interface 192.168.1.1 has DHCP enabled for `relay-server` a DHCP relay process associates to the IP interface of the subnet. When DHCP DISCOVER packets arrive as broadcasts, they will be copied to a unicast packet from the `192.168.1.1` interface as the `relay-id` source address and unicast forwarded to the defined `relay-server` address. Additional parameters are encoded for inspection at the DHCP server as present in `circuit-id`-format and `remote-id`-format options. diff --git a/configuration-examples/device-feature-configuration-examples/dynamic-air-time-fairness.md b/configuration-examples/device-feature-configuration-examples/dynamic-air-time-fairness.md new file mode 100644 index 0000000..833f03f --- /dev/null +++ b/configuration-examples/device-feature-configuration-examples/dynamic-air-time-fairness.md @@ -0,0 +1,6 @@ +--- +description: TIP OpenWiFi 2.0 +--- + +# Dynamic Air Time Fairness + diff --git a/configuration-examples/device-feature-configuration-examples/dynamic-air-time-policy.md b/configuration-examples/device-feature-configuration-examples/dynamic-air-time-policy.md new file mode 100644 index 0000000..c6365e1 --- /dev/null +++ b/configuration-examples/device-feature-configuration-examples/dynamic-air-time-policy.md @@ -0,0 +1,37 @@ +--- +description: TIP OpenWiFi 2.0 +--- + +# Dynamic Air-Time Policy + +Dynamic Air-Time Policy is a service to influence underlying co-ordination function of the Wi-Fi MAC domain per associated UE in terms of priority to use the air interface. + +It is possible to govern certain application use cases such as streaming media or real time communications based on the resolution of those services through DNS. + +This results in the UE, by its IP address having matched a specific fully qualified domain name or a wildcard therein, to having its air-time weighted priority to the value set in the weight parameter. + +``` + "services": { + "airtime-policies": { + "dns-match": ["*.example.com", "host.example2.com" ], + "dns-weight": 256 + } + } +``` + +{% hint style="info" %} +Note: In release 2.1, airtime-policies must be applied to SSIDs in a NAT configuration. Bridge / VLAN mode SSIDs with airtime-policies will be updated in a future release +{% endhint %} + +## Possible Uses + +Any application a user may commonly use the OpenWiFi administrator seeks to prioritize air-time for may be triggered via the airtime-policies. + +For example: + +| Service | FQDN / URL | +| -------- | ---------------------------------------------------------- | +| MS Teams | _\*.lync.com, \*_.teams.microsoft.com, teams.microsoft.com | +| Zoom | \*.zoom.us | + +Any number of services may interest the administrator for airtime-policies. Simply determine the FQDN or wildcard FQDN applicable and update the OpenWiFi device configuration. diff --git a/configuration-examples/device-feature-configuration-examples/dynamic-subscriber-qos.md b/configuration-examples/device-feature-configuration-examples/dynamic-subscriber-qos.md new file mode 100644 index 0000000..e590d79 --- /dev/null +++ b/configuration-examples/device-feature-configuration-examples/dynamic-subscriber-qos.md @@ -0,0 +1,6 @@ +--- +description: TIP OpenWiFi 2.0 +--- + +# Dynamic Subscriber QoS + diff --git a/configuration-examples/device-feature-configuration-examples/expresswifi.md b/configuration-examples/device-feature-configuration-examples/expresswifi.md new file mode 100644 index 0000000..6451a10 --- /dev/null +++ b/configuration-examples/device-feature-configuration-examples/expresswifi.md @@ -0,0 +1,92 @@ +--- +description: OpenWiFi 2.1 +--- + +# ExpressWiFi + +At home, in a cafe, or on the go, Express Wi-Fi gives you access to fast, affordable, and reliable internet so you can make connections that matter. + +Express Wi-Fi partners with service providers to deliver great wi-fi to people when and where it's needed. + +For information about becoming an expressWIFI partner please visit their [site.](https://expresswifi.fb.com) + +![](<../../.gitbook/assets/image (36).png>) + +## Configuration + +ExpressWiFi builds a captive portal experience using a control plane protocol called OpenFlow.\ +Configuring OpenWiFi for use with expressWiFi is as simple as defining a downstream interface and associating with an SSID and the open-flow service. + +{% tabs %} +{% tab title="expressWIFI" %} +``` + "interfaces": [ + { + "name": "WAN", + "role": "upstream", + "services": [ "lldp" ], + "ethernet": [ + { + "select-ports": [ + "WAN*" + ] + } + ], + "ipv4": { + "addressing": "dynamic" + } + }, + { + "name": "LAN", + "role": "downstream", + "services": [ "ssh", "lldp", "open-flow"], + "ethernet": [ + { + "select-ports": [ + "LAN*" + ] + } + ], + "ipv4": { + "addressing": "static", + "subnet": "192.168.1.1/24", + "dhcp": { + "lease-first": 10, + "lease-count": 100, + "lease-time": "6h" + } + }, + "ssids": [ + { + "name": "ExpressWiFi", + "wifi-bands": [ + "5G", "2G" + ], + "bss-mode": "ap" + } + ] + } + ], + "services": { + "lldp": { + "describe": "OpenWiFi - expressWiFi", + "location": "Hotspot" + }, + "ssh": { + "port": 22 + }, + "open-flow": { + "controller": " IP / FQDN of expressWiFi Controller ", + "mode": "specific mode pssl, ptcp, ssl, tcp" + "ca-certificate": " the client cert as Base64 here ", + "ssl-certificate": "the shared ca as Base64 here", + "private-key": "client key as Base64 here" + } + } +``` +{% endtab %} +{% endtabs %} + +{% hint style="info" %} +Contact expressWiFi for appropriate CA, Client Cert, and Key for TLS Security mode in addition to the specific expressWiFi Controller FQDN. Ensure these values are Base64 encoded when passed into the configuration +{% endhint %} diff --git a/configuration-examples/device-feature-configuration-examples/gre.md b/configuration-examples/device-feature-configuration-examples/gre.md new file mode 100644 index 0000000..ec9096d --- /dev/null +++ b/configuration-examples/device-feature-configuration-examples/gre.md @@ -0,0 +1,63 @@ +--- +description: TIP OpenWiFi 2.0 +--- + +# GRE + +OpenWiFi 2.0 supports Generic Routing Encapsulation as an available "tunnel" protocol type. + +This makes it possible to configure GRE for multiple types of deployments as any interface may be encapsulated by the "tunnel" parameter. + +For example, to send all content of a specific SSID over an GRE tunnel, the following configuration would apply. + +``` + "interfaces": [ + { + "name": "WAN", + "role": "upstream", + "ethernet": [ + { + "select-ports": [ + "WAN*" + ] + } + ], + "ipv4": { + "addressing": "dynamic" + } + }, + { + "name": "GRE", + "role": "upstream", + "vlan": { + "id": 20 + }, + "tunnel": { + "proto": "gre", + "peer-address": "far end IP address", + }, + "ssids": [ + { + "name": "Tunneled SSID via GRE from VLAN 20 Interface", + "wifi-bands": [ + "2G", "5G" + ], + "bss-mode": "ap", + "encryption": { + "proto": "none", + "ieee80211w": "optional" + }, + "rate-limit": { + "ingress-rate": 100, + "egress-rate": 100 + }, + "roaming": { + "message-exchange": "ds", + "generate-psk": true + } + } + ] + }, +``` + +In the above example, the WAN untagged port will request DHCP in addition to present a VLAN interface with id 20 that both initiates the GRE tunnel as well as passes SSID traffic over that tunnel. Optionally the GRE tunnel itself may also carry a VLAN encapsulated payload. In the above example a WAN presentation of VLAN interface 20 has GRE tunnel. Within the GRE tunnel on WAN interface of VLAN 20 is a GRE payload with VLAN 30 in the payload header. diff --git a/configuration-examples/device-feature-configuration-examples/l2tp.md b/configuration-examples/device-feature-configuration-examples/l2tp.md new file mode 100644 index 0000000..13201a2 --- /dev/null +++ b/configuration-examples/device-feature-configuration-examples/l2tp.md @@ -0,0 +1,64 @@ +--- +description: TIP OpenWiFi 2.0 +--- + +# L2TP + +Layer 2 Tunneling Protocol may be associated to any interface using the "tunnel" configuration option. + +This makes it possible to configure L2TP for multiple types of deployments as any interface may be encapsulated by the "tunnel" parameter. + +For example, to send all content of a specific SSID over an L2TP tunnel, the following configuration would apply. + +``` + { + "name": "LAN", + "role": "downstream", + "services": [ "ssh" ], + "ethernet": [ + { + "select-ports": [ + "LAN*" + ] + } + ], + "ipv4": { + "addressing": "static", + "subnet": "192.168.1.1/24", + "dhcp": { + "lease-first": 10, + "lease-count": 100, + "lease-time": "6h" + } + } + }, + { + "name": "L2TP", + "role": "downstream", + "tunnel": { + "proto": "l2tp", + "server": " far end IP address ", + "user-name": "secret-l2tp-username", + "password": "secrectPassword" + }, + "ipv4": { + "addressing": "static", + "subnet": "192.168.10.1/24", + "dhcp": { + "lease-first": 10, + "lease-count": 100, + "lease-time": "6h" + } + }, + "ssids": [ + { + "name": "Tunneled SSID", + "wifi-bands": [ + "5G", "2G" + ], + "bss-mode": "ap" + } + ] + } + ], +``` diff --git a/configuration-examples/device-feature-configuration-examples/mesh.md b/configuration-examples/device-feature-configuration-examples/mesh.md new file mode 100644 index 0000000..09e2549 --- /dev/null +++ b/configuration-examples/device-feature-configuration-examples/mesh.md @@ -0,0 +1,80 @@ +--- +description: OpenWiFi 2.0 +--- + +# Mesh + +OpenWiFi Mesh has been designed to eliminate configuration complexity while also remaining capable of advanced topology designs including Multi-Gateway, Multi-SSID, VLAN, and Zero Touch Mesh onboarding. + +The physical wired interface(s) to participate in the mesh topology egress are defined with the protocol "mesh". + +The logical wireless interface(s) to participate in mesh topology are defined by their bss-mode set to "mesh". + +{% tabs %} +{% tab title="Basic Mesh" %} +``` + "interfaces": [ + { + "name": "WAN", + "role": "upstream", + "tunnel": { + "proto": "mesh" + }, + "services": [ "lldp" ], + "ethernet": [ + { + "select-ports": [ + "WAN*" + ] + } + ], + "ipv4": { + "addressing": "dynamic" + }, + "ssids": [ + { + "name": "transit", + "wifi-bands": [ + "5G" + ], + "bss-mode": "mesh", + "encryption": { + "proto": "psk2", + "key": "meshpassword", + "ieee80211w": "optional" + } + }, + { + "name": "2GHz Clients", + "wifi-bands": [ + "2G" + ], + "bss-mode": "ap", + "encryption": { + "proto": "psk2", + "key": "OpenWiFi", + "ieee80211w": "optional" + } + }, + { + "name": "5GHz Clients", + "wifi-bands": [ + "5G" + ], + "bss-mode": "ap", + "encryption": { + "proto": "psk2", + "key": "OpenWiFi", + "ieee80211w": "optional" + } + + } + ] + }, +``` +{% endtab %} +{% endtabs %} + +In this basic mesh, dual SSIDs are configured for clients while an SSID for mesh transit is configured for IEEE802.11s client associations. Additional mesh clients simply use the same approach, no other configuration is required for the client to participate in this mesh. + +Advanced examples with VLANs and roaming are all possible by adding additional configuration steps. diff --git a/configuration-examples/device-feature-configuration-examples/metrics.md b/configuration-examples/device-feature-configuration-examples/metrics.md new file mode 100644 index 0000000..b8fd78a --- /dev/null +++ b/configuration-examples/device-feature-configuration-examples/metrics.md @@ -0,0 +1,74 @@ +--- +description: TIP OpenWiFi 2.0 +--- + +# Metrics + +## Metrics + +Several metrics are reported during intervals to the OpenWiFi Gateway. In general metrics contain traffic counters, neighbor tables, discovered clients. + +Each OpenWiFi device is capable of sending statistics on SSID, LLDP, and associated Clients learned by the device. + +Additionally, OpenWiFi devices expose all 802.11 management data within wifi-frames and to assist network troubleshooting and client fingerprinting solutions OpenWiFi provides dhcp-snooping for all possible client exchanges over DHCP and DHCPv6. + +``` + "metrics": { + "statistics": { + "interval": 60, + "types": [ "ssids", "lldp", "clients" ] + }, + "health": { + "interval": 300 + }, + "wifi-frames": { + "filters": [ "probe", + "auth", + "assoc", + "disassoc", + "deauth", + "local-deauth", + "inactive-deauth", + "key-mismatch", + "beacon-report", + "radar-detected"] + }, + "dhcp-snooping": { + "filters": [ "ack", + "discover", + "offer", + "request", + "solicit", + "reply", + "renew" ] + } +``` + +The metrics data is sent to OpenWiFi Gateway at the intervals set where configurable. + +Metrics must be associated with the interfaces they are to report on. For example, to send DHCP data from LAN to OpenWiFi Gateway, the following configuration would apply. + +``` + { + "name": "LAN", + "role": "downstream", + "services": [ "ssh", "lldp", "dhcp-snooping" ], + "ethernet": [ + { + "select-ports": [ + "LAN*" + ] + } + ], + "ipv4": { + "addressing": "static", + "subnet": "192.168.1.1/24", + "dhcp": { + "lease-first": 10, + "lease-count": 100, + "lease-time": "6h" + } + } + } + ], +``` diff --git a/configuration-examples/device-feature-configuration-examples/multi-psk-mdu-multiple-shared-key.md b/configuration-examples/device-feature-configuration-examples/multi-psk-mdu-multiple-shared-key.md new file mode 100644 index 0000000..71ffe84 --- /dev/null +++ b/configuration-examples/device-feature-configuration-examples/multi-psk-mdu-multiple-shared-key.md @@ -0,0 +1,45 @@ +--- +description: TIP OpenWiFi 2.0 +--- + +# Multi-PSK (MDU Shared Key) + +Multiple Pre Shared Key is a popular configuration option in Multi Dwelling Unit, dormitory or similar environment where it is costly to implement complex 802.1x security however that same level of per-client security is highly desired. + +A SSID when configured for multi-psk can have multiple PSK/VID mappings. Each one of them can be bound to a specific MAC or be a wildcard. + +``` + "ssids": [ + { + "name": "MDU Wi-Fi", + "wifi-bands": [ + "5G", + "2G" + ], + "bss-mode": "ap", + "encryption": { + "proto": "psk2", + "ieee80211w": "optional", + "key": "OpenWifi" + }, + "multi-psk": [ + { + "key": "akey", + "vlan-id": 100 + }, + { + "key": "bkey" + "vlan-id": 200 + } + ], + "roaming": { + "message-exchange": "ds", + "generate-psk": true + } + } + ] +``` + +{% hint style="info" %} +Note: M-PSK passwords must be unique per `vlan-id` as the device will attempt to match security key to assigned virtual lan. In the above example, a password of `OpenWifi` will match the untagged interface of the SSID and unique password of `"akey"` will match client(s) to virtual lan 100. +{% endhint %} diff --git a/configuration-examples/device-feature-configuration-examples/passpoint-r1/README.md b/configuration-examples/device-feature-configuration-examples/passpoint-r1/README.md new file mode 100644 index 0000000..5d62bc4 --- /dev/null +++ b/configuration-examples/device-feature-configuration-examples/passpoint-r1/README.md @@ -0,0 +1,19 @@ +--- +description: TIP OpenWiFi 2.0 +--- + +# Passpoint® + +Passpoint® brings seamless, automatic and secure Wi-Fi connectivity using either pre-provisioned credentials or the SIM card in a mobile device. Passpoint provides simple, fast online sign-up and provisioning that is only required upon a user’s first visit to a Passpoint network. Once a Passpoint enabled device contains the Wi-Fi AP or network credentials, it will discover and securely connect when the user is nearby—without requiring additional user action. This makes staying connected while mobile infinitely easier, and because Passpoint employs enterprise-level security, users can feel confident their data is better protected. + +Passpoint® also delivers more value to carriers, service providers, and IT managers of enterprise networks, enabling: + +* Mobile data offload +* Wi-Fi networks for + * Hospitality, venues and enterprise + * Streamlined, enterprise-class device provisioning and credential management for enterprise and other private networks +* Wi-Fi–based services such as Wi-Fi calling, and collaboration tools +* Wi-Fi roaming agreements across carriers and service providers +* Opportunities to engage users and extract additional value from the network + +Passpoint® is already supported by most enterprise-class APs on the market today, and natively supported by major mobile operating systems including Android, iOS, macOS, and Windows 10. With active support from a wide ecosystem of device manufacturers, mobile operators, and service providers, Passpoint® benefits both users and Wi-Fi network providers diff --git a/configuration-examples/device-feature-configuration-examples/passpoint-r1/advertising-services.md b/configuration-examples/device-feature-configuration-examples/passpoint-r1/advertising-services.md new file mode 100644 index 0000000..7291f26 --- /dev/null +++ b/configuration-examples/device-feature-configuration-examples/passpoint-r1/advertising-services.md @@ -0,0 +1,19 @@ +--- +description: TIP OpenWiFi 2.0 +--- + +# Advertising Services + +Passpoint® requires ANQP to supply three information elements from the Access Point. + +## PLMN-Id + +Public Land Mobile Network Id is defined by 3GPP and comprised of two, three digit numbers to uniquely identify the Mobile Network Operator (MNO). + +## Realm + +A Fully Qualified Domain Name (FQDN) is a realm representing the service provider of the Wi-Fi service. Non MNO operators are an example of 'realm-based' service advertisements. Examples include Cable MSOs, Enterprises or other on MNO providers. Authentication methods used with realm-based configuration are EAP-TLS and EAP-TTLS. + +## OI / RCOI + +Organization Id or as defined by Wireless Broadband Alliance, Roaming Consortium Organization Id indicate the federated identity capable of authentication. Examples would be OpenRoaming, Eduroam and follow the Passpoint® EAP authentication methods. diff --git a/configuration-examples/device-feature-configuration-examples/passpoint-r1/configuration-introduction.md b/configuration-examples/device-feature-configuration-examples/passpoint-r1/configuration-introduction.md new file mode 100644 index 0000000..f9a08a8 --- /dev/null +++ b/configuration-examples/device-feature-configuration-examples/passpoint-r1/configuration-introduction.md @@ -0,0 +1,22 @@ +--- +description: TIP OpenWiFi 2.0 +--- + +# Configuration Introduction + +TIP OpenWiFi devices implement support for both the air interface and systems interfaces necessary to support Passpoint® Release 2 and above. Once also termed Hotspot 2.0, IEEE 802.11u specified added air interface fields exposing Access Network Query Protocol interactions for clients to discovery Access Point capabilities. + +Wi-Fi Alliance expanded ANQP to include Online Signup (OSU) concepts to leverage seamless onboarding and client security for Passpoint® networks. Following on from these efforts, Wireless Broadband Alliance has provided the necessary system interfaces for identity, security, mobile offload within a common federated operator solution known as OpenRoaming. + +TIP OpenWiFi enables operators to deploy the full range of Passpoint® and OpenRoaming solutions. + +| Term | Description | +| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Operator |

Wi-Fi Infrastructure Operator

Access Network Provider (ANP) as defined by OpenRoaming

| +| Venue | Deployed location of Wi-Fi service | +| Identity Provider |

Subscriber authenticating service provider

Home Service Provider (HSP) as defined by OpenRoaming

| +| Roaming Exchange | Operator and Identity Provider Authentication, Authorization, Accounting | +| ANQP |

Access Network Query Protocol contains:

  • Domain
  • Venue Name
  • Venue Info
  • Operator Friendly Name
  • IP Type
  • WAN Metric
  • Connection Capability
  • Operating Class
  • Authentication Type
  • Service Providers List
| +| GAS |

Generic Advertisement Layer 2 Service for client query

  • Client query returns:

    • Organization Identifier / Service Provider Identity
    • Domain
    • Authentication
    • Roaming Consortium List
    • Network Access Identifier Realm (NAI)
    • 3GPP Network Data
| +| OSU |

Online Signup - Advertised over ANQP contains:

  • OSU SSID
  • OSU URI
  • OSU Method
  • OSU Available Icons
  • OSU ESS (OSEN) SSID
  • OSU Description
| +| OSEN | OSU Server Authenticated Layer 2 Encryption Network | diff --git a/configuration-examples/device-feature-configuration-examples/passpoint-r1/passpoint-r-configuration.md b/configuration-examples/device-feature-configuration-examples/passpoint-r1/passpoint-r-configuration.md new file mode 100644 index 0000000..e9ba044 --- /dev/null +++ b/configuration-examples/device-feature-configuration-examples/passpoint-r1/passpoint-r-configuration.md @@ -0,0 +1,125 @@ +--- +description: TIP OpenWiFi 2.0 +--- + +# Passpoint® Configuration + +Ahead of the Provisioning service coming in release 2.1 sprint, it is possible to configure all Passpoint attributes as OpenWiFi has tested in prior OpenWiFi releases. + +Capabilities for Hotspot 2.0 / Passpoint® include: + +* venue-name +* venue-group +* venue-type +* venue-url +* auth-type +* domain-name +* nai-realm +* osen +* anqp-domain +* anqp-3gpp-cell-net +* firendly-name +* icons + +``` + "interfaces": [ + { + "name": "WAN", + "role": "upstream", + "ethernet": [ + { + "select-ports": [ + "WAN*" + ] + } + ], + "ipv4": { + "addressing": "dynamic" + }, + "ssids": [ + { + "name": "OpenRoaming", + "wifi-bands": [ + "5G" + ], + "bss-mode": "ap", + "encryption": { + "proto": "wpa-mixed", + "ieee80211w": "optional" + }, + "radius": { + "nas-identifier": "TIPLABAP101", + "chargeable-user-id": true, + "authentication": { + "host": "IP Address of RADIUS", + "port": 11812, + "secret": "passphrase", + "request-attribute": [ + { + "id": 126, + "value": "s:TIP" + } + ] + }, + "accounting": { + "host": "IP Address of RADIUS", + "port": 11813, + "secret": "passphrase", + "request-attribute": [ + { + "id": 126, + "value": "s:TIP" + } + ], + "interval": 600 + } + }, + "pass-point": { + "venue-name": [ + "eng:Example passpoint_venue", + "fra:Exemple de lieu" + ], + "venue-group": 2, + "venue-type": 8, + "venue-url": [ + "http://www.example.com/info-fra", + "http://www.example.com/info-eng" + ], + "auth-type": { + "type": "terms-and-conditions" + }, + "domain-name": "onboard.example.com", + "nai-realm": [ + "0,oss.example.com,21[5:7][2:4]" + ], + "osen": false, + "anqp-domain": 1234, + "anqp-3gpp-cell-net": [ + "310,260", + "310,410" + ], + "friendly-name": [ + "eng:TIPLabs", + "fra:TIPLabs" + ], + "icons": [ + { + "icon": "iVBORw0KGgoAAAANSUhEUgAAACIAAAAiCAYAAAA6RwvCAAAACXBIWXMAAAsSAAALEgHS3X78AAAEDklEQVRYhc1YTUgUcRR/q7uGUzsuYSClNRcbymS3wII6KNF0Cly7dHSNioIiD3Ppg9IOETHQB50S2vUqhBt1qBZ0pWuQG3VYJJ1SI8h0d4qRsnbjrW+Xv+N87VbYg2H/M/P/v/d732/W499+KA9rTFo64fECLSqBoitCBwDEAGCbxZYxAOjjZDVpxYMXpYIhqiq1BYEYtQGB1I57dEWIOPErG4iuCAKBuM08TgFAFyerHrxwDQCPmPdROmNJ3jIAoFZ9JhZAEB2crGaKDzhZjQNAnM5E6TGetQTjyiK6IsSIoZkbwiwIljhZxXOD9KgdrWklw9EiuiKEAaCbbrMUnKhxCAAynKyqDixuM+cRiOl+UyCEvI+EBRkQ6IJxurfMBJZwv66UDBHRFWHczIKrXEN+nSItgsyrGAOiRLwoPedF6YoVEIM7kGdSV4SQLRCK7KhhT4rqQcwExGMAkACgnxelUxZYUPs7ZFEg5VbxMlqk1wBgNyerIU5WO8ysAQA36XcRAIbMUKAbOFntJTe/L4Ix1hYjkE5mHbYQXiItnXhB67taOmGaOQwgleKuxN8UiMGXKRfZUAmxigXY82zW8EzOT7oRwotS0bwRXpRuOFmFUtdUBuuajRTVeB0sU9sA1QhborQ1lVFx04PlGClGf0xLJ2zjyYlKrjkz0jC/wZcrmG0p55m8L5fFZ5PbjYeHtxZk1HpzkwlGRgnI8Dt/0TVIY/cBrjkx5UXpAS07eVEKubHK67l1JRnAyKjYNRSoPXRbjRWTFyXHOLEiFsgvKmJ4zTqAMFZgPFOHzZAXpYDNUbCSwQJBrYJUgrfYgAhR9wXGInEahILMOysylVGWa0jbOGnfz2QNUoQ0bedFaVUvcSLXQAhEkoajQS2dYMs1UDELU3PrZord3wVCAw6aNKWlEzhXBHRFKMwk8p75q9jEtHRCpXEQwUR5UQo7s3UBBKczFHbiyL4ZqoYpZu6MZH9U4ZQOQxP+BRqQBUrhQhev9eaHRuUdL3VFwPnVNogtgVATHD490tA6NMFv4WtycKHtyz2mnwSeqhve4mLmm4+b/uqDYpnH2DkXWniz+NPjO/qkMTT9zdtpNoO4tYiAzOPLhQ4iOzPZ86H5RuZ98th2reXy3rlXz8Iflpr8S1n2Q+pS29yu9b7c/K88VHc9bpq1m+CdgKhN/iW4vv/z9IHNi1MX277UsYMvCe06G1zQWuu/PzQR9Ch+ZKaG8+YWotLHOqcZ12qKFxoGmjOfTk70HG/J9B1vyaBV+unzoETF7xcLHpHW+u/xyZ537VRjIlSDygKCKZpsGGjupfqwTAOSrXlXUjMYJjLkc6tcIECpOupe8J8RGyPo/+y/EGJBK6a5/+b/EU8+v+Y4AADgN/LdfxH+Qd9IAAAAAElFTkSuQmCC", + "width": 32, + "height": 32, + "type": "image/png", + "language": "fra" + }, + { + "icon": "iVBORw0KGgoAAAANSUhEUgAAACIAAAAiCAYAAAA6RwvCAAAACXBIWXMAAAsSAAALEgHS3X78AAAEDklEQVRYhc1YTUgUcRR/q7uGUzsuYSClNRcbymS3wII6KNF0Cly7dHSNioIiD3Ppg9IOETHQB50S2vUqhBt1qBZ0pWuQG3VYJJ1SI8h0d4qRsnbjrW+Xv+N87VbYg2H/M/P/v/d732/W499+KA9rTFo64fECLSqBoitCBwDEAGCbxZYxAOjjZDVpxYMXpYIhqiq1BYEYtQGB1I57dEWIOPErG4iuCAKBuM08TgFAFyerHrxwDQCPmPdROmNJ3jIAoFZ9JhZAEB2crGaKDzhZjQNAnM5E6TGetQTjyiK6IsSIoZkbwiwIljhZxXOD9KgdrWklw9EiuiKEAaCbbrMUnKhxCAAynKyqDixuM+cRiOl+UyCEvI+EBRkQ6IJxurfMBJZwv66UDBHRFWHczIKrXEN+nSItgsyrGAOiRLwoPedF6YoVEIM7kGdSV4SQLRCK7KhhT4rqQcwExGMAkACgnxelUxZYUPs7ZFEg5VbxMlqk1wBgNyerIU5WO8ysAQA36XcRAIbMUKAbOFntJTe/L4Ix1hYjkE5mHbYQXiItnXhB67taOmGaOQwgleKuxN8UiMGXKRfZUAmxigXY82zW8EzOT7oRwotS0bwRXpRuOFmFUtdUBuuajRTVeB0sU9sA1QhborQ1lVFx04PlGClGf0xLJ2zjyYlKrjkz0jC/wZcrmG0p55m8L5fFZ5PbjYeHtxZk1HpzkwlGRgnI8Dt/0TVIY/cBrjkx5UXpAS07eVEKubHK67l1JRnAyKjYNRSoPXRbjRWTFyXHOLEiFsgvKmJ4zTqAMFZgPFOHzZAXpYDNUbCSwQJBrYJUgrfYgAhR9wXGInEahILMOysylVGWa0jbOGnfz2QNUoQ0bedFaVUvcSLXQAhEkoajQS2dYMs1UDELU3PrZord3wVCAw6aNKWlEzhXBHRFKMwk8p75q9jEtHRCpXEQwUR5UQo7s3UBBKczFHbiyL4ZqoYpZu6MZH9U4ZQOQxP+BRqQBUrhQhev9eaHRuUdL3VFwPnVNogtgVATHD490tA6NMFv4WtycKHtyz2mnwSeqhve4mLmm4+b/uqDYpnH2DkXWniz+NPjO/qkMTT9zdtpNoO4tYiAzOPLhQ4iOzPZ86H5RuZ98th2reXy3rlXz8Iflpr8S1n2Q+pS29yu9b7c/K88VHc9bpq1m+CdgKhN/iW4vv/z9IHNi1MX277UsYMvCe06G1zQWuu/PzQR9Ch+ZKaG8+YWotLHOqcZ12qKFxoGmjOfTk70HG/J9B1vyaBV+unzoETF7xcLHpHW+u/xyZ537VRjIlSDygKCKZpsGGjupfqwTAOSrXlXUjMYJjLkc6tcIECpOupe8J8RGyPo/+y/EGJBK6a5/+b/EU8+v+Y4AADgN/LdfxH+Qd9IAAAAAElFTkSuQmCC", + "width": 32, + "height": 32, + "type": "image/png", + "language": "eng" + } + ] + } + } + ] + }, +``` diff --git a/configuration-examples/device-feature-configuration-examples/qos.md b/configuration-examples/device-feature-configuration-examples/qos.md new file mode 100644 index 0000000..72f19d8 --- /dev/null +++ b/configuration-examples/device-feature-configuration-examples/qos.md @@ -0,0 +1,6 @@ +--- +description: OpenWiFi +--- + +# QoS + diff --git a/configuration-examples/device-feature-configuration-examples/radius-authenticated-ssid/README.md b/configuration-examples/device-feature-configuration-examples/radius-authenticated-ssid/README.md new file mode 100644 index 0000000..eccd312 --- /dev/null +++ b/configuration-examples/device-feature-configuration-examples/radius-authenticated-ssid/README.md @@ -0,0 +1,100 @@ +--- +description: TIP OpenWiFi 2.0 +--- + +# RADIUS Authenticated SSID + +When authenticating clients with back office RADIUS systems, the configuration of OpenWiFi permits this on a per SSID basis. + +{% tabs %} +{% tab title="Simple RADIUS" %} +``` + "interfaces": [ + { + "name": "WAN", + "role": "upstream", + "ethernet": [ + { + "select-ports": [ + "WAN*" + ] + } + ], + "ipv4": { + "addressing": "dynamic" + }, + "ssids": [ + { + "name": "OpenWifi", + "wifi-bands": [ + "5G" + ], + "bss-mode": "ap", + "encryption": { + "proto": "wpa2", + "ieee80211w": "optional" + }, + "radius": { + "authentication": { + "host": "192.168.178.192", + "port": 1812, + "secret": "secret" + }, + "accounting": { + "host": "192.168.178.192", + "port": 1813, + "secret": "secret" + } + } + } + ] + }, +``` +{% endtab %} + +{% tab title="EAP-Local SSID" %} +``` + "ssids": [ + { + "name": "OpenWifi", + "wifi-bands": [ + "2G" + ], + "bss-mode": "ap", + "encryption": { + "proto": "wpa2", + "ieee80211w": "optional" + }, + "certificates": { + "ca-certificate": "/etc/ucentral/cas.pem", + "certificate": "/etc/ucentral/cert.pem", + "private-key": "/etc/ucentral/key.pem" + }, + "radius": { + "local": { + "server-identity": "OpenWiFi-Local-EAP", + "users": [ + { + "user-name": "open", + "password": "wifi" + } + ] + } + } + } + ] + }, +``` +{% endtab %} +{% endtabs %} + +Many parameters are possible with RADIUS authentications given the many methods in use worldwide. Many of the EAP methods have configuration options described below. + +| RADIUS Attribute | Description | +| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| nas-identifier | Unique NAS Id used with RADIUS server | +| chargeable-user-id | Chargeable User Entity per RFC4372 | +| local |

Local RADIUS within AP device

  • server-identity

    • users - Local EAP users based on username, PreShared Key and VLAN id
| +| authentication |

RADIUS server

  • host IP address
  • port ( example 1812)
  • secret ( Shared secret with RADIUS server )

Additional methods within Access-Request

  • request-attribute ( id of RADIUS server )

    • id ( numeric value of RADIUS server )
    • value

      Any sub-value defined as integer RADIUS attribute value

| +| accounting |

RADIUS server

  • host IP address
  • port ( example 1813)
  • secret ( Shared secret with RADIUS server )

Additional methods within Access-Request sent in Accounting

  • request-attribute ( id of RADIUS server )

    • id ( numeric value of RADIUS server )
    • value

      Any sub-value defined as integer RADIUS attribute value

| +| accounting | interval ( Interim accounting interval defined in seconds ) | diff --git a/configuration-examples/device-feature-configuration-examples/radius-authenticated-ssid/dynamic-vlans-with-radius.md b/configuration-examples/device-feature-configuration-examples/radius-authenticated-ssid/dynamic-vlans-with-radius.md new file mode 100644 index 0000000..432dc5f --- /dev/null +++ b/configuration-examples/device-feature-configuration-examples/radius-authenticated-ssid/dynamic-vlans-with-radius.md @@ -0,0 +1,62 @@ +--- +description: TIP OpenWiFi 2.0 +--- + +# Dynamic VLANs with RADIUS + +In many deployment scenarios, user authentication is centralized with RADIUS systems. In addition, users may have association to their own networks or private networks. A common approach for this is to dynamically assign VLANs to Wi-Fi subscribers as they join the OpenWiFi network. + +To configure Dynamic VLANs with RADIUS, associate an SSID with RADIUS authentication, and associate the interface to "upstream" role as dynamic VLANs are most likely to be applicable across the service provider, venue, enterprise network. + +``` + "interfaces": [ + { + "name": "WAN", + "role": "upstream", + "ethernet": [ + { + "select-ports": [ + "WAN*" + ] + } + ], + "ipv4": { + "addressing": "dynamic" + }, + "ssids": [ + { + "name": "OpenWifi", + "wifi-bands": [ + "5G", "2G" + ], + "bss-mode": "ap", + "encryption": { + "proto": "wpa2", + "ieee80211w": "optional" + }, + "radius": { + "authentication": { + "host": "192.168.178.192", + "port": 1812, + "secret": "secret" + }, + "accounting": { + "host": "192.168.178.192", + "port": 1813, + "secret": "secret" + } + } + } + ] + }, +``` + +## RADIUS Access-Accept + +OpenWiFi devices will determine a VLAN is associated to the authentication of a subscriber when the access-accept message returns the following attribute value pairs: + +* Tunnel-Type = 13 +* Tunnel-Medium-Type = 6 +* Tunnel-Private-Group-Id = VLAN Id Number + +Upon return of an access-accept from RADIUS, based on any method chosen for security, OpenWiFi will dynamically create a VLAN Id as described in Tunnel-Private-Group-Id, associated to the interface role, in this example upstream. diff --git a/configuration-examples/device-feature-configuration-examples/roaming-rrm-and-son.md b/configuration-examples/device-feature-configuration-examples/roaming-rrm-and-son.md new file mode 100644 index 0000000..809208f --- /dev/null +++ b/configuration-examples/device-feature-configuration-examples/roaming-rrm-and-son.md @@ -0,0 +1,130 @@ +--- +description: TIP OpenWiFi 2.0 +--- + +# Roaming RRM and SON + +Radio Resource Management and Self Organizing Network features in OpenWiFi 2.0 operate by default in local mode from the Access Point device without dependency on the cloud. Data and state related to client steering and roaming is also possible in co-operation with the cloud when so configured. + +Metrics and telemetry are sent to the cloud as desired based on configuration however operation of 802.11k/v/r behavior and autonomous channel control are built in features of all OpenWiFi 2.0 Access Points. + +## Steering + +OpenWiFi services feature "wifi-steering" determines the operating parameters of RRM on the Access Point. + +``` + "services": { + "wifi-steering": { + "mode": "local", + "network": "upstream", + "assoc-steering": true, + "required-snr": -75, + "required-probe-snr": -70, + "required-roam-snr": -85, + "load-kick-threshold": 90 + }, +``` + +When mode is set to local, the Access Point handles steering decisions autonomously with the surrounding OpenWifi devices.\ +Which network association, in this case "upstream" will steering be operating on. Note in prior examples most service provider, venue, enterprise services operate on the WAN side upstream network of the Access Point. + +| Parameter | Value | +| ------------------- | ----------------------------------------------------------------------------- | +| mode: local | autonomous operation | +| network: upstream | performs roaming among SSIDs on upstream interfaces | +| assoc-steering | reject client association requests when the UE is subject to a steering event | +| required-snr | minimum signal in dBm a client will be permitted to remain connected | +| required-probe-snr | minimum signal level in dBm for management probes to be replied to | +| required-roam-snr | minimum signal level in dBm client roaming threshold | +| load-kick-threshold | minimum channel load as % available before clients are kicked | + +## Apply Wi-Fi Steering to enable 802.11r Fast Roaming SSIDs + +``` + "ssids": [ + { + "name": "OpenWiFi Roaming", + "wifi-bands": [ + "2G", "5G" + ], + "bss-mode": "ap", + "encryption": { + "proto": "psk2", + "key": "OpenWiFi", + "ieee80211w": "optional" + }, + "roaming": { + "message-exchange": "air", + "generate-psk": true, + "domain-identifier": "EFAB" + }, + "services": [ "wifi-steering" ] + } + ] + }, +``` + +Each SSID to participate in roaming must have "services" : \[ "wifi-steering" ] associated. + +Additional fast roaming configuration is possible including setting message-exchange either to "air" or "ds" to determine pre authenticated message exchange occurs over the air or distribution system. + +The generate-psk option generates FT response locally for PSK networks. This avoids use of PMK-R1 push/pull from other APs with FT-PSK networks. + +Configuring domain-identifier sets Mobility Domain identifier (dot11FTMobilityDomainID, MDID) permitting segmentation of fast roaming RF topologies. + +When pmk-r0-key-holder and pmk-r1-key-holder are left un-configured, the pairwise master key R0 and R1 will generate a deterministic key automatically for fast mobility domain exchange over the air. + +## RRM 802.11k + +To enable 80211k parameters, associate these on a participating SSID basis. + +``` + "ssids": [ + { + "name": "OpenWiFi Roaming", + "wifi-bands": [ + "2G", "5G" + ], + "bss-mode": "ap", + "encryption": { + "proto": "psk2", + "key": "OpenWiFi", + "ieee80211w": "optional" + }, + "roaming": { + "message-exchange": "air", + "generate-psk": true, + "domain-identifier": "EFAB" + }, + "rrm": { + "neighbor-reporting": true, + "ftm-responder": true, + "stationary-ap": true + }, + "services": [ "wifi-steering" ] + } + ] + }, +``` + +In addition to 802.11k features for neighbor reporting, fine timing measurement responder and stationary ap indication, OpenWiFi also supports LCI measurement, Civic Location subelement as well. + +## Automatic Channel Balancing + +As part of "wifi-steering" feature, autonomous channel management algorithm may be enabled to establish a self organizing Wi-Fi network. + +The auto-channel setting operates in co-ordination with other OpenWiFi Access Points by enumerating the newest AP in the network, then running neighbor and RF scans to determine the best channel of operation. Once the newest AP completes this process, the next AP is sequence will run the same algorithm for channel balancing until all APs in the network complete. The entire process may take up to 5 minutes the first time a network is powered on. The algorithm will re-run every 12 hours. + +``` + "services": { + "wifi-steering": { + "mode": "local", + "network": "upstream", + "auto-channel": true, + "assoc-steering": true, + "required-snr": -75, + "required-probe-snr": -70, + "required-roam-snr": -85, + "load-kick-threshold": 90 + }, +``` diff --git a/configuration-examples/device-feature-configuration-examples/services.md b/configuration-examples/device-feature-configuration-examples/services.md new file mode 100644 index 0000000..d82a450 --- /dev/null +++ b/configuration-examples/device-feature-configuration-examples/services.md @@ -0,0 +1,136 @@ +--- +description: TIP OpenWiFi 2.0 +--- + +# Services + +OpenWiFi devices have global services that operate either independently system wide or as an association to a physical or logical interface. + +Within the "services" configuration block, define the operating mode for each service, then associate a service with an interface. + +## SSH + +Secure shell may optionally be enabled on OpenWiFi devices, associated to specific interface(s), and optionally support operator defined keys or password authentication. + +``` + "services": { + "ssh": { + "port": 22, + "authorized-keys": { + "items": [ + "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC0ghdSd2D2y08TFowZLMZn3x1/Djw3BkNsIeHt/Z+RaXwvfV1NQAnNdaOngMT/3uf5jZtYxhpl+dbZtRhoUPRvKflKBeFHYBqjZVzD3r4ns2Ofm2UpHlbdOpMuy9oeTSCeF0IKZZ6szpkvSirQogeP2fe9KRkzQpiza6YxxaJlWw== user@example", + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ4FDjyCsg+1Mh2C5G7ibR3z0Kw1dU57kfXebLRwS6CL bob@work", + "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBP/JpJ/KHtKKImzISBDwLO0/EwytIr4pGZQXcP6GCSHchLMyfjf147KNlF9gC+3FibzqKH02EiQspVhRgfuK6y0= alice@home" + ] + } + } + } +``` + +### Associate Service to Interface + +``` + { + "name": "LAN", + "role": "downstream", + "services": [ "ssh" ], + "ethernet": [ + { + "select-ports": [ + "LAN*" + ] + } + ], +``` + +### Operator Key Management + +For production deployments, it is recommended to assign operator SSH key from the OpenWiFi Provisioning configuration of the Venue or Entity which the device associates. + +In this way, an operator may ensure their standard SSH key is delivered to all devices on a network operating region basis. All keys remain base64 encoded when added to the device. + +## NTP + +Network time protocol for OpenWiFi devices may be configured to listen for time synchronization from NTP sources and may also be configured to supply NTP source. + +``` + "services": { + "ntp": { + "servers": [ + "0.openwrt.pool.ntp.org", + "1.openwrt.pool.ntp.org" + ] + } + } +``` + +### Associate to an Interface + +``` + { + "name": "WAN", + "role": "downstream", + "services": [ "ntp" ], + "ethernet": [ + { + "select-ports": [ + "WAN*" + ] + } + ], + "ipv4": { + "addressing": "dynamic" + } + }, +``` + +## LLDP + +Link Layer Discovery Protocol describes interfaces and capabilities between directly attached neighbors over Layer 2. + +``` + "lldp": { + "describe": "OpenWiFi", + "location": "Stadium Level 2" + }, +``` + +Associate "lldp" as a services attribute to any interface. + +## MDNS + +To assist in device or service discovery over smaller networks, multicast DNS (mDNS) protocol if often used. In an mDNS environment there is no local name server for resources to leverage. mDNS zero-configuration service effectively behaves as unicast Domain Name Service (DNS). + +``` + "mdns": { + "enable": true + }, +``` + +Associate "mdns" as a services attribute to any interface. + +## Syslog + +Remote syslog systems may be configured to receive device logs in a central location. This content is standard device log and not related to telemetry for metrics and service information received by the OpenWiFi Gateway. Valid port range is from 100 - 65535 with operation over UDP or TCP. + +``` + "log": { + "host": "Syslog Server IP", + "port": 514, + "proto": "udp" + }, +``` + +Associate "log" as a services attribute to appropriate interface. + +## IGMP + +When enabled the OpenWiFi device will process IGMP Proxy. + +``` + "igmp": { + "enable": true + }, +``` + +Associate "igmp" as a services attribute to any interface participating in IGMP Proxy. diff --git a/configuration-examples/device-feature-configuration-examples/switching/README.md b/configuration-examples/device-feature-configuration-examples/switching/README.md new file mode 100644 index 0000000..2cff769 --- /dev/null +++ b/configuration-examples/device-feature-configuration-examples/switching/README.md @@ -0,0 +1,306 @@ +--- +description: TIP OpenWiFi 2.0 +--- + +# Switching + +{% hint style="info" %} +Switching Features Remain Under Test +{% endhint %} + +TIP OpenWiFi use of the OpenWrt operating system combined with new virtual data plane present in all images for 2.0 major release and the uCentral data model make it possible to include PoE access switching as a cloud managed component of the OpenWiFi stack. + +Nightly builds include supported switch platforms. + +Currently the list of features for switching include: + +* IEEE 802.1Q VLAN + * Port based Untagged + * Tagged trunk +* IEEE 802.1ad Q-inQ +* VxLAN +* PoE Auto Power +* Port Mirroring / Monitor +* Link Aggregation +* Link Layer Discovery Protocol +* Port Speed Control + +### Configuring a Switch + +All ports needs to be specified for link negotiation to occur. In the below example, the "ethernet" section defines the physical port. The "interfaces" configuration will cause the physical port to negotiate. Effectively removal of a "select-ports" for a physical port in any or all "interfaces" is the equivalent of an interface in shutdown state. + +``` + "ethernet": [ + { + "select-ports": [ + "WAN1" + ], + "speed": 1000, + "duplex": "full" + }, + { + "select-ports": [ + "WAN2" + ], + "speed": 1000, + "duplex": "full" + }, + { + "select-ports": [ + "WAN3" + ], + "speed": 1000, + "duplex": "full" + }, + { + "select-ports": [ + "WAN4" + ], + "speed": 1000, + "duplex": "full" + }, + { + "select-ports": [ + "WAN5" + ], + "speed": 1000, + "duplex": "full" + }, + { + "select-ports": [ + "WAN6" + ], + "speed": 1000, + "duplex": "full" + }, + { + "select-ports": [ + "WAN7" + ], + "speed": 1000, + "duplex": "full", + "vlan-tag": "auto" + }, + { + "select-ports": [ + "WAN8" + ], + "speed": 1000, + "duplex": "full", + "vlan-tag": "auto" + }, + { + "select-ports": [ + "WAN9" + ], + "speed": 1000, + "duplex": "full" + }, + { + "select-ports": [ + "WAN10" + ], + "speed": 1000, + "duplex": "full" + }, + { + "select-ports": [ + "WAN11" + ], + "speed": 1000, + "duplex": "full" + }, + { + "select-ports": [ + "WAN12" + ], + "speed": 1000, + "duplex": "full" + } + ], +``` + +Without any "interfaces" defined, the ifconfig on the switch will return eth0, lan1, lo as an output. When adding "interfaces" additional ports become active and also visible. + +``` + "interfaces": [ + { + { + "name": "VLAN-30-Ports", + "role": "downstream", + "services": [ "lldp" ], + "vlan": { + "id": 30, + "proto": "802.1q" + }, + "ethernet": [ + { + "select-ports": [ + "WAN7", "WAN8" + ] + } + ] + } +``` + +Vlan-Id 30 has been assigned to interfaces 7 and 8 on the switch. Traffic is isolated among participating ports. + +#### Ifconfig output example + +``` +# ifconfig +down1v30 Link encap:Ethernet HWaddr 90:3C:B3:39:C0:C1 + inet6 addr: fe80::923c:b3ff:fe39:c0c1/64 Scope:Link + UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 + RX packets:79 errors:0 dropped:0 overruns:0 frame:0 + TX packets:10 errors:0 dropped:0 overruns:0 carrier:0 + collisions:0 txqueuelen:1000 + RX bytes:22135 (21.6 KiB) TX bytes:1036 (1.0 KiB) + +eth0 Link encap:Ethernet HWaddr 90:3C:B3:39:C0:C0 + inet6 addr: fe80::923c:b3ff:fe39:c0c0/64 Scope:Link + UP BROADCAST RUNNING MULTICAST MTU:1504 Metric:1 + RX packets:31617 errors:0 dropped:0 overruns:0 frame:0 + TX packets:7479 errors:0 dropped:0 overruns:0 carrier:0 + collisions:0 txqueuelen:1000 + RX bytes:4293282 (4.0 MiB) TX bytes:1228185 (1.1 MiB) + Interrupt:24 Memory:c000000-bb00a3ff + +lan1 Link encap:Ethernet HWaddr 90:3C:B3:39:C0:C1 + UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 + RX packets:27321 errors:0 dropped:69 overruns:0 frame:0 + TX packets:5445 errors:0 dropped:0 overruns:0 carrier:0 + collisions:0 txqueuelen:1000 + RX bytes:2893034 (2.7 MiB) TX bytes:825702 (806.3 KiB) + +lan7 Link encap:Ethernet HWaddr 90:3C:B3:39:C0:C7 + UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 + RX packets:2204 errors:0 dropped:0 overruns:0 frame:0 + TX packets:507 errors:0 dropped:0 overruns:0 carrier:0 + collisions:0 txqueuelen:1000 + RX bytes:421385 (411.5 KiB) TX bytes:100251 (97.9 KiB) + +lan8 Link encap:Ethernet HWaddr 90:3C:B3:39:C0:C8 + UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 + RX packets:1241 errors:0 dropped:0 overruns:0 frame:0 + TX packets:496 errors:0 dropped:0 overruns:0 carrier:0 + collisions:0 txqueuelen:1000 + RX bytes:220496 (215.3 KiB) TX bytes:98164 (95.8 KiB) + +lo Link encap:Local Loopback + inet addr:127.0.0.1 Mask:255.0.0.0 + inet6 addr: ::1/128 Scope:Host + UP LOOPBACK RUNNING MTU:65536 Metric:1 + RX packets:958 errors:0 dropped:0 overruns:0 frame:0 + TX packets:958 errors:0 dropped:0 overruns:0 carrier:0 + collisions:0 txqueuelen:1000 + RX bytes:76410 (74.6 KiB) TX bytes:76410 (74.6 KiB) + +up Link encap:Ethernet HWaddr 90:3C:B3:39:C0:C1 + inet6 addr: fe80::923c:b3ff:fe39:c0c1/64 Scope:Link + UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 + RX packets:27027 errors:0 dropped:0 overruns:0 frame:0 + TX packets:4368 errors:0 dropped:0 overruns:0 carrier:0 + collisions:0 txqueuelen:1000 + RX bytes:3008700 (2.8 MiB) TX bytes:587431 (573.6 KiB) + +up0v0 Link encap:Ethernet HWaddr 90:3C:B3:39:C0:C1 + inet addr:10.75.0.154 Bcast:10.75.0.255 Mask:255.255.255.0 + inet6 addr: fe80::923c:b3ff:fe39:c0c1/64 Scope:Link + UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 + RX packets:22673 errors:0 dropped:0 overruns:0 frame:0 + TX packets:3865 errors:0 dropped:0 overruns:0 carrier:0 + collisions:0 txqueuelen:1000 + RX bytes:2390361 (2.2 MiB) TX bytes:525377 (513.0 KiB) +``` + +#### Bridge Vlan Table Output + +``` +# bridge vlan +port vlan-id +lan1 4090 PVID Egress Untagged +lan7 30 PVID Egress Untagged +lan8 30 PVID Egress Untagged +up 30 + 4090 +# +``` + +### Assigning VLANs to Ports + +To define additional VLAN memberships to any port, create additional "interfaces" configuration. + +``` + { + "name": "VLAN-30-Ports", + "role": "upstream", + "services": [ "lldp" ], + "vlan": { + "id": 30, + "proto": "802.1q" + }, + "ethernet": [ + { + "select-ports": [ + "WAN7", "WAN8" + ] + } + ] + }, + { + "name": "VLAN-40-Ports", + "role": "upstream", + "services": [ "lldp" ], + "vlan": { + "id": 40, + "proto": "802.1q" + }, + "ethernet": [ + { + "select-ports": [ + "WAN7", "WAN8" + ] + } + ] + } +``` + +#### Ifconfig and Bridge Results + +``` +up1v30 Link encap:Ethernet HWaddr 90:3C:B3:39:C0:C1 + inet6 addr: fe80::923c:b3ff:fe39:c0c1/64 Scope:Link + UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 + RX packets:1178 errors:0 dropped:0 overruns:0 frame:0 + TX packets:8 errors:0 dropped:0 overruns:0 carrier:0 + collisions:0 txqueuelen:1000 + RX bytes:245923 (240.1 KiB) TX bytes:816 (816.0 B) + +up2v40 Link encap:Ethernet HWaddr 90:3C:B3:39:C0:C1 + inet6 addr: fe80::923c:b3ff:fe39:c0c1/64 Scope:Link + UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 + RX packets:106 errors:0 dropped:0 overruns:0 frame:0 + TX packets:8 errors:0 dropped:0 overruns:0 carrier:0 + collisions:0 txqueuelen:1000 + RX bytes:34638 (33.8 KiB) TX bytes:816 (816.0 B) + + +# bridge vlan +port vlan-id +lan1 4090 PVID Egress Untagged +lan7 30 + 40 +lan8 30 + 40 +up 30 + 40 + 4090 +``` + + + + + + + diff --git a/configuration-examples/device-feature-configuration-examples/switching/port-speed.md b/configuration-examples/device-feature-configuration-examples/switching/port-speed.md new file mode 100644 index 0000000..d51f0b4 --- /dev/null +++ b/configuration-examples/device-feature-configuration-examples/switching/port-speed.md @@ -0,0 +1,35 @@ +--- +description: OpenWiFi 2.1 +--- + +# Port Speed + +Configuring port speed and operation is most commonly done with PoE access switches however the same configurations are possible for all OpenWiFi device types. + +By default all ports attempt 1,000 Mb/s full duplex operation. + +``` + "ethernet": [ + { + "select-ports": [ + "WAN1" + ], + "speed": 100, + "duplex": "half" + }, + { + "select-ports": [ + "WAN2" + ], + "speed": 1000, + "duplex": "full" + }, + { + "select-ports": [ + "WAN3" + ], + "speed": 100, + "duplex": "half" + } + ], +``` diff --git a/configuration-examples/device-feature-configuration-examples/vxlan.md b/configuration-examples/device-feature-configuration-examples/vxlan.md new file mode 100644 index 0000000..068f870 --- /dev/null +++ b/configuration-examples/device-feature-configuration-examples/vxlan.md @@ -0,0 +1,59 @@ +--- +description: TIP OpenWiFi 2.0 +--- + +# VxLAN + +VXLAN’s goal is allowing dynamic large scale isolated virtual L2 networks to be created for virtualized and multi-tenant environments. It does this by encapsulating Ethernet frames in VXLAN packets which when deployed in Wi-Fi topologies can create highly extensible Layer 2 inter-network domains over large campus, MDU, venue service networks. + +VxLAN header uses a 24-bit VNID as a unique layer 2 forwarding domain value. VxLAN maintains layer 2 isolation between the forwarding domains and does not leak MAC addresses into upstream switches. Through the use of 24 bits in VNID VxLAN scales up to 16 million unique LAN forwarding domains. + +The VXLAN encapsulation method is IP based and provides for a virtual L2 network. With VXLAN the full Ethernet Frame (with the exception of the Frame Check Sequence: FCS) is carried as the payload of a UDP packet. VXLAN utilizes a 24-bit VXLAN header, to identify virtual networks. This header provides for up to 16 million virtual L2 networks. + +Frame encapsulation is done by an entity known as a VxLAN Tunnel Endpoint (VTEP.) A VTEP has two logical interfaces: an uplink and a downlink. The uplink is responsible for receiving VxLAN frames and acts as a tunnel endpoint with an IP address used for routing VxLAN encapsulated frames. + +The VTEP in a TIP OpenWiFi device would be a management interface or designated uplink port(s). VTEP in an AP would be the AP WAN interface, or otherwise designated management interface (such as sub-interface on bridge wan). + +In a traditional L2 switch a behavior known as flood and learn is used for unknown destinations (i.e. a MAC not stored in the MAC table). This means that if there is a miss when looking up the MAC the frame is flooded out all ports except the one on which it was received. When a response is sent the MAC is then learned and written to the table. + +The next frame for the same MAC will not incur a miss because the table will reflect the port it exists on. VXLAN preserves this behavior over an IP network using IP multicast groups. + +## Configure VxLAN + +OpenWiFi device will establish a VTEP adjacency to the upstream switch. It is anticipated that any Wi-Fi networks in a VxLAN topology are associated to "upstream" interface(s). + +The following example creates a VxLAN endpoint from a WAN upstream port that will participate in VLAN 100, encapsulate this into VxLAN where it may be distributed across the campus or venue transparently. + +``` + "interfaces": [ + { + "name": "WAN", + "role": "upstream", + "ethernet": [ + { + "select-ports": [ + "WAN*" + ] + } + ], + "ipv4": { + "addressing": "dynamic" + } + }, + { + "name": "VXLAN", + "role": "upstream", + "vlan": { + "id": 100 + }, + "tunnel": { + "proto": "vxlan", + "peer-address": "192.168.178.9", + "peer-port": 4789 + }, + "ipv4": { + "addressing": "static", + "subnet": "10.0.0.1/24" + } + }, +``` diff --git a/configuration-examples/device-feature-configuration-examples/wds-topologies.md b/configuration-examples/device-feature-configuration-examples/wds-topologies.md new file mode 100644 index 0000000..8d5d708 --- /dev/null +++ b/configuration-examples/device-feature-configuration-examples/wds-topologies.md @@ -0,0 +1,125 @@ +--- +description: OpenWiFi 2.0 +--- + +# WDS + +Wireless Distribution System (WDS) supports an Access Point, Station and Repeater mode of operation. OpenWiFi 2.0 supports all three. + +In the below example, the LAN side of the Access Point at the top of the topology will be wirelessly bridged to the LAN side of the Access Point Station at the bottom of the topology. + +{% tabs %} +{% tab title="WDS-AP" %} +``` + "interfaces": [ + { + "name": "WAN", + "role": "upstream", + "services": [ "lldp" ], + "ethernet": [ + { + "select-ports": [ + "WAN*" + ] + } + ], + "ipv4": { + "addressing": "dynamic" + } + }, + { + "name": "LAN", + "role": "downstream", + "services": [ "ssh", "lldp" ], + "ethernet": [ + { + "select-ports": [ + "LAN*" + ] + } + ], + "ssids": [ + { + "name": "OpenWifi_WDS_AP", + "wifi-bands": [ + "5G" + ], + "bss-mode": "wds-ap", + "encryption": { + "proto": "psk2", + "key": "OpenWifi", + "ieee80211w": "optional" + }, + "roaming": { + "message-exchange": "ds", + "generate-psk": true + } + } + ], + "ipv4": { + "addressing": "static", + "subnet": "192.168.10.1/24", + "dhcp": { + "lease-first": 10, + "lease-count": 100, + "lease-time": "6h" + } + } + } + ], +``` +{% endtab %} + +{% tab title="WDS-STA" %} +``` + "interfaces": [ + { + "name": "WAN", + "role": "upstream", + "services": [ "lldp" ], + "ethernet": [ + { + "select-ports": [ + "WAN*" + ] + } + ], + "ipv4": { + "addressing": "dynamic" + } + }, + { + "name": "LAN", + "role": "downstream", + "services": [ "ssh", "lldp" ], + "ethernet": [ + { + "select-ports": [ + "LAN*" + ] + } + ], + "ssids": [ + { + "name": "OpenWifi_WDS_AP", + "wifi-bands": [ + "5G" + ], + "bss-mode": "wds-sta", + "encryption": { + "proto": "psk2", + "key": "OpenWifi", + "ieee80211w": "optional" + }, + "roaming": { + "message-exchange": "ds", + "generate-psk": true + } + } + ], + } +``` +{% endtab %} +{% endtabs %} + +In this configuration, LAN clients of the WDS Station AP receive IP addresses from the WDS Access Point AP from its LAN side DHCP service, via WDS link at 5GHz. diff --git a/configuration-examples/device-feature-configuration-examples/zero-touch-provisioning.md b/configuration-examples/device-feature-configuration-examples/zero-touch-provisioning.md new file mode 100644 index 0000000..33f6957 --- /dev/null +++ b/configuration-examples/device-feature-configuration-examples/zero-touch-provisioning.md @@ -0,0 +1,74 @@ +--- +description: OpenWiFi 2.0 +--- + +# Zero Touch Provisioning + +OpenWiFi supports Zero Touch Provisioning in a number of ways. + +* Zero Touch Mesh +* Zero Touch WDS +* Zero Touch Provisioning ( Provisioning Services in upcoming 2.5/2.6 Release ) + +### Onboarding + +OpenWiFi makes use of TIP device certificates present on every access point as a secure identity from which to automate a number of Zero Touch operations. + +Onboarding is a local EAP-TLS based authentication service available on any OpenWiFi device that works together with default OpenWiFi _firstboot_ behavior to scan for `"OpenWifi-onboarding"` SSID, associate to that SSID, when challenged supply TIP root signed device certificate. + +#### Onboarding Steps + +1. Provision an Access Point for onboarding role as an SSID config\ + `{` \ + `"purpose": "onboarding-ap",` \ + `"bss-mode": "ap",` \ + `"encryption": { "proto": "wpa2", "ieee80211w": "required" },` \ + `"certificates": { "use_local_certificates": true },` \ + `"radius": { "local":` \ + `{ "server-identity": "uCentral-EAP" }` \ + `},` \ + `"name": "OpenWifi-onboarding",` \ + `"wifi-bands": [ "2G" ]` \ + `}` +2. Ensure the SSID for onboarding use provides network connectivity for clients + * Any topology such as NAT, Bridge, VLAN may be used + * Any radio(s) may be used +3. Firstboot devices with no WAN wired port detected will + * Enable all radios + * Scan for SSID "OpenWifi-onboarding" + * Associate and when challenged use TIP certificate as identity + * Obtain IP connection using DHCP over wireless interface association to onboarding AP + * Connect to SDK, obtain provisioning from OpenWiFi Gateway service + * Reload configuration + +### Zero Touch Mesh + +Deployment of Mesh may have multiple Mesh Client access points with no wired connectivity. These devices use IEEE802.11s Mesh participating interface(s) as transit for WAN / LAN connections. + +In a Zero Touch Mesh deployment, the Gateway Access Point, sometimes termed the Root node, advertises mesh participating interfaces when `"bss-mode": "mesh"` is applied to an SSID. Please see [mesh.md](mesh.md "mention") for further details on initial setup. + +Mesh Client Access Points needing to associate wirelessly for initial provisioning to join the mesh network, may be served using the onboarding feature of OpenWiFi. + +Adding an SSID to the Mesh Gateway Access Point configuration to advertise `"OpenWifi-onboarding"` enables initial boot of any OpenWiFi Access Point to reach the OpenWiFi Gateway. + +Upon connection to Onboarding, the Access Point obtains management network access from the upstream Access Point providing `"onboarding-ap"` service. + +With management network access, reachability for the Mesh Client Access Point to the OpenWiFi Gateway should be possible, device provisioning stage will initiate with the production configuration being loaded to the client device. + +Once processed, client Access Point will have receive provisioning to join the Mesh network as a Mesh Client Access Point. + +### Zero Touch WDS + +Deployment of WDS links may have multiple WDS client devices with no wired WAN connectivity. WDS Access Points use the 4-tuple frame header with participating WDS Clients. Therefore WDS Clients must first receive provisioning from the OpenWiFi Gateway for their production state as a WDS link participant. + +WDS Client Access Points needing to associate wirelessly for initial provisioning to join the WDS network, may be served using the onboarding feature of OpenWiFi from the WDS Root Access Point at the top of the topology with a `"bss-mode": "ap"` SSID for onboarding. + +Adding an SSID to the WDS Root Access Point configuration to advertise `"OpenWifi-onboarding"` enables initial boot of any OpenWiFi Access Point to reach the OpenWiFi Gateway. + +Upon connection to Onboarding, the WDS Client Access Point obtains management network access from the upstream WDS Root Access Point providing `"onboarding-ap"` service. + +With management network access, reachability for the WDS Client Access Point to the OpenWiFi Gateway should be possible, device provisioning stage will initiate with the production configuration being loaded to the client device. For more information on WDS configuration please consult [WDS](wds-topologies.md). + +Once processed, WDS Client Access Point will have receive provisioning to join the WDS link as a Client WDS node. + +### diff --git a/device-partner-information.md b/device-partner-information.md new file mode 100644 index 0000000..32ba54b --- /dev/null +++ b/device-partner-information.md @@ -0,0 +1,44 @@ +--- +description: TIP OpenWiFi +--- + +# Device Partner Information + +TIP OpenWiFi enables a turnkey from factory experience for the managed Wi-Fi ecosystem.\ +When an ODM or an OEM join TIP it is for the purpose of supplying a TIP SKU to market direct from factory. + +This has numerous advantages including scale of supply, ease of distribution, partner branding, use of standard software including device certificates direct from factory. + +### Step 1 : Join + +If your organization is not already a TIP Open Converged Wireless Project Group (OCW PG) member, consider signing up. Joining the OCW PG is free as a Software Participation Tier in TIP. + +For more information please visit:[ Becoming a Member](https://telecominfraproject.com/apply-for-membership/) + +### Step 2 : Slack, Keys & Atlassian Tools + +Introduce your organization to the Community on Slack. All Community members have access to Telecom Infra Project Slack. Send a message to "general" and "open-wifi-ucentral" channels. + +Send an email to licensekeys@telecominfraproject.com to request onboarding as a supplier for OpenWiFi SKU devices. + +Ensure your GitHub account was linked in your Telecom Infra Project user profile, this will enable write access to OpenWiFi repositories. Also confirm Atlassian link is also present in user profile. + +### Step 3 : Build your device profile + +Devices follow standard Linux patch process for enhancements and bug fixes. A development branch should be defined, perform work necessary to add support for the new device including a new profile for the build system. + +Test your work locally, when confident push and submit a pull request for the next branch. + +Follow the guidance posted: [Source Code & Repositories](https://telecominfraproject.atlassian.net/wiki/spaces/WIFI/pages/355598358/Source+Code+Repositories) + +### Step 4 : Submit Device for Community Lab Testing + +To obtain access to TIP OpenWiFi support and regression, devices must be sent to the Community Test Lab for QA sanity automation. A formal process for obtaining a TIP OpenWiFi Logo mark will be launched in 2022. + +### Summary + +If the pull request review is successful the new device will be merged. + +Provided the ODM / OEM device vendor has been onboarded for license keys, the device will be included in nightly builds. + + diff --git a/getting-started/README.md b/getting-started/README.md index 13601e6..10634e9 100644 --- a/getting-started/README.md +++ b/getting-started/README.md @@ -1,10 +1,59 @@ +--- +description: TIP OpenWiFi 2.0 +--- + # Getting Started -There are two ways to get started with TIP OpenWiFi. For those interested in 'rolling their own' feel free to continue through the Cloud SDK Installation and related information to configure and consume the open source stack. Note you will need to join the TIP Open Converged Wireless PG for this. +OpenWiFi 2.0 Minimum Viable Product at the end of July, 2021 enables a cloud native and cloud agnostic Software Development Kit (SDK) with management and deployment support for a wide range of Access Point and PoE network switch platforms. -Interested in getting started with a partner? Obtaining a TIP AP directly or via a partner is simple and these partners will help setup cloud trial environment with you. +## Initial release 2.0 SDK includes: -### +* Zero Touch Cloud Discovery +* Firmware Management +* User Interface + * Device List + * Device Reboot + * Device LED Blink + * Device Remote Packet Capture + * Device Configuration + * Device Factory Reset + * Device Remote TTY shell + * Remote Wi-Fi Scan + * Associations + * UE (Wi-Fi Clients) + * Mesh and WDS Clients + * MCS, NSS, RSSI, Channel, SSID, Tx/Rx + * Device Health Check + * Interface Statistics + * Device Command History +Upcoming sprint for August includes Dynamic Provisioning service support for template based device configuration. +OpenWiFi 2.0 SDK is deployable as both a Docker Compose or a Helm on Kubernetes model. See [Release 2.0 SDK](sdk.md) section for installation instructions. + +## New in this Release + +* Firmware + * Basic Features for OpenWiFi Switching + * Passpoint + * NAPTR Functionality + * Proxy Static Routing + * HSP Auth / Acc Service Discovery + * Last Resort Proxy + * RADIUS OpenRoaming Compliance + * External 3rd Party Captive Portal Redirect + * Burst Rate Ad-Hoc Telemetry + * Static Routing + * CS1 Merge - Wi-Fi 6 + * IEEE802.1d STP Control + * Timestamp on Health Check messages + * L2 DHCP Relay + * Station Association Idle and Session time +* SDK + + * OpenWiFi Provisioning Service + * OpenWiFi Inventory Service + * Multi Tenant Support + * Service Group - Venues + * Logical Regions - Entities diff --git a/getting-started/access-points/README.md b/getting-started/access-points/README.md new file mode 100644 index 0000000..6fffd5b --- /dev/null +++ b/getting-started/access-points/README.md @@ -0,0 +1,31 @@ +--- +description: TIP OpenWiFi 2.0 +--- + +# Access Points + +Initial Minimum Viable Product Release 2.0 does not include template driven device provisioning, this will be available in the next sprint. + +Given many cloud and ODM partners wish to consume the 2.0 reference stack early, some with their own device provisioning logic as part of commercial cloud controllers, the following describes uCentral based management and telemetry, interactions with the OpenWiFi SDK processing provisioning and telemetry data. + +## Device Interactions with SDK + +![OpenWiFi with uCentral Management](<../../.gitbook/assets/image (22) (2).png>) + +OpenWiFi 2.0 follows the uCentral system. Complete data model is available [here](http://ucentral.io/docs/ucentral-schema.html). Upon discovery of the cloud, a device default or specific configuration is transferred. + +All devices are known to the cloud by their unique id and provisioned based on advertised capabilities. Each configuration generates a new unique hash value to ensure as devices report back to the cloud, their configuration state is guaranteed. + +If the cloud sends invalid configuration data or the device has insufficient ability to complete the provisioning commands, the error handling process will send this response back to the cloud. + +For example results returned to SDK from a device configuration error: + +``` +"results": { + "serial": "aabbcc00120a", + "status": { + "error": 0, + "rejected": [ + "[W] ("A Reason will be given" + ], +``` diff --git a/getting-started/access-points/local-device-settings.md b/getting-started/access-points/local-device-settings.md new file mode 100644 index 0000000..d112d5d --- /dev/null +++ b/getting-started/access-points/local-device-settings.md @@ -0,0 +1,57 @@ +--- +description: OpenWiFi 2.0 Devices +--- + +# Local Device Settings + +When OpenWiFi devices are unable to connect to the cloud during their initial power on from factory, this may be a result of Internet connectivity issues. + +Certain WAN connections may require credentials such as a username and password or a mobile configuration or simply static address assignment instead of dynamic. + +OpenWiFi 2.0 supports these scenarios. When a device does not have an existing configuration and is unable to contact the cloud for provisioning it enters "Maverick" mode. + +For all Wi-Fi devices this means a Wi-Fi network with the SSID 'Maverick' will become available.\ +Association with and logging in to the device will permit initial WAN connectivity to be entered. + +## Using Maverick + +![Maverick Login Page](<../../.gitbook/assets/Screen Shot 2021-07-29 at 5.04.23 PM.png>) + +After association to the Maverick SSID, open a web browser to `http://192.168.1.1`\ +Log into the OpenWiFi device with username: **`root`** and password: **`openwifi`** + +![Logged into Maverick](<../../.gitbook/assets/Screen Shot 2021-07-29 at 5.06.35 PM.png>) + +When the page above is displayed, begin to configure Uplink based on the WAN requirements of the deployment. + +![Uplink Configuration in Maverick](<../../.gitbook/assets/Screen Shot 2021-07-29 at 5.07.50 PM.png>) + +If connection uses Point to Point over Ethernet (PPPoE) username and password credentials, enter those values and save. + +![PPPoE Uplink](<../../.gitbook/assets/Screen Shot 2021-07-29 at 5.09.14 PM.png>) + +If the OpenWiFi device has a Cellular connection which is possible on device models with 4G and 5G radios, the network Access Point Name (APN) and PIN will be required. These values are supplied by your mobile network provider. + +![Cellular Uplink](<../../.gitbook/assets/Screen Shot 2021-07-29 at 5.11.05 PM.png>) + +When dynamic address allocation is not available, static IP address assignment may be required. IPv4 and IPv6 are supported, enter these values with DNS address and save. + +![Uplink Static IP](<../../.gitbook/assets/Screen Shot 2021-07-29 at 5.12.39 PM.png>) + +Otherwise leave the Uplink configuration to DHCP or cloud defaults. + +![Uplink DHCP](<../../.gitbook/assets/Screen Shot 2021-07-29 at 5.13.40 PM.png>) + +## Manual Redirector and Certificate Upload + +If under rare circumstances it is not possible to discover the OpenWiFi cloud associated with the device or there is a need to replace device certificates, this may be configured in Settings. + +![Local Redirector Setting](<../../.gitbook/assets/Screen Shot 2021-07-29 at 5.16.01 PM.png>) + +## System + +It is possible to reset the device to defaults, or locally update firmware using the commands available from System. + +![System Commands](<../../.gitbook/assets/Screen Shot 2021-07-29 at 5.17.13 PM.png>) + +\*\*\*\* diff --git a/getting-started/cloud-discovery/README.md b/getting-started/cloud-discovery/README.md new file mode 100644 index 0000000..cdf252c --- /dev/null +++ b/getting-started/cloud-discovery/README.md @@ -0,0 +1,23 @@ +--- +description: TIP OpenWiFi 2.0 +--- + +# Cloud Discovery + +All TIP OpenWiFi devices use the same cloud discovery mechanism on initial boot. + +OpenWiFi devices ship from factory with a unique device certificate signed by the Telecom Infra Project Certificate Authority. + +When a device boots for the first time, or is factory reset, a 'first-boot' process occurs within the device.\ +First-boot initiates a connection over HTTPs to the Certificate Authority requesting the unique device record information. All connections to the Certificate Authority occur over mTLS encrypted session.\ +Devices use their unique certificate identity to authenticate and retrieve the location of the assigned cloud. + +![Device First Boot / Factory Cloud Discovery](<../../.gitbook/assets/image (22).png>) + +Once the cloud location has been learned from first-boot, the device no longer depends on this cloud discovery and will return to the assigned cloud learned from first-boot. + +Devices may periodically initiate connection to the Certificate Authority to validate their unique certificate status. This is a normal process involved in mutual TLS security models. + +When an operator or end customer seeks to change the cloud associated with their device(s), the value of the cloud stored in the Certificate Authority device record is updated. A factory reset of the device will cause first-boot to re-occur which will then discover the new cloud. + +TIP OpenWiFi ODM partners are able to manage device records directly using the Certificate Authority portal. All other users should send an email to licensekeys@telecominfraproject.com to request update of cloud discovery. diff --git a/getting-started/cloud-discovery/discovery-without-cloud.md b/getting-started/cloud-discovery/discovery-without-cloud.md new file mode 100644 index 0000000..307c356 --- /dev/null +++ b/getting-started/cloud-discovery/discovery-without-cloud.md @@ -0,0 +1,26 @@ +--- +description: TIP OpenWiFi 2.0 +--- + +# Discovery without Cloud + +There could be reasons cloud discovery does not complete.\ +These include: + +* Lack of Internet Connectivity + * Device may require additional WAN settings + * Network may not be connected to Internet +* No Configuration of Cloud in Certificate Authority + * Manufacturer may have left this value blank in the device record stored in Certificate Authority + +![Manual Cloud Entry](<../../.gitbook/assets/image (23).png>) + +When the cloud can not be automatically discovered, OpenWiFi devices will turn on a local admin web UI made available via SSID "Maverick". + +The Maverick UI will support configuring WAN interface parameters, including DHCP, Static, PPPoE, and LTE/5G settings. Please see [Local Device Settings](../access-points/local-device-settings.md) for details on using Maverick.\ +[ \ +](../access-points/local-device-settings.md)Additionally the Maverick UI supports direct entry of the cloud for cases when the cloud value has not been supplied during manufacture. + +For non-Wi-Fi devices such as PoE access switches, the same cloud location information may be configured using local management interface. + +![Admin / User Entered WAN or Cloud](<../../.gitbook/assets/image (24).png>) diff --git a/getting-started/repositories.md b/getting-started/repositories.md new file mode 100644 index 0000000..de61f6d --- /dev/null +++ b/getting-started/repositories.md @@ -0,0 +1,41 @@ +--- +description: 2.4 Repository Information +--- + +# Repositories + +**Access Point Network OS (APNOS)** + +License: BSD-3-Clause + +* Openwrt based APNOS: [https://github.com/Telecominfraproject/wlan-ap/tree/release/v2.4.0](https://github.com/Telecominfraproject/wlan-ap/tree/release/v2.4.0) + +**Controller SDK** + +License: BSD-3-Clause + +* Gateway Service: [https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/tree/release/v2.4.0](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/tree/release/v2.4.0) +* Gateway UI: [https://github.com/Telecominfraproject/wlan-cloud-ucentralgw-ui/tree/release/v2.4.0](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw-ui/tree/release/v2.4.0) +* Security Service: [https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/tree/release/v2.4.0](https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/tree/release/v2.4.0) +* Firmware Service: [https://github.com/Telecominfraproject/wlan-cloud-ucentralfms/tree/release/v2.4.0](https://github.com/Telecominfraproject/wlan-cloud-ucentralfms/tree/release/v2.4.0) +* Provisioning Service:[https://github.com/Telecominfraproject/wlan-cloud-owprov/tree/main](https://github.com/Telecominfraproject/wlan-cloud-owprov/tree/main) +* Provisioning UI: [https://github.com/Telecominfraproject/wlan-cloud-owprov-ui/tree/main](https://github.com/Telecominfraproject/wlan-cloud-owprov-ui/tree/main) + +**Testing** + +License: BSD-3-Clause + +* Open Test Harness and Test cases: [https://github.com/Telecominfraproject/wlan-testing/tree/master](https://github.com/Telecominfraproject/wlan-testing/tree/master) + +**SDK Load Simulator** + +License: BSD-3-Clause + +* OpenWiFi Load Simulator (OWLS): [https://github.com/Telecominfraproject/wlan-cloud-owls/tree/main](https://github.com/Telecominfraproject/wlan-cloud-owls/tree/main)\ + + +**Deployment** + +License: BSD-3-Clause + +* Helm and Docker Compose Deployments: [https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/tree/release/v2.4.0](https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/tree/release/v2.4.0) diff --git a/getting-started/sdk.md b/getting-started/sdk.md new file mode 100644 index 0000000..c415385 --- /dev/null +++ b/getting-started/sdk.md @@ -0,0 +1,20 @@ +--- +description: TIP OpenWiFi 2.0 +--- + +# Release 2.0 SDK + +Release 2.0 SDK offers a number of ways to consume OpenWiFi. Available as a single Docker for just the uCentralGW or as a set of micro services offering increasing value to consume helps multiple eco-system partners use as much or as little as desired to integrate with or build a commercial product on the TIP OpenWiFi SDK. + +Features of the 2.0 SDK at July MVP include: + +* RBAC based security framework +* OpenAPI compliant Northbound +* Kafka Message Bus +* PGSql HA Cluster +* Firmware Manager +* Central Logging Dashboard +* User Interface +* Docker Compose & Helm DevOps Deployment Automation + +![OpenWiFi 2.0 SDK](<../.gitbook/assets/image (31).png>) diff --git a/monitoring/README.md b/monitoring/README.md new file mode 100644 index 0000000..acdd0f1 --- /dev/null +++ b/monitoring/README.md @@ -0,0 +1,181 @@ +--- +description: OpenWiFi 2.0 Telemetry and Analysis +--- + +# Monitoring + +TIP OpenWiFi software stack is envisioned to have a rich telemetry data that can be extracted, transformed and stored for analytics purposes. This section will outline various integration using the current capabilities of the OpenWiFi release. These integrations will provide examples for the community to enrich, adopt and productize. + +The current release of OpenWiFi utilizes both a rich open API and Kafka for retrieving telemetry information from Access Points and SDK services. For the purpose of this section and Release 2.0 we will be showcasing Kafka integration with third party monitoring subsystems. + +## Kafka Data Source + +The current release of 2.0 SDK architecture contains a Kafka broker for the purposes inter-services communication, state, healthcheck, device provisioning state producing and consuming Kafka topics. You can find the latest information related to Kafka topics here: [https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/KAFKA.md#kafka-integration](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/KAFKA.md#kafka-integration) + +The current Kafka topics used for this monitoring integration are: + +* state +* healthcheck + +All Kafka messages carry a JSON payload, example of a healthcheck message is as follow: + +``` +{ + "system":{ + "id":179033843641952, + "host":"https://gw-ucentral-dev01.cicd.lab.wlan.tip.build:17002" + }, + "payload":{ + "data":{ + "interfaces":{ + "up0v0":{ + "dhcp":false, + "location":"/interfaces/0" + } + }, + "unit":{ + "memory":36 + } + }, + "sanity":67, + "serial":"112233445566", + "uuid":1627357625 + } +} +``` + +A state Kafka message looks like: + +``` +{ + "system":{ + "id":179033843641952, + "host":"https://gw-ucentral-dev01.cicd.lab.wlan.tip.build:17002" + }, + "payload":{ + "serial":"112233445566", + "state":{ + "interfaces":[ + { + "clients":[ + { + "ipv6_addresses":[ + "fe80:0:0:0:206:aeff:fee0:69ad" + ], + "mac":"07:06:06:06:06:06", + "ports":[ + "eth1" + ] + }, + { + "ipv4_addresses":[ + "192.168.4.1" + ], + "mac":"01:02:03:04:05:06", + "ports":[ + "eth1" + ] + } + ], + "counters":{ + "collisions":0, + "multicast":63, + "rx_bytes":14725, + "rx_dropped":0, + "rx_errors":0, + "rx_packets":209, + "tx_bytes":13571, + "tx_dropped":0, + "tx_errors":0, + "tx_packets":80 + }, + "dns_servers":[ + "1.1.1.1", + "9.9.9.9" + ], + "ipv4":{ + "addresses":[ + "192.168.4.33/24" + ], + "leasetime":600 + }, + "location":"/interfaces/0", + "name":"up0v0", + "uptime":31349 + }, + { + "counters":{ + "collisions":0, + "multicast":0, + "rx_bytes":0, + "rx_dropped":0, + "rx_errors":0, + "rx_packets":0, + "tx_bytes":1058, + "tx_dropped":0, + "tx_errors":0, + "tx_packets":5 + }, + "ipv4":{ + "addresses":[ + "192.168.1.1/24" + ] + }, + "location":"/interfaces/1", + "name":"down1v0", + "uptime":31355 + } + ], + "radios":[ + { + "active_ms":24459917, + "busy_ms":1173593, + "channel":149, + "channel_width":"80", + "noise":4294967198, + "phy":"soc/40000000.pci/pci0000:00/0000:00:00.0/0000:01:00.0", + "receive_ms":4647, + "transmit_ms":88272, + "tx_power":30 + }, + { + "active_ms":24456321, + "busy_ms":11878205, + "channel":11, + "channel_width":"20", + "noise":4294967204, + "phy":"platform/soc/a000000.wifi", + "receive_ms":1329, + "transmit_ms":73228, + "tx_power":30 + }, + { + "active_ms":24458178, + "busy_ms":1162312, + "channel":36, + "channel_width":"80", + "noise":4294967192, + "phy":"platform/soc/a800000.wifi", + "receive_ms":12339, + "transmit_ms":86904, + "tx_power":23 + } + ], + "unit":{ + "load":[ + 0.190921, + 0.263188, + 0.240726 + ], + "localtime":1627418941, + "memory":{ + "free":348540928, + "total":520409088 + }, + "uptime":31386 + } + }, + "uuid":1627357625 + } +} +``` diff --git a/monitoring/elk-integration.md b/monitoring/elk-integration.md new file mode 100644 index 0000000..37247f3 --- /dev/null +++ b/monitoring/elk-integration.md @@ -0,0 +1,21 @@ +--- +description: Kafka integration with ELK +--- + +# ELK Integration + +The following pipeline is used to leverage Kafka messages being emitted from OpenWiFi 2.0 for ELK (Elastic Logstash Kibana) stack integration : + +![](../.gitbook/assets/kafka-ELK-pipeline.png) + +TIP OpenWiFi project has deployed an ELK stack for community members to access [here](https://kibana.lab.wlan.tip.build). + +The key for this integration is to use a plugin that enables Kafka to be used as an input for Logstash. This plugin can be found [here](https://www.elastic.co/guide/en/logstash/current/plugins-inputs-kafka.html). Once installed then Logstash can be configured to listen to the input source of the Kafka broker that is deployed as part of OpenWiFi SDK 2.0 release and its appropriate topics. Here is a [sample](https://github.com/Telecominfraproject/wlan-cloud-ucentral-analytics) Logstash configuration. + +It is important to note that Logstash provides the ability to transform messages which then can be pushed to Elasticsearch for storage with effective indexing. Finally Kibana is used to create visualization such as this: + +![](../.gitbook/assets/kibana.png) + +![](../.gitbook/assets/kibana-2.png) + +The following [repository](https://github.com/Telecominfraproject/wlan-cloud-ucentral-analytics) will be used to store necessary files for integration examples for monitoring. diff --git a/ordering-open-wi-fi-aps.md b/ordering-open-wi-fi-aps.md new file mode 100644 index 0000000..df11c2f --- /dev/null +++ b/ordering-open-wi-fi-aps.md @@ -0,0 +1,13 @@ +--- +description: TIP OpenWiFi Member Access Point Ordering Information +--- + +# Ordering OpenWiFi APs + +TIP Wi-Fi members may contact the ODM manufacturers in the TIP OpenWiFi eco-system using the information posted within Community Confluence page. + +{% embed url="https://telecominfraproject.atlassian.net/wiki/spaces/WIFI/pages/112689187/AP+Hardware" %} + +If your organization is not already a TIP Open Converged Wireless Project Group (OCW PG) member, consider signing up. Joining the OCW PG is free as a Software Participation Tier in TIP. + +For more information please visit:[ Becoming a Member](https://telecominfraproject.com/apply-for-membership/) diff --git a/provisioning/README.md b/provisioning/README.md new file mode 100644 index 0000000..17c0164 --- /dev/null +++ b/provisioning/README.md @@ -0,0 +1,37 @@ +--- +description: uCentral Data Model Introduction +--- + +# Provisioning + +OpenWiFi 2.0 makes it possible for integrators of the SDK to implement commercial products leveraging OpenWiFi Gateway service with vendor supplied provisioning above OpenWiFi SDK.\ +As a minimum, the OpenWiFi 2.0 SDK framework offers a Security service which handles all OpenAPI authentication northbound, and the Gateway service which provides all uCentral websocket interface functionality southbound. + +![Minimum 2.0 SDK - Assumes DB is either SQLite or PGSql](<../.gitbook/assets/image (28).png>) + +OpenWiFi also provides options to receive telemetry and events over both OpenAPI interface as well as Kafka message bus. When using Kafka, OpenWiFi Gateway directly publishes telemetry and event topics to the bus. + +In future sprints of OpenWiFi dynamic device provisioning will be available as an added micro service. + +## Gateway + +OpenWiFi 2.0 Gateway implements the uCentral device management interface. uCentral specifies the data model and interface for management and telemetry of OpenWrt based devices.\ +Gateway uCentral interface is a websocket JSON-RPC based design between OpenWiFi Gateway and the device running uCentral agent. + +![Southbound Interface to Devices](<../.gitbook/assets/image (29).png>) + +All communications from Gateway to Device are secured using mutual Transport Layer Security (mTLS). In mTLS systems each endpoint is a unique device sharing the same signed root or intermediate trust. In OpenWiFi each device has a signed certificate, key and device identifier. These are validated by the uCentral-Gateway to establish mTLS session. + +Upon successful connection the device exchanges its capabilities with the OpenWiFi SDK. OpenWIFi SDK, via the Gateway micro service will send the entire device provisioning data as a JSON payload.\ +Within OpenWiFi devices, the uCentral agent has a reader and renderer process providing serialization and validation of data sent from cloud.\ +If any data presented can not be processed by the local agent, this is returned within an ERROR message using the same websocket connection. + +![High Level SDK Gateway to uCentral Agent](<../.gitbook/assets/image (30) (1).png>) + +If the device agrees with provisioning information presented, the render process builds calls into the operating system configuration sub-system known as UCI. The Unified Configuration Interface ensures OpenWrt compliant syntax is persisted within the device. + +Configuration source of truth is the OpenWiFi SDK. Consistency of device configuration is handled with an applied hash compared by the Gateway for each device. If the value differs on device from that of the stored information in cloud, the device will be immediately resent its configuration from the OpenWiFi SDK Gateway service. + +Once present, all configuration data is preserved on device restart. + +It is possible to generate device configurations outside of the OpenWiFi 2.0 SDK as shown in the minimum SDK image at the start of this page. This may occur for some integrations or may occur when the OpenWiFi Provisioning micro service is not present. In this way, integrators of commercial products are welcome to build device provisioning outside of OpenWiFi and use the OpenWiFi cloud to manage the scale, state, security and validation of device websocket communications. diff --git a/provisioning/creating-a-configuration.md b/provisioning/creating-a-configuration.md new file mode 100644 index 0000000..0278055 --- /dev/null +++ b/provisioning/creating-a-configuration.md @@ -0,0 +1,201 @@ +--- +description: OpenWiFi 2.0 Device Configuration +--- + +# Creating a Configuration + +To introduce the Community to the uCentral data model structure, the below illustrates a basic Access Point configuration that assumes a typical enterprise Wi-Fi scenario of a ceiling mount or wall mount device presenting a single WAN interface with a private management network and separate Wi-Fi network on a virtual local area network. + +## Start with Location and Radios + +We will set the unit location and timezone, then proceed to configure radios. + +``` +{ + "uuid": 2, + "unit": { + "location": "TIP Lab Network", + "timezone": "EST+5EDT,M3.2.0/2,M11.1.0/2" + }, + "radios": [ + { + "band": "5G", + "country": "CA", + "channel": "auto", + "channel-mode": "HE", + "channel-width": 80, + "require-mode": "HT", + "rates": { + "beacon": 6000, + "multicast": 24000 + } + }, + { + "band": "2G", + "country": "CA", + "channel": 11, + "channel-mode": "HE", + "channel-width": 80, + "require-mode": "HT", + "rates": { + "beacon": 6000, + "multicast": 24000 + } + } + ], +``` + +In this example, a two radio device that indicates it is Wi-Fi 6 as the channel-mode values for both radios is "HE" which defines 802.11ax operation. Valid values are "HT" -High Throughput 802.11n mode, "VHT" - Very High Throughput 802.11ac mode, "HE" - High Efficiency 802.11ax mode. + +Channel defines the specific channel number the radio shall operate on as an integer from 1 - 171 and may also be set to a string for "auto" mode. Channel width permits configuring the amount of RF channel the radio will operator over from 20-40-80-160 including 8080 mode (also known as 80+80) . + +OpenWiFi radios may be set to require UE clients to associate to a minimum standard such as excluding any 802.11b associations depicted above with "require-mode" set to "HT" meaning 802.11n or higher clients may associate. + +Control of beacon interval and multicast rates is possible per radio as shown in the "rates" section. + +## Interfaces + +OpenWiFi 2.0 offers a highly flexible model for arranging network interfaces. Multi-port devices may be easily provisioned for numerous types of network segmentation and logical network configuration. We will start with a simple WAN that has a management IP and also a VLAN sub-interface for a logical SSID in a subsequent step. + +``` + "interfaces": [ + { + "name": "WAN", + "role": "upstream", + "services": [ "lldp", "dhcp-snooping" ], + "ethernet": [ + { + "select-ports": [ + "WAN*" + ] + } + ], + "ipv4": { + "addressing": "dynamic" + } + }, +``` + +In the above configuration block we have a WAN interface, its role is "upstream" meaning it faces the upstream in terms of service it provides (WAN). This has a direct alignment to how the device interprets a physical or logical port participates in bridge forwarding domains. + +Note we want this port to have an IP address for its management, therefore the "ipv4" configuration is associated as a child of any Ethernet WAN ports and set to DHCP. + +### Common Config - VLAN on WAN for SSID + +Imagine the OpenWiFi device is an enterprise Access Point mounted on a ceiling. These devices do not always have a LAN port. Also in an enterprise, it is likely the Wi-Fi services are in their own network segments and not subject to Network Address Translation (NAT). Since the enterprise would also not want Wi-Fi on the same network as Management, an 802.1Q Virtual LAN is used. + +``` + { + "name": "WAN100", + "role": "upstream", + "services": [ "lldp", "dhcp-snooping" ], + "vlan": { + "id": 100 + }, + "ethernet": [ + { + "select-ports": [ + "WAN*" + ] + } + ], +``` + +In this next section of configuration, an additional logical interface associated to the WAN ports for the VLAN id of "100" is shown. Note there is no IP address associated to this interface, it is a layer 2 interface that will emit on any and all WAN ports with VLAN id 100. + +To associate the Wi-Fi with the VLAN interface define, we continue within the WAN100 interface adding SSID services. + +``` + "ssids": [ + { + "name": "TIP OpenWiFi", + "wifi-bands": [ + "5G", "2G" + ], + "bss-mode": "ap", + "encryption": { + "proto": "psk2", + "key": "OpenWiFi", + "ieee80211w": "optional" + } + }, + "services": [ "wifi-frames"] +``` + +Within the "ssids" configuration block we can process an array of SSIDs. Often there may be separate "2G" and "5G" configurations. We have grouped them in this introductory example for simplicity however "2G", "5G", "5G-lower", "5G-upper", "6G" are all valid options. + +The "name" value is the advertised SSID clients will discover for this access point. Hidden is supported by setting the "hidden-ssid" to true.\ +Which operating mode is determined by "bss-mode". The "bss-mode" is a highly flexible operating parameter to determine "ap", "sta", mesh", "wds-ap", "wds-sta", "wds-repeater" radio modes of operation. + +Security of the SSID is determined using the "encryption" section. Many options are possible, in this initial example, a WPA-PSK2 shared key encryption is shown.\ +Lastly, for devices that support, 802.11w protected management frames are defined as optional for this SSID. This may also be disabled or required. + +Metrics for wifi-frames will be described next. + +### Sending Data + +Add metrics to our configuration that will help expose state of the Wi-Fi network and its services to the cloud. + +``` + "metrics": { + "statistics": { + "interval": 120, + "types": [ "ssids", "lldp", "clients" ] + }, + "health": { + "interval": 120 + }, + "wifi-frames": { + "filters": [ "probe", + "auth", + "assoc", + "disassoc", + "deauth", + "local-deauth", + "inactive-deauth", + "key-mismatch", + "beacon-report", + "radar-detected"] + }, + "dhcp-snooping": { + "filters": [ "ack", + "discover", + "offer", + "request", + "solicit", + "reply", + "renew" ] + } + }, +``` + +Within metrics it is possible to define the interval for sending information to the cloud. Additionally the type of information sent is defined here. In this example configuration there are associated services to interfaces along the way. This included LLDP and dhcp-snooping and wifi-frames. + +Within each uCentral device, the agent has a global health check feature that includes memory, cpu, temperature operating states in addition to performing various network and service health tests. The interval at which these reports are sent to the cloud is configured within health. + +For all SSIDs that have wifi-frames associated as a service, the listed management frame types will be gathered and sent to the cloud, on each interval. + +To assist with fingerprinting and client troubleshooting, dhcp-snooping sends the cloud all current client DHCP and DHCPv6 state. + +### Global Services + +The final section of the simple configuration example turns on LLDP and SSH where those services were associated to interfaces listed above. + +``` + "services": { + "lldp": { + "describe": "TIP OpenWiFi", + "location": "LivingLab" + }, + "ssh": { + "port": 22 + } + } +} +``` + +The complete simple configuration file as described in this page may be downloaded here: + +{% file src="../.gitbook/assets/SimpleConfig_OpenWiFidocs.json" %} +SimpleConfig\_Wi-Fi\_VLAN +{% endfile %} diff --git a/provisioning/data-model-introduction.md b/provisioning/data-model-introduction.md new file mode 100644 index 0000000..3eb207d --- /dev/null +++ b/provisioning/data-model-introduction.md @@ -0,0 +1,30 @@ +--- +description: OpenWiFi 2.0 +--- + +# Data Model Introduction + +OpenWiFi 2.0 data model for device management is based on uCentral. + +uCentral is set to become a leading component of OpenWrt, as such will have a diverse, and worldwide developer and support base in open source. + +Within the model it is possible to provision or return state for all aspects of an OpenWiFi based device easily structured as a JSON payload. + +The complete data model may be found here : [https://ucentral.io/docs/ucentral-schema.html](https://ucentral.io/docs/ucentral-schema.html) + +## Organization + +Each device has a Universally Unique Identifier (UUID). For each device, the configuration presented either manually, via the future Provisioning service from OpenWifi or via a commercial controller generation of provisioning data, the high level relationships of the schema may be understood as follows. + +![uCentral Agent Schema Processing](<../.gitbook/assets/image (32).png>) + +The unique device record has a set of top level configurations. A device is referred to as a 'unit' that may have a Description, Location, TimeZone as example. Each unit may have globals for IPv4 and IPv6 networks that are derived to lower lever interfaces in later generation. + +Services and Metrics are associated with logical and physical interfaces. Services enable configuration of features such as LLDP or SSH, rTTY, IGMP, 802.1x, RADIUS Proxy, WiFi-Steering, or NTP and are then associated with Interfaces as desired. + +Interfaces define upstream and downstream configuration over both Wi-Fi logical (SSID) and wired physical ports. + +Metrics enable visibility to the cloud for numerous states of the device. These are associated per interface and may be sent in 60 second or greater intervals and include Statistics of SSID, LLDP, Clients. Also include Health check reports of device load, network reachability, temperature.\ +To assist with fingerprinting DHCP-Snooping exposes numerous interactions of IP binding to clients. Additionally wifi-frames expose all 802.11 management frames to the SDK Gateway. + +It is also possible to configure config-raw elements that will parse direct UCI commands once the device provisioning has been completed by the uCentral agent. diff --git a/release-notes/features.md b/release-notes/features.md new file mode 100644 index 0000000..3a250ba --- /dev/null +++ b/release-notes/features.md @@ -0,0 +1,75 @@ +# Features + +**Epic** + +[WIFI-5726](https://telecominfraproject.atlassian.net/browse/WIFI-5726) Security fixes for 2.4 + +#### Improvement + +[WIFI-5998](https://telecominfraproject.atlassian.net/browse/WIFI-5998) Detect if an invalid channel is requested on 5G 40/80MHz + +[WIFI-5997](https://telecominfraproject.atlassian.net/browse/WIFI-5997) Make it possible to flash r2.4 on eap102 with older bootloaders + +[WIFI-5823](https://telecominfraproject.atlassian.net/browse/WIFI-5823) MU-MIMO setting need to be fine tuned + +[WIFI-5728](https://telecominfraproject.atlassian.net/browse/WIFI-5728) APNOS CSu1 Update + +[WIFI-5439](https://telecominfraproject.atlassian.net/browse/WIFI-5439) Enhance Maverick Stage - TIming + +[WIFI-4934](https://telecominfraproject.atlassian.net/browse/WIFI-4934) Coova Based External Captive Portal support in Bridge Mode + +[WIFI-3760](https://telecominfraproject.atlassian.net/browse/WIFI-3760) Last Resort Proxy Routing + +[WIFI-3758](https://telecominfraproject.atlassian.net/browse/WIFI-3758) Proxy Static Routing Test Functionality + +[WIFI-3628](https://telecominfraproject.atlassian.net/browse/WIFI-3628) Document ZTM Onboarding + +[WIFI-2675](https://telecominfraproject.atlassian.net/browse/WIFI-2675) QoS management + +[WIFI-1793](https://telecominfraproject.atlassian.net/browse/WIFI-1793) Scale 5,000 - 20,000 per OpenWiFi 2.0 Cloud Service - Stand alone + +[WIFI-1792](https://telecominfraproject.atlassian.net/browse/WIFI-1792) Extend OWLS to uCentral Device Types + +#### New Feature + +[WIFI-5797](https://telecominfraproject.atlassian.net/browse/WIFI-5797) Add support for HFCL ion4x wifi-6 (in/outdoor) SKU + +[WIFI-5723](https://telecominfraproject.atlassian.net/browse/WIFI-5723) Add DFS channel list to capabilities + +[WIFI-5703](https://telecominfraproject.atlassian.net/browse/WIFI-5703) Add ATF scheduler + +[WIFI-4888](https://telecominfraproject.atlassian.net/browse/WIFI-4888) Wispr AVPs for Dynamic Subscriber QoS - Traffic Shaping + +[WIFI-3322](https://telecominfraproject.atlassian.net/browse/WIFI-3322) ATF Dynamic Fair Queue + +[WIFI-2064](https://telecominfraproject.atlassian.net/browse/WIFI-2064) Implementation of Social Wi-Fi + +[WIFI-368](https://telecominfraproject.atlassian.net/browse/WIFI-368) OCI Container Support in AP NOS - Testing + +#### Sub-task + +[WIFI-5724](https://telecominfraproject.atlassian.net/browse/WIFI-5724) IP rate limit for sensitive endpoints + +[WIFI-2852](https://telecominfraproject.atlassian.net/browse/WIFI-2852) Documentation PPPoE OpenWiFi 2.0 + +#### Task + +[WIFI-5772](https://telecominfraproject.atlassian.net/browse/WIFI-5772) Hardcoded RTTY access configuration \[ucentral-deploy] + +[WIFI-5767](https://telecominfraproject.atlassian.net/browse/WIFI-5767) Add support for CIG WF196 Wifi6E PCBA + +[WIFI-5727](https://telecominfraproject.atlassian.net/browse/WIFI-5727) Update UUIDGenerator to UUIDv4 \[ucentral-gw] + +[WIFI-5619](https://telecominfraproject.atlassian.net/browse/WIFI-5619) Exposed certificate absolute paths \[ucentral-gw] + +[WIFI-5618](https://telecominfraproject.atlassian.net/browse/WIFI-5618) Exposed server version \[deployment] + +[WIFI-5617](https://telecominfraproject.atlassian.net/browse/WIFI-5617) Exposed password hashes \[ucentral-sec] + +[WIFI-5616](https://telecominfraproject.atlassian.net/browse/WIFI-5616) Improper default username & password handling \[ucentral-sec] + +[WIFI-5615](https://telecominfraproject.atlassian.net/browse/WIFI-5615) Unsalted hash \[ucentral-sec] + +[WIFI-3585](https://telecominfraproject.atlassian.net/browse/WIFI-3585) Action links should be temporary and randomly generated \[ucentral-sec] + +[WIFI-3487](https://telecominfraproject.atlassian.net/browse/WIFI-3487) CIG - ath11k BDF files diff --git a/release-notes/resolved-issues.md b/release-notes/resolved-issues.md new file mode 100644 index 0000000..b13ef2b --- /dev/null +++ b/release-notes/resolved-issues.md @@ -0,0 +1,68 @@ +# Resolved Issues + +[WIFI-6014](https://telecominfraproject.atlassian.net/browse/WIFI-6014) Gateway will accept any simulator input + +[WIFI-6013](https://telecominfraproject.atlassian.net/browse/WIFI-6013) CIG\_194C AP is going in out of RAM State and getting crashed when connecting 128 stations + +[WIFI-5981](https://telecominfraproject.atlassian.net/browse/WIFI-5981) GW accepts commands for unknown devices. + +[WIFI-5965](https://telecominfraproject.atlassian.net/browse/WIFI-5965) UI: A device with connected status on SDK central instance can not connect to console. + +[WIFI-5841](https://telecominfraproject.atlassian.net/browse/WIFI-5841) Country\_Code\_SOUTH\_AFRICA: Client connectivity fails for channels under U-NII-2C 5GHz band (20/40/80Mhz) (build-next-d58d87a) + +[WIFI-5834](https://telecominfraproject.atlassian.net/browse/WIFI-5834) UI: mismatch serial AP: post upgrade now has another new MAC address. Old entry still stay on UI + +[WIFI-5828](https://telecominfraproject.atlassian.net/browse/WIFI-5828) MU-MIMO is not working EAP-102 + +[WIFI-5826](https://telecominfraproject.atlassian.net/browse/WIFI-5826) webui: Dashboard not displaying accurate associations on several places plus suggested UI issues combined + +[WIFI-5825](https://telecominfraproject.atlassian.net/browse/WIFI-5825) AP194C: post upgrade connected to SDK but has a mismatch serial warning /changed mac + +[WIFI-5795](https://telecominfraproject.atlassian.net/browse/WIFI-5795) REGDM is outdated inside qca/ax BDF files + +[WIFI-5794](https://telecominfraproject.atlassian.net/browse/WIFI-5794) hfcl\_ion4 CI device type is wrong + +[WIFI-5785](https://telecominfraproject.atlassian.net/browse/WIFI-5785) TPlink ex227/447 are using the wrong memory profile + +[WIFI-5782](https://telecominfraproject.atlassian.net/browse/WIFI-5782) DFS: CAC start is failing on channel 52 on EAP102 using latest image.:TIP-devel-0e0f8c6 + +[WIFI-5780](https://telecominfraproject.atlassian.net/browse/WIFI-5780) UI:command history does not auto populate in TIP-devel-0e0f8c6 ( compared to 2.3) + +[WIFI-5779](https://telecominfraproject.atlassian.net/browse/WIFI-5779) EAP101 AP - UI feature- Showing as Mismatch serial + +[WIFI-5732](https://telecominfraproject.atlassian.net/browse/WIFI-5732) hostapd: add script foo for multiple\_bssid/ema + +[WIFI-5701](https://telecominfraproject.atlassian.net/browse/WIFI-5701) rate-limiting only works on 2.4GHz + +[WIFI-5625](https://telecominfraproject.atlassian.net/browse/WIFI-5625) Wi-Fi Scan breaks 5GHz 11ax 80MHz and 40MHz operation + +[WIFI-5535](https://telecominfraproject.atlassian.net/browse/WIFI-5535) Interop(Manual)captive portal:5GHz: Verify that internet access after getting successful splash page on WPA authentication-iOS--Error While Joining the SSID + +[WIFI-5444](https://telecominfraproject.atlassian.net/browse/WIFI-5444) Interop:Mobiles are not showing 5g ssid after getting Successfully pushed by AP + +[WIFI-5423](https://telecominfraproject.atlassian.net/browse/WIFI-5423) WiFi Frames in Telemetry Non Functional + +[WIFI-5415](https://telecominfraproject.atlassian.net/browse/WIFI-5415) Docker Compose Self-Signed Non-LB Not Deploy Functional + +[WIFI-5414](https://telecominfraproject.atlassian.net/browse/WIFI-5414) Interop: Iphone is not getting connected for 5g wpa2\_enterprise ssid + +[WIFI-5404](https://telecominfraproject.atlassian.net/browse/WIFI-5404) Interop: phones unable to select enterprise ssids in iOS + +[WIFI-5389](https://telecominfraproject.atlassian.net/browse/WIFI-5389) Hitting Invalid Response Code from Gateway when executing /configure + +[WIFI-5292](https://telecominfraproject.atlassian.net/browse/WIFI-5292) Viasat - XWF Wired Client Not getting IP/rediret + +[WIFI-4913](https://telecominfraproject.atlassian.net/browse/WIFI-4913) Test Failiure due to not showing WPA Enterprise VLAN 5g SSID's on the mobiles + +[WIFI-4387](https://telecominfraproject.atlassian.net/browse/WIFI-4387) AP in disconnected state in the UI + +[WIFI-4267](https://telecominfraproject.atlassian.net/browse/WIFI-4267) Radio down for 2G ssid + +[WIFI-3967](https://telecominfraproject.atlassian.net/browse/WIFI-3967) Interface names and MAC address not stable on CIG-194C and EX-447 on uCentral load + +[WIFI-3721](https://telecominfraproject.atlassian.net/browse/WIFI-3721) WIFI6 AP's - 2G radio is getting down, during test execution + +[WIFI-3701](https://telecominfraproject.atlassian.net/browse/WIFI-3701) Captive Portal : Captive portal is not working on WF188n (basic 5) + +[WIFI-3413](https://telecominfraproject.atlassian.net/browse/WIFI-3413) Why does interop test summary banner show up on non-interop marker runs + diff --git a/release-notes/security.md b/release-notes/security.md new file mode 100644 index 0000000..24a2103 --- /dev/null +++ b/release-notes/security.md @@ -0,0 +1,23 @@ +# Security + +The following list of major security enhancements have been implemented within the 2.4 release: + + + +| **Issue** | **Description** | **Resolution** | +| ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------ | +| [WIFI-3585](https://telecominfraproject.atlassian.net/browse/WIFI-3585) | Password reset and email verification procedures can be exploited by an adversary that acquired a user ID | Hardened action link generation with UUIDs | +| [WIFI-6011](https://telecominfraproject.atlassian.net/browse/WIFI-6011) | Cloud services do not log sensitive events occurred during runtime | Implemented security logs to collect evidence that can help with incident investigation | +| [WIFI-5615](https://telecominfraproject.atlassian.net/browse/WIFI-5615) | Weak password hash computation is vulnerable to rainbow table attacks | Hardened password hash computation with salting | +| [WIFI-5616](https://telecominfraproject.atlassian.net/browse/WIFI-5616) | Hardcoded default password is vulnerable to password guessing attacks | Implemented password change procedure on first login and replaced hardcoded password with a hash | +| [WIFI-5617](https://telecominfraproject.atlassian.net/browse/WIFI-5617) | Some API responses leak user secrets by revealing password hashes | Removed password hashes from API responses | +| [WIFI-5618](https://telecominfraproject.atlassian.net/browse/WIFI-5618) | Some API responses reveal server version which can be leveraged by an adversary to compromise it using exploits | Removed server version from API responses | +| [WIFI-5619](https://telecominfraproject.atlassian.net/browse/WIFI-5619) | API ‘system’ command leak internal file tree by revealing absolute paths of certificate files | Replaced absolute paths of certificates with file names | +| [WIFI-5724](https://telecominfraproject.atlassian.net/browse/WIFI-5724) | Cloud services are vulnerable to black box exploitation attempts, brute forcing, credential stuffing and DDoS | Implemented IP-based rate limit for API endpoints | +| [WIFI-5727](https://telecominfraproject.atlassian.net/browse/WIFI-5727) | Weak UUID generation with reduced entropy | Hardened UUID by increasing entropy | +| [WIFI-5772](https://telecominfraproject.atlassian.net/browse/WIFI-5772?src=confmacro) | RTTY-enabled APs can be overtaken by an adversary accessing RTTYS dedicated management interface using default hardcoded credentials | Hardened RTTYS access by randomizing default credentials at deployment | + +### Known security issues + +* [WIFI-5770](https://telecominfraproject.atlassian.net/browse/WIFI-5770) - RTTYS version used has security flaws which are to be resolved in next releases + diff --git a/sdk-installation/deploy-using-docker-compose.md b/sdk-installation/deploy-using-docker-compose.md new file mode 100644 index 0000000..b1329b2 --- /dev/null +++ b/sdk-installation/deploy-using-docker-compose.md @@ -0,0 +1,142 @@ +--- +description: TIP OpenWiFi 2.0 SDK +--- + +# Deploy using Docker Compose + +The docker-compose [directory](https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/tree/release/v2.4.0/docker-compose) within the deploy repository contains all the relevant files for various modes of SDK. + +### Modes + +The following two modes are currently supported by docker-compose: + +* **Deployments without a Load Balancer** + + This model contains single instances of SDK micro-services. Non-Load Balancer is suitable for scenarios where load given number of APs is below 10,000 or design for network availability is not required. \ + \ + A single local docker-compose deployment performance is listed [here](broken-reference). Additionally this deployment includes options to use either self-signed certificates or user provided certificates: + + * [Non-LB deployment with self-signed certificates](https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/tree/release/v2.4.0/docker-compose#non-lb-deployment-with-self-signed-certificates) + * [Non-LB deployment with own certificates](https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/tree/release/v2.4.0/docker-compose#non-lb-deployment-with-own-certificates)\ + +* **Deployments with a Load Balancer** + + This model is suitable for deployments where there is a need to scale performance and/or use Letsencrypt certificates for northbound service interactions. \ + \ + This deployment allows the user to scale up number of instances of micro-services to handle a larger load than listed [here](broken-reference). \ + \ + The repository contains the instructions here: + + * [LB deployment with self-signed certificates](https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/tree/release/v2.4.0/docker-compose#lb-deployment-with-self-signed-certificates) + * [LB deployment with Letsencrypt certificates](https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/tree/release/v2.4.0/docker-compose#lb-deployment-with-letsencrypt-certificates) + + The docker-compose yaml files are related as follows to the modes above: + +* docker-compose.yml : manages Non-LB deployment with self-signed and own certificates +* docker-compose.lb.selfsigned.yml: manages LB deployment with self-signed certificates +* docker-compose.lb.letsencrypt.yml: manages LB deployment with Letencrypt certificates + +### Docker Compose Environment Variables + +The deployments are managed using different environment files for docker-compose: + +* .env : used for non LB deployments with either self-signed or own certificate deployments executed by docker-compose. For additional information please read [this](https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/tree/main/docker-compose#non-lb-deployment-with-self-signed-certificates). +* .env.selfsigned: used for LB with self-signed deployments executed by alias docker-compose-lb-selfsigned. For additional information please read [this](https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/tree/main/docker-compose#lb-deployment-with-self-signed-certificates). +* .env.letsencrypt: used for LB with letsencrypt deployments executed by alias docker-compose-lb-letsencrypt. For additional information please read [this](https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/tree/main/docker-compose#lb-deployment-with-letsencrypt-certificates). + +### Volumes + +The deployment creates local volumes to persist mostly application and database data. In addition to that several bind mounts are created: + +`docker-compose/certs/` directory used by multiple services + +`docker-compose/{microservice}_data/` directory used by each service for configuration and data. Where {microservice} is one of: owgw, owsec, owfms and owprov. + +{% hint style="info" %} +Be aware that the deployment uses bind mounts on the host to mount certificate and configuration data for the micro services and therefore these files and directories will be owned by the user in the container.\ +Since the files are under version control, you may have to change the ownership to your user again before pulling changes. +{% endhint %} + +### Configuration Variables + +Localizing the installation to the production environment is done through configuration information environment files per microservice. These files are: owgw.env, owgw-ui.env, owsec.env, owfms.env, owprov.env and owprov-ui.env. \ +\ +These env files are used to generate runtime configuration (properties) file when no configuration is found in their respective {microservices}-data directory. + +### Ports + +Exposed port dependencies by application are listed below: + +`127.0.0.1:80/443 tcp` - OpenWiFi-uCentralGW-UI\ +`127.0.0.1:8080/8443 tcp` - OpenWiFi-Provisoning-UI\ +`127.0.0.1:5912/tcp` - rttys dev\ +`127.0.0.1:5913/tcp` - rttys user\ +`0.0.0.0:15002/tcp` - OpenWiFi-uCentralGW websocket\ +`127.0.0.1:16002/tcp` - OpenWiFi-uCentralGW REST API public\ +`0.0.0.0:16003/tcp` - OpenWiFi-uCentralGW fileupload\ +`127.0.0.1:16102/tcp` - OpenWiFi-uCentralGW alivecheck\ +`127.0.0.1:16001/tcp` - OpenWiFi-uCentralSec REST API public\ +`127.0.0.1:16101/tcp` - OpenWiFi-uCentralSec alivecheck + +{% hint style="info" %} +By default only the websocket and fileupload component of the OpenWiFi uCentralGW (Gateway) micro service are exposed on all interfaces. All other exposed services listen on localhost. You can change that according to your needs in the `ports` sections of`docker-compose/docker-compose.yml`. +{% endhint %} + +### Default Certificates + +When cloning the repository, by default the southbound websocket certificate signed by TIP Root CA is provided for the \*.wlan.local domain. Additionally a self-signed certificate for the northbound REST API is present. These enable creating a local deployment out of the box. Production deployments will replace both the southbound websocket and northbound API certificates. + +The supplied certificates are valid for the `*.wlan.local` domain. + +## How to + +1. First you'll have to [install Docker Compose](https://docs.docker.com/compose/install/) according to your platform specific instructions. After that clone the repository with `git clone https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy`. +2. The Docker Compose uCentral micro service configs use `openwifi.wlan.local` as a hostname, so make sure you add an entry in your hosts file (or in your local DNS solution) which points to `127.0.0.1` or the IP of the host running the SDK. +3. Switch to the Compose project directory with `cd docker-compose/`. +4. Default user is: tip@ucentral.com and password is: openwifi + 1. Service enforces a password change on first login +5. Initialize the deployment with `docker-compose up -d`. If your deployment was successfully created, you should see the following output with `docker-compose ps`: + +``` + Name Command State Ports +--------------------------------------------------------------------------------------------------------------------------------------------------------------------- +openwifi_kafka_1 /opt/bitnami/scripts/kafka ... Up 9092/tcp +openwifi_owfms_1 /docker-entrypoint.sh /ope ... Up 0.0.0.0:16004->16004/tcp,:::16004->16004/tcp, 0.0.0.0:16104->16104/tcp,:::16104->16104/tcp, 17004/tcp +openwifi_owgw-ui_1 /docker-entrypoint.sh ngin ... Up 0.0.0.0:443->443/tcp,:::443->443/tcp, 0.0.0.0:80->80/tcp,:::80->80/tcp +openwifi_owgw_1 /docker-entrypoint.sh /ope ... Up 0.0.0.0:15002->15002/tcp,:::15002->15002/tcp, 0.0.0.0:16002->16002/tcp,:::16002->16002/tcp, + 0.0.0.0:16003->16003/tcp,:::16003->16003/tcp, 0.0.0.0:16102->16102/tcp,:::16102->16102/tcp, 17002/tcp +openwifi_owprov-ui_1 /docker-entrypoint.sh ngin ... Up 80/tcp, 0.0.0.0:8080->8080/tcp,:::8080->8080/tcp, 0.0.0.0:8443->8443/tcp,:::8443->8443/tcp +openwifi_owprov_1 /docker-entrypoint.sh /ope ... Up 0.0.0.0:16005->16005/tcp,:::16005->16005/tcp, 0.0.0.0:16105->16105/tcp,:::16105->16105/tcp, 17005/tcp +openwifi_owsec_1 /docker-entrypoint.sh /ope ... Up 0.0.0.0:16001->16001/tcp,:::16001->16001/tcp, 0.0.0.0:16101->16101/tcp,:::16101->16101/tcp, 17001/tcp +openwifi_rttys_1 /rttys/rttys Up 0.0.0.0:5912->5912/tcp,:::5912->5912/tcp, 0.0.0.0:5913->5913/tcp,:::5913->5913/tcp +``` + +1. When the certificate for the REST API and other components is self-signed, accepting trust for the self-signed REST API certificate on your local machine is required. \ + \ + Add `certs/restapi-ca.pem` to your trusted browser certificates or add certificate exceptions in your browser by visiting each of the following URLs (one per port) : \ + `https://openwifi.wlan.local:16001 and ports :16002 :16003 :16004 and :16005` \ + \ + Using the browser, accept the self-signed SSL certificate warnings (make sure to visit both and add the exceptions). +2. Connect to your AP via SSH and add a static hosts entry in `/etc/hosts` for `openwifi.wlan.local` which points to the address of the host the SDK deployment runs on. +3. While staying in the SSH session, copy the content of `certs/restapi-ca.pem` on your local machine to your clipboard and append it to the file `/etc/ssl/cert.pem` on the AP. This way your AP will also trust the self-signed certificate. \ + This step is necessary for rtty features and only required when using self-signed test deployment. +4. Navigate in a web browser to `https://openwifi.wlan.local` to access the UI and login with default username and password. You will now be prompted to change this default password to something more secured. + +![ +](<../.gitbook/assets/Screen Shot 2021-12-08 at 2.14.02 PM.png>) + +1. To use the curl test scripts which are included in the micro service repositories make sure to set the following environment variables before issuing a request: + +``` +export UCENTRALSEC="openwifi.wlan.local:16001" +export FLAGS="-s --cacert /docker-compose/certs/restapi-ca.pem" +``` + +### Upgrading Compose Deployments + +Stop the running containers with `docker-compose down` + +Check out the new branch by repeating _Step 1_ from _How to_ above for the given release and `docker-compose up -d`. + +Don’t forget to re-add the self-signed certificates to the containers with the provided script.\ +Also be aware that you may have to change back some file permissions. To obtain the most recent changes as the files are under version control, you may have to change the ownership to your user again before pulling changes. diff --git a/sdk-installation/deploy-using-helm.md b/sdk-installation/deploy-using-helm.md new file mode 100644 index 0000000..8b2224d --- /dev/null +++ b/sdk-installation/deploy-using-helm.md @@ -0,0 +1,60 @@ +--- +description: TIP OpenWiFi 2.0 SDK +--- + +# Deploy using Helm + +SDK can be deployed to Kubernetes using a Helm package. The Helm package code is located at [https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/](https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/) repository. + +Each micro service in the OpenWiFi SDK system has its own Helm chart that is managed in the micro service’s own repository. The assembly chart collects all the relevant micro service charts and other external dependencies like kafka, rtty, etc. and deploys them together as one cohesive release. + +You can review the full list of all the assembled micro services and related dependencies here: [https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/blob/main/chart/Chart.yaml#L6](https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/blob/main/chart/Chart.yaml#L6) + +## Installation + +There are multiple ways you can install OpenWiFi SDK with assembly charts: + +1. One way is by installing directly from the assembly chart’s repository. For that, you’ll need to install and extra Helm plugin that is used to pull the latest charts code from all the referenced micro services: [https://github.com/aslafy-z/helm-git](https://github.com/aslafy-z/helm-git). +2. Another way, which is considered more stable, is by installing from a prepackaged bundle that is published to [https://tip.jfrog.io/ui/native/tip-wlan-cloud-ucentral-helm/](https://tip.jfrog.io/ui/native/tip-wlan-cloud-ucentral-helm/) on every official uCentral release. For this approach to work, you don’t need to install any additional plugins or dependencies, just to make sure you’ve got Helm installed on your local system. + +### Directly from the Assembly repository + +1. Install the helm-git pluging according to the official documentation +2. Run helm upgrade --install tip-ucentral git+[https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/@chart?ref=main](https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/@chart?ref=main) +3. You can also reference any other open branch from the deployment repository. For example, if you want to deploy using the assembly code from the v2.0.0-rc1 branch, you can just run helm upgrade --install tip-ucentral git+[https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/@chart?ref=v2.0.0-rc1](https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/@chart?ref=v2.0.0-rc1) + +### Using the pre-built Helm package + +1. This method doesn’t require to install anything locally other than Helm +2. Start by adding the wlan-cloud-ucentral Helm repository to your local list of repositories by running helm repo add tip-ucentral [https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/](https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/) +3. helm upgrade --install tip-ucentral wlan-cloud-ucentral to install the latest version, or specify the release you want to install by adding the --version x.y.z flag. + +## Chart configuration using the Values file + +The configuration of OpenWiFi SDK using Helm chart may be separated into layers: + +1. Micro services default values - values files that are stored in micro service helm charts (i.e. [https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/helm/values.yaml](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/helm/values.yaml) ). These values are used by default if no other parameters are supplied, so in case you have any microservice-related variables that need to be added in default installation (for example new application configuration properties), add them in the related helm chart values as they will be applied in next release update. +2. Assembly chart values - values that are stored in the assembly repository ([https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/blob/main/chart/values.yaml](https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/blob/main/chart/values.yaml) ) – these are values that override default micro services values so that all uCentral components could connect to each other correctly, and the whole system can be installed as one bundle. These parameters are environment specific, and can differ between and installation of the bundle on an EKS cluster or a MicroK8s local setup. +3. Helm upgrade/install flag overwrites - these values cam be specific for each specific helm install command during execution and usually contain installation-specific values like TLS certificates, security credentials, loadbalancer configuration parameters and so on. These may be passed using --set flag or --values flag (details may be found in [https://helm.sh/docs/chart\_best\_practices/values/](https://helm.sh/docs/chart\_best\_practices/values/) and in micro services helm charts), or you can also save them into one file and reference this file during the helm upgrade command using the --values flag. + +During deployment all values are merged as maps with priority to the level of deployment (so Environment-specific values will override any overrides from Assembly chart values and so on). + +**Example**: Let’s pass environment-specific ucentralgw.properties configuration parameter (which is probably quite common thing to test). For example, we have an environment that requires to set parameter ucentral.websocket.host.0.backlog to 1000. For that we would need to run following command, extending our base command: + +``` +helm upgrade --install tip-ucentral git+https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/@chart?ref=main --set ucentralgw.configProperties."ucentral\.websocket\.host\.0\.backlog"=1000 +``` + +## Automated community deployment + +OpenWiFi SDK can also be deployed to an AWS labs environment using a Github actions workflow: [https://github.com/Telecominfraproject/wlan-testing/actions/workflows/ucentralgw-deployment.yaml](https://github.com/Telecominfraproject/wlan-testing/actions/workflows/ucentralgw-deployment.yaml). + +The configuration is dynamic, and new namespaces (a.k.a environments) may be created by adjusting the json configuration in the workflow. + +The json format allows to deploy or upgrade and existing environment using the latest Docker images or to specify a specific version of each micro service. + +To deploy specific version to the specific environment a list of things must be done: + +1. First, you need to make sure that the Docker image with the correct version exists in Artifactory, otherwise, the Helm upgrade will fail. +2. Update the json configuration in the workflow to reference the require version for the require micro service (examples are attached in the json file itself) +3. Re-run the deployment in Github actions. You can also make all the above changes in a separate branch, and re-run the workflow from that branch (using a drop-down in the top left corner in Github’s UI). diff --git a/sdk-installation/overview.md b/sdk-installation/overview.md new file mode 100644 index 0000000..a74cd0b --- /dev/null +++ b/sdk-installation/overview.md @@ -0,0 +1,12 @@ +# Overview + +The [wlan-cloud-ucentral-deploy](https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy) repository contains two packaging options: + +* [Docker Compose](deploy-using-docker-compose.md) +* [Helm](deploy-using-helm.md) + +The repository is managed using branches where: + +* main branch: contains references to the latest development SDK images +* release/v\* branch: contains image references specific to the release artifacts. For example: release/v2.4.0 branch will contain references to SDK images related to 2.4.0 release candidates (RC) and GA. + diff --git a/test-automation-framework/overview.md b/test-automation-framework/overview.md new file mode 100644 index 0000000..476060d --- /dev/null +++ b/test-automation-framework/overview.md @@ -0,0 +1,2 @@ +# Overview + diff --git a/user-interface/README.md b/user-interface/README.md index 04f6e28..7129196 100644 --- a/user-interface/README.md +++ b/user-interface/README.md @@ -1,25 +1,65 @@ --- -description: TIP Cloud SDK +description: OpenWiFi 2.0 --- # User Interface -## Navigating the UI +Release 2.0 uses a Single-Page Application (SPA) as an example user interface built using React to demonstrate several interactions using the northbound OpenAPI. -TIP open source SDK offers a web based user interface supporting many common configurations. The web based interface uses the SDK north bound API. +## Login to OpenWiFi SDK -It is possible to further extend functionality of the SDK user interface or to create other interfaces using the SDK API. +![Login Page](<../.gitbook/assets/Screen Shot 2021-07-28 at 4.40.17 PM.png>) -### Log In +Default username is: **`tip@ucentral.com`** and password is: **`openwifi`** -Default user account is `support@example.com` with password `support`. +## **Base Navigation** -If using the self-signed certificates provided in the open source distribution, it will be necessary to add an exception to the web browser for the following URLs: +A left side navigation menu provides direction to major feature or service settings. -* [https://wlan-ui.wlan.local/login](https://wlan-ui.wlan.local/login) -* [https://wlan-ui-graphql.wlan.local/](https://wlan-ui.wlan.local/login) +![Left Navigation](<../.gitbook/assets/Screen Shot 2021-07-29 at 3.21.37 PM.png>) -Further instructions available [here](../getting-started/controller.md). +## Internationalization -![TIP SDK Login Screen](../.gitbook/assets/screen-shot-2021-03-28-at-12.50.28-pm.png) +OpenWiFi 2.0 SDK supports multiple languages. Simply select the desired language from the right drop down for pages to re-populate accordingly. +![](<../.gitbook/assets/Screen Shot 2021-07-29 at 3.26.35 PM.png>) + +## Devices + +Upon login the first page presented is a Devices table. This table reflects all discovered and managed devices known by the OpenWiFi SDK. + +![Devices Table](<../.gitbook/assets/Screen Shot 2021-08-01 at 12.04.01 PM.png>) + +Devices table indicates device Connected or Disconnected state in the first column with green and red respectively. + +Certificate column indicates invalid, valid with mismatch serial, or valid device certificate identity state as red crossed seal, yellow seal and green seal respectively. + +Serial Number column links to the device record. + +Compatible model, Tx, Rx, and connected IP Address present basic information of the device type and its connection. + +Three final columns provide Details (also obtained by selecting the serial number), Wi-Fi Analysis presenting current Wi-Fi associations and their performance and Refresh commands. + +## Displaying Associations + +From the Devices table, second from right column icon the WiFi Analysis may be accessed. This may also be accessed within the Device View page of a single record along the top right of Statistics section. + +![Wi-Fi Analysis](<../.gitbook/assets/Screen Shot 2021-08-01 at 12.04.36 PM.png>) + +Within the WiFi Analysis page, all active associations are displayed with the ability to view approximately the last 30 minutes of data reported from the Access Point. + +For each association the device MAC address, mode of connection and SSID are displayed. This will include end devices as well as Wi-Fi infrastructure such as WDS and Mesh associations. + +![](<../.gitbook/assets/Screen Shot 2021-07-28 at 4.54.43 PM.png>) + +Associations have RSSI, Rx Rate & Bytes, Tx Rate & Bytes, MCS negotiated, Number Spatial Streams and IP Address information. + +## Dashboard View + +OpenWiFi SDK provides visual indications on the overall health of the deployed Wi-Fi network. this includes Device Status for connected and non-connected devices. Device health indicating percentage of devices failing a health check. Distribution of devices by vendor in the network and by model. + +![Dashboard View](<../.gitbook/assets/Screen Shot 2021-08-01 at 12.06.15 PM.png>) + +Additionally, verified certificates or serial mismatch certificates, number of Command actions from all Gateways to devices and devices with greater than 75% memory utilization, greater than 50% less than 75% memory and less than 50% utilization are displayed. + +![](<../.gitbook/assets/Screen Shot 2021-07-30 at 12.09.27 AM.png>) diff --git a/user-interface/devices-view/README.md b/user-interface/devices-view/README.md new file mode 100644 index 0000000..7cfeaa2 --- /dev/null +++ b/user-interface/devices-view/README.md @@ -0,0 +1,63 @@ +--- +description: OpenWiFi 2.0 SDK +--- + +# Devices + +Each device presents Metrics and Health check data to the Gateway. Devices view displays this information in the following organization: + +* Status +* Configuration +* Logs +* Health +* Commands +* Statistics +* Command History + +![Initial Device View](<../../.gitbook/assets/Screen Shot 2021-07-28 at 5.15.03 PM.png>) + +## Status + +Connection status reflects the Gateway to Device current communications status.\ +Uptime and Last Contact reflect communication state.\ +Load indicates processing load on the device.\ +Memory Used indicates free memory on the device. + +![Device Status](<../../.gitbook/assets/Screen Shot 2021-07-28 at 5.17.59 PM.png>) + +## Configuration + +Device UUID, Serial Number, MAC Address and Device Type are displayed.\ +Last configuration update date and timestamp reflects the last time a "configure" action completed on the device.\ +Password may be set and device notes may be added. + +![Device view Configuration Panel](<../../.gitbook/assets/Screen Shot 2021-07-28 at 5.21.07 PM.png>) + +## Logs + +Log history of the device is presented within Logs. Expand the tile selecting the down arrow. + +![](<../../.gitbook/assets/Screen Shot 2021-07-28 at 5.25.29 PM.png>) + +## Health + +Health score is an active tile reflecting the device health out of a score reported by the device to Gateway. Health metrics are configured on the device based on chosen data model options. When the device falls out of 100%, this tile changes to red. Expanding the tile will present all health reports. Those with less than 100% score will contain reasons for the result from this interface. + +![](<../../.gitbook/assets/Screen Shot 2021-07-28 at 5.24.00 PM.png>) + +## Commands + +Commands tile provides a number of administrative actions for the user: + +| Command | Action | +| ---------------- | ------------------------------------------------------- | +| Reboot | Warm Restart remote device | +| Firmware Upgrade | Initiate firmware upgrade process | +| WiFi Scan | Initiate remote scan of surrounding Wi-Fi | +| Connect | Initiate an rTTY Remote Shell session | +| Blink | Set LEDs to On, Off or Blinking state | +| Trace | Initiate a remote Packet Capture | +| Factory Reset | Hard Reset remote device - destroys device local config | +| Configure | Upload Device Configuration | + +![Commands Tile](<../../.gitbook/assets/Screen Shot 2021-07-28 at 5.25.50 PM.png>) diff --git a/user-interface/devices-view/command-history.md b/user-interface/devices-view/command-history.md new file mode 100644 index 0000000..3455eca --- /dev/null +++ b/user-interface/devices-view/command-history.md @@ -0,0 +1,25 @@ +--- +description: OpenWiFi SDK 2.0 +--- + +# Command History + +Multiple events are recorded in the Command History tile. Each line item will have a Result, Details, and Delete action. + +![Command History Tile](<../../.gitbook/assets/Screen Shot 2021-07-29 at 3.10.22 PM.png>) + +When an rTTY session is executed, this is a displayed command history. Selecting the Result icons will display the Success or Fail of the command. + +![rTTY Command History](<../../.gitbook/assets/Screen Shot 2021-07-29 at 3.12.02 PM.png>) + +Each provisioning event is reflected as a configure command history. To see the entire JSON payload and the result, including success or error with message, simply select Details to expand the dialog below with this data. A date and time in the third column indicates when the configure command was executed successfully. + +![Configure Command History](<../../.gitbook/assets/Screen Shot 2021-07-29 at 3.12.27 PM.png>) + +If a provisioning event has failed to complete, its command history for configure will show as pending. + +![configure Pending Command History](<../../.gitbook/assets/Screen Shot 2021-07-29 at 3.18.12 PM.png>) + +Remote packet capture is shown as the trace command history. When packet captures are persisted in the OpenWiFi SDK, they may be downloaded again through the cloud download icon. + +![trace Command History](<../../.gitbook/assets/Screen Shot 2021-07-29 at 3.16.52 PM.png>) diff --git a/user-interface/devices-view/commands.md b/user-interface/devices-view/commands.md new file mode 100644 index 0000000..62e8d33 --- /dev/null +++ b/user-interface/devices-view/commands.md @@ -0,0 +1,70 @@ +--- +description: OpenWiFi 2.0 SDK +--- + +# Commands + +Within the devices view, the Commands tile offers a number of features and administrative actions.\ +Each of these represent API calls exposed on the OpenAPI northbound interface from the SDK. + +## Reboot + +Selecting the Reboot action will prompt the below dialog. Options presented permit an immediate reboot or a scheduled reboot based on date and time. + +![](<../../.gitbook/assets/Screen Shot 2021-07-29 at 2.25.03 PM.png>) + +## Firmware Upgrade + +Multiple methods exist to execute a remote Firmware Upgrade of a device. When selecting Firmware Upgrade via the Commands tile, a simple dialog to upgrade immediately or at a scheduled time is presented. Alternatively using the Firmware Management Service provides a complete solution including managed access to all TIP firmware images. + +![](<../../.gitbook/assets/Screen Shot 2021-07-29 at 2.28.44 PM.png>) + +## Wi-Fi Scan + +OpenWiFi devices may perform channel scanning and return this neighbor and RF data to the SDK in an on demand or ongoing manner. + +![](<../../.gitbook/assets/Screen Shot 2021-07-29 at 2.31.03 PM.png>) + +### Wi-Fi Scan Results + +Scan operations function over all channels. If 5GHz channels do not display in the returned results ( either via the UI or over API ) this indicates the device is configured in a DFS channel for which it may not return survey scans at this time. + +![](<../../.gitbook/assets/Screen Shot 2021-07-29 at 2.33.58 PM.png>) + +## Connect + +OpenWiFi enables remote connection to any managed device using rTTY encrypted shell session. Selecting Connect will cause a browser tab to open with the login session to current device. + +![](<../../.gitbook/assets/Screen Shot 2021-07-29 at 2.35.48 PM.png>) + +## Blink + +To assist with remote identification of devices in the network, it is possible to turn the LED lights On, Off, of continuous blinking. This may be run on-demand or scheduled. + +![](<../../.gitbook/assets/Screen Shot 2021-07-29 at 2.37.30 PM.png>) + +## Trace + +Trace feature enables a remote packet capture to occur on the managed device, over a specified period of time or amount of traffic, returning the "pcap" packet capture file locally to the OpenWiFi admin user. + +![](<../../.gitbook/assets/Screen Shot 2021-07-29 at 2.39.24 PM.png>) + +Once complete the user is asked to open or save the packet capture file locally. + +![](<../../.gitbook/assets/image (33).png>) + +## Factory Reset + +It is possible to revert a device to initial out of box state from the OpenWiFi SDK. Sending a Factory Reset will remove all configuration on the device and optionally reset the discovered cloud stored as the 'Redirector' in the device configuration. + +![](<../../.gitbook/assets/Screen Shot 2021-07-29 at 2.46.29 PM.png>) + +{% hint style="info" %} +Note: When Redirector is not kept, devices will re-contact the Certificate Authority to re-discover their OpenWiFi cloud address +{% endhint %} + +## Configure + +Prior to the introduction of OpenWiFi 2.0 Provisioning Service, device configuration is done through creation of the JSON provisioning file and either loading that file or applying its contents using the dialog presented via Configure. The same options exist when using the API directly. + +![](<../../.gitbook/assets/Screen Shot 2021-07-29 at 2.48.31 PM.png>) diff --git a/user-interface/devices-view/statistics.md b/user-interface/devices-view/statistics.md new file mode 100644 index 0000000..d9b1b48 --- /dev/null +++ b/user-interface/devices-view/statistics.md @@ -0,0 +1,37 @@ +--- +description: OpenWiFi 2.0 SDK +--- + +# Statistics + +Each device page presents statistics in traffic terms per interface as a line graph of bandwidth over time. + +![](<../../.gitbook/assets/Screen Shot 2021-07-29 at 2.52.10 PM.png>) + +The generated image may be downloaded for offline use. + +![](<../../.gitbook/assets/Screen Shot 2021-07-29 at 2.53.14 PM.png>) + +Accessing Wi-Fi Analysis and Last Statistics may be found at the top right of Statistics tile. + +![](<../../.gitbook/assets/Screen Shot 2021-07-29 at 3.06.20 PM.png>) + +## Wi-Fi Analysis + +Operating channels, channel width, noise floor and transmit power are the first values reported in Radios table. + +Viewing associations, from the Associations table, and their use is important in terms of bandwidth and connection quality. Wi-Fi Analysis helps visualize each client association, this could be an end user device or a WDS or Mesh association. + +Each association is known by their MAC address or BSSID value. The mode of connection will indicate if an end user client device entering the "ap" or if a client is associated as "wds" or "mesh. + +![](<../../.gitbook/assets/Screen Shot 2021-07-29 at 2.57.34 PM.png>) + +The access point view of RSSI, Rx and Tx Rate, Modulation Coding Scheme and Number of Spatial Streams are exposed for each association. + +Using the slider along the top, the last 15 to 30 minutes of performances data may be viewed. + +## Latest Statistics + +The option to view Latest Statistics is at time of the MVP release, intended to help the Community see on a per device basis how much, or how little depending on device configuration, is being sent to the OpenWiFi Gateway in terms of telemetry. + +![](<../../.gitbook/assets/Screen Shot 2021-07-29 at 3.04.42 PM.png>) diff --git a/user-interface/firmware.md b/user-interface/firmware.md new file mode 100644 index 0000000..20929dc --- /dev/null +++ b/user-interface/firmware.md @@ -0,0 +1,35 @@ +--- +description: OpenWiFi 2.0 SDK +--- + +# Firmware + +Firmware management service integrates across all OpenWiFi Gateways deployed in a cluster enabling updates to running firmware either from the latest published version, or any other released version. + +## Dashboard + +Firmware dashboard provides a single view for overall health of deployed device firmware. Latest firmware charts, device firmware version distribution, distribution of device by type and current connected devices. + +![Firmware Dashboard](<../.gitbook/assets/Screen Shot 2021-08-01 at 12.07.27 PM.png>) + +## Device Table + +From the Devices table, any device with a newer firmware published by TIP OpenWiFi is indicated with a yellow icon. Selecting this icon presents the option to upgrade to latest or specify which firmware to use. + +![Firmware Control in Device Table](<../.gitbook/assets/Screen Shot 2021-08-01 at 12.08.45 PM.png>) + +When the upgrade has been sent successfully, a green Success dialog will display in the upper right on the screen. Devices with latest firmware version will show a green firmware icon in the Devices row. + +## Firmware Management Service + +Viewing the contents of Firmware Management Service is available from the left navigation, select Firmware. + +Once in Firmware, it is possible to search by device model for all known firmware revisions. + +![Firmware Management Service](<../.gitbook/assets/Screen Shot 2021-07-29 at 4.43.57 PM.png>) + +If in the Device Table reference above, instead of selecting Upgrade to Latest, the specific URI location of any available firmware is found using the Firmware table. + +Selecting Details will present information for any firmware row, including the URI which may be copied into the Choose Custom Firmware dialog prompt accordingly. + +![Firmware Entry Details](<../.gitbook/assets/Screen Shot 2021-07-29 at 4.46.01 PM.png>)