├── .env.template ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE.md ├── commitlint.config.cjs ├── dependabot.yml └── workflows │ ├── dependency-review.yml │ ├── helm-tgz-asset.yml │ ├── projectsSync.yaml │ ├── scorecards.yml │ └── semantic.yml ├── .gitignore ├── .gitmodules ├── Jenkinsfile ├── LICENSE ├── Readme.md ├── SECURITY.md ├── aks.json ├── azureDeploy.json ├── build.ps1 ├── data ├── init.sql └── initMPS.sql ├── docker-compose.yml ├── kong.conf ├── kong.yaml ├── kubernetes ├── charts │ ├── .helmignore │ ├── Chart.lock │ ├── Chart.yaml │ ├── charts │ │ ├── kong-2.39.3.tgz │ │ └── vault-0.28.0.tgz │ ├── secrets.yaml │ ├── templates │ │ ├── _helpers.tpl │ │ ├── kong.yaml │ │ ├── mps.yaml │ │ ├── mpsrouter.yaml │ │ ├── rps.yaml │ │ └── webui.yaml │ └── values.yaml └── config.json ├── makefile ├── mosquitto.conf ├── nginx.conf ├── pg ├── Dockerfile └── pg_hba.conf └── sdle.yaml /.env.template: -------------------------------------------------------------------------------- 1 | # WEB UI 2 | WEBUI_PORT=4200 3 | 4 | # RPS 5 | RPS_WEBSOCKETTLS=true 6 | RPSWEBPORT=8081 7 | RPSWEBSOCKETPORT=8080 8 | RPS_LOG_LEVEL=info 9 | RPS_DELAY_TIMER=12 10 | RPS_MQTT_ADDRESS= 11 | 12 | # MPS 13 | MPS_VAULT_ADDRESS=http://vault:8200 14 | MPS_GENERATE_CERTS=true 15 | MPS_COMMON_NAME=localhost 16 | MPSPORT=4433 17 | MPSWEBPORT=3000 18 | MPS_DEBUG=true 19 | MPS_WEB_ADMIN_USER= 20 | MPS_WEB_ADMIN_PASSWORD= 21 | MPS_HTTPS=true 22 | MPS_TLS_OFFLOAD=false 23 | MPS_LOG_LEVEL=info 24 | MPS_JWT_EXPIRATION=1440 25 | MPS_JWT_SECRET= 26 | MPS_JWT_ISSUER=9EmRJTbIiIb4bIeSsmgcWIjrR6HyETqc 27 | MPS_MQTT_ADDRESS= 28 | 29 | # MPS ROUTER 30 | PORT=8003 31 | 32 | # POSTGRES 33 | POSTGRES_USER=postgresadmin 34 | POSTGRES_PASSWORD= 35 | 36 | # VAULT 37 | SECRETS_PATH=secret/data/ 38 | VAULT_ADDRESS=http://vault:8200 39 | VAULT_TOKEN= 40 | 41 | # CONSUL 42 | CONSUL_ENABLED=false 43 | CONSUL_HOST=consul 44 | CONSUL_PORT=8500 -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | mosquitto.conf text eol=lf -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 6 | **Describe the bug** 🪲 7 | A clear and concise description of what the bug is. 8 | 9 | 10 | **To Reproduce** 🪜 11 | Steps to reproduce the behavior: 12 | 1. Go to '...' 13 | 2. Click on '....' 14 | 3. Scroll down to '....' 15 | 4. See error 16 | 17 | **Expected behavior** 18 | A clear and concise description of what you expected to happen. 19 | 20 | **Screenshots** 🖼️ 21 | If applicable, add screenshots to help explain your problem. 22 | 23 | **AMT Device (please complete the following information):** 🖥️ 24 | - OS: [e.g. Linux Kernel & Version] 25 | - AMT Version: [e.g. 11.8.5, 12.0.45] 26 | - AMT Configuration Mode: [e.g. Admin Control Mode or Client Control Mode] 27 | - Network Configuration [e.g. Dynamic IP or Static IP] 28 | 29 | **Service Deployment (please complete the following information):** ⛈️ 30 | - Deployment Type: [e.g. Azure, Docker, K8s] 31 | - Node Version: [e.g. LTS 14] 32 | - Component & Version: [e.g. RPS 2.0.0] 33 | 34 | **Additional context** 35 | Add any other context about the problem here. 36 | -------------------------------------------------------------------------------- /.github/commitlint.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['@commitlint/config-conventional'], 3 | rules: { 4 | 'body-max-line-length': [2, 'always', 200], 5 | 'subject-case': [ 6 | 1, 7 | 'never', 8 | ['sentence-case', 'start-case', 'pascal-case', 'upper-case'], 9 | ], 10 | } 11 | } -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: github-actions 4 | directory: / 5 | schedule: 6 | interval: daily 7 | 8 | - package-ecosystem: docker 9 | directory: /pg 10 | schedule: 11 | interval: daily 12 | -------------------------------------------------------------------------------- /.github/workflows/dependency-review.yml: -------------------------------------------------------------------------------- 1 | # Dependency Review Action 2 | # 3 | # This Action will scan dependency manifest files that change as part of a Pull Request, 4 | # surfacing known-vulnerable versions of the packages declared or updated in the PR. 5 | # Once installed, if the workflow run is marked as required, 6 | # PRs introducing known-vulnerable packages will be blocked from merging. 7 | # 8 | # Source repository: https://github.com/actions/dependency-review-action 9 | name: 'Dependency Review' 10 | on: [pull_request] 11 | 12 | permissions: 13 | contents: read 14 | 15 | jobs: 16 | dependency-review: 17 | runs-on: ubuntu-latest 18 | steps: 19 | - name: Harden Runner 20 | uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 21 | with: 22 | egress-policy: audit 23 | 24 | - name: 'Checkout Repository' 25 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 26 | - name: 'Dependency Review' 27 | uses: actions/dependency-review-action@da24556b548a50705dd671f47852072ea4c105d9 # v4.7.1 28 | -------------------------------------------------------------------------------- /.github/workflows/helm-tgz-asset.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | tags: 4 | - "*" 5 | name: Build and release on push 6 | permissions: 7 | contents: read 8 | jobs: 9 | release: 10 | name: create release artifacts 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Harden Runner 14 | uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 15 | with: 16 | egress-policy: audit 17 | 18 | - name: clone open amt examples repo 19 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 20 | with: 21 | ref: ${{ github.ref }} 22 | 23 | - name: Print github workspace 24 | run: echo $GITHUB_WORKSPACE && pwd && echo ${{ github.workspace }} 25 | 26 | - name: tar zip helm directory 27 | shell: bash 28 | run: | 29 | (cd $GITHUB_WORKSPACE/kubernetes && tar -czvf open-amt-toolkit-helm.tar.gz charts) 30 | 31 | - name: upload helm tarball release artifact 32 | uses: svenstaro/upload-release-action@04733e069f2d7f7f0b4aebc4fbdbce8613b03ccd # v2 33 | with: 34 | repo_token: ${{ secrets.GITHUB_TOKEN }} 35 | file: ${{ github.workspace}}/kubernetes/open-amt-toolkit-helm.tar.gz 36 | asset_name: open-amt-toolkit-helm.tar.gz 37 | tag: ${{ github.ref }} 38 | overwrite: true 39 | body: "Open AMT Cloud Toolkit Helm deployment tarball asset" 40 | -------------------------------------------------------------------------------- /.github/workflows/projectsSync.yaml: -------------------------------------------------------------------------------- 1 | name: Adds all issues to project board 2 | on: 3 | issues: 4 | types: 5 | - opened 6 | permissions: 7 | contents: read 8 | 9 | jobs: 10 | add-to-project: 11 | name: Add issue to project 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Harden Runner 15 | uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 16 | with: 17 | egress-policy: audit 18 | 19 | - uses: actions/add-to-project@244f685bbc3b7adfa8466e08b698b5577571133e # v1.0.2 20 | with: 21 | project-url: https://github.com/orgs/device-management-toolkit/projects/10 22 | github-token: ${{ secrets.PROJECTS_PAT }} 23 | -------------------------------------------------------------------------------- /.github/workflows/scorecards.yml: -------------------------------------------------------------------------------- 1 | # This workflow uses actions that are not certified by GitHub. They are provided 2 | # by a third-party and are governed by separate terms of service, privacy 3 | # policy, and support documentation. 4 | 5 | name: Scorecard supply-chain security 6 | on: 7 | # For Branch-Protection check. Only the default branch is supported. See 8 | # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection 9 | branch_protection_rule: 10 | # To guarantee Maintained check is occasionally updated. See 11 | # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained 12 | schedule: 13 | - cron: '20 7 * * 2' 14 | push: 15 | branches: ["main"] 16 | 17 | # Declare default permissions as read only. 18 | permissions: read-all 19 | 20 | jobs: 21 | analysis: 22 | name: Scorecard analysis 23 | runs-on: ubuntu-latest 24 | permissions: 25 | # Needed to upload the results to code-scanning dashboard. 26 | security-events: write 27 | # Needed to publish results and get a badge (see publish_results below). 28 | id-token: write 29 | contents: read 30 | actions: read 31 | 32 | steps: 33 | - name: Harden Runner 34 | uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 35 | with: 36 | egress-policy: audit 37 | 38 | - name: "Checkout code" 39 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 40 | with: 41 | persist-credentials: false 42 | 43 | - name: "Run analysis" 44 | uses: ossf/scorecard-action@05b42c624433fc40578a4040d5cf5e36ddca8cde # v2.4.2 45 | with: 46 | results_file: results.sarif 47 | results_format: sarif 48 | # (Optional) "write" PAT token. Uncomment the `repo_token` line below if: 49 | # - you want to enable the Branch-Protection check on a *public* repository, or 50 | # - you are installing Scorecards on a *private* repository 51 | # To create the PAT, follow the steps in https://github.com/ossf/scorecard-action#authentication-with-pat. 52 | # repo_token: ${{ secrets.SCORECARD_TOKEN }} 53 | 54 | # Public repositories: 55 | # - Publish results to OpenSSF REST API for easy access by consumers 56 | # - Allows the repository to include the Scorecard badge. 57 | # - See https://github.com/ossf/scorecard-action#publishing-results. 58 | # For private repositories: 59 | # - `publish_results` will always be set to `false`, regardless 60 | # of the value entered here. 61 | publish_results: true 62 | 63 | # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF 64 | # format to the repository Actions tab. 65 | - name: "Upload artifact" 66 | uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 67 | with: 68 | name: SARIF file 69 | path: results.sarif 70 | retention-days: 5 71 | 72 | # Upload the results to GitHub's code scanning dashboard. 73 | - name: "Upload to code-scanning" 74 | uses: github/codeql-action/upload-sarif@fca7ace96b7d713c7035871441bd52efbe39e27e # v3.28.19 75 | with: 76 | sarif_file: results.sarif 77 | -------------------------------------------------------------------------------- /.github/workflows/semantic.yml: -------------------------------------------------------------------------------- 1 | name: "Semantic Pull Request" 2 | 3 | on: 4 | pull_request: 5 | types: 6 | - opened 7 | - edited 8 | - synchronize 9 | permissions: 10 | contents: read 11 | 12 | jobs: 13 | main: 14 | permissions: 15 | contents: read # for actions/checkout to fetch code 16 | pull-requests: read # for wagoid/commitlint-github-action to get commits in PR 17 | name: Validate PR and Commits 18 | runs-on: ubuntu-latest 19 | steps: 20 | - name: Harden Runner 21 | uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 22 | with: 23 | egress-policy: audit 24 | 25 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 26 | with: 27 | fetch-depth: 0 28 | - uses: wagoid/commitlint-github-action@b948419dd99f3fd78a6548d48f94e3df7f6bf3ed # v6.2.1 29 | with: 30 | configFile: ./.github/commitlint.config.cjs 31 | - name: Install Dependencies 32 | run: npm install @commitlint/config-conventional@18.5 33 | - uses: JulienKode/pull-request-name-linter-action@8c05fb989d9f156ce61e33754f9802c9d3cffa58 # v0.5.0 34 | with: 35 | configuration-path: ./.github/commitlint.config.cjs 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | .vscode/ -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "rpc"] 2 | path = rpc 3 | url = https://github.com/device-management-toolkit/rpc.git 4 | [submodule "rps"] 5 | path = rps 6 | url = https://github.com/device-management-toolkit/rps.git 7 | [submodule "ui-toolkit"] 8 | path = ui-toolkit 9 | url = https://github.com/device-management-toolkit/ui-toolkit.git 10 | [submodule "mps"] 11 | path = mps 12 | url = https://github.com/device-management-toolkit/mps.git 13 | [submodule "sample-web-ui"] 14 | path = sample-web-ui 15 | url = https://github.com/device-management-toolkit/sample-web-ui.git 16 | [submodule "mps-router"] 17 | path = mps-router 18 | url = https://github.com/device-management-toolkit/mps-router.git 19 | [submodule "ui-toolkit-angular"] 20 | path = ui-toolkit-angular 21 | url = https://github.com/device-management-toolkit/ui-toolkit-angular.git 22 | [submodule "ui-toolkit-react"] 23 | path = ui-toolkit-react 24 | url = https://github.com/device-management-toolkit/ui-toolkit-react.git 25 | [submodule "rpc-go"] 26 | path = rpc-go 27 | url = https://github.com/device-management-toolkit/rpc-go 28 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | pipeline { 2 | agent { 3 | label 'rbhe' 4 | } 5 | stages { 6 | stage('SDLE Upload') { 7 | when { 8 | anyOf { 9 | allOf { 10 | expression { env.GIT_BRANCH == 'main' } 11 | expression { common.isSdleUploadCommit() } 12 | } 13 | triggeredBy 'UserIdCause' 14 | } 15 | } 16 | steps { 17 | script { 18 | parallel getStages('sdle.yaml') 19 | } 20 | } 21 | } 22 | } 23 | post { 24 | cleanup { 25 | cleanWs() 26 | } 27 | } 28 | } 29 | 30 | def getStages(filename) { 31 | def projects = readYaml file: filename 32 | def stages = projects.collectEntries { 33 | ["${it.repo}" : generateStage(it)] 34 | } 35 | stages 36 | } 37 | 38 | def generateStage(project) { 39 | return { 40 | stage("${project.repo}") { 41 | // ensure isolated workspace for each project 42 | ws { 43 | sh 'rm -rf artifacts/' 44 | 45 | downloadGHArtifacts([ 46 | projectOwner: project.owner, 47 | projectRepo: project.repo, 48 | projectBranch: project.branch, 49 | projectArtifacts: project.artifacts, 50 | projectFolders: project.folders]) 51 | 52 | sdleUpload([ 53 | sdleUploadProjectId: project.sdle_project_id]) 54 | } 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # Device Management Toolkit (formerly known as Open AMT Cloud Toolkit) 2 | 3 | [![Discord](https://img.shields.io/discord/1063200098680582154?style=for-the-badge&label=Discord&logo=discord&logoColor=white&labelColor=%235865F2&link=https%3A%2F%2Fdiscord.gg%2FDKHeUNEWVH)](https://discord.gg/DKHeUNEWVH) 4 | 5 | > Disclaimer: Production viable releases are tagged and listed under 'Releases'. All other check-ins should be considered 'in-development' and should not be used in production 6 | 7 | Device Management Toolkit (formerly known as Open Active Management Technology Cloud Toolkit (Open AMT Cloud Toolkit)) offers open-source microservices and libraries to streamline Intel AMT integration, simplifying out-of-band management solutions for Intel vPro Platforms. 8 | 9 | **For detailed documentation** about the Open AMT Cloud Toolkit, see the [docs]. 10 | 11 | ## Clone 12 | 13 | **Important!** Make sure you clone this repo with the `--recursive` flag since it uses git submodules. 14 | 15 | To clone live, in-development code (main branch): 16 | 17 | ```bash 18 | git clone --recursive https://github.com/device-management-toolkit/cloud-deployment.git 19 | ``` 20 | 21 | Alternatively, for steps to clone and Get Started with one of the tagged releases, [see our documentation][docs]. 22 | 23 | ## Get Started 24 | 25 | There are multiple options to quickly deploy the Open AMT Cloud Toolkit: 26 | 27 | ### Option 1: Local using Docker 28 | 29 | The quickest and easiest option is to set up a local stack using Docker, view our [Documentation Site][docs] and click the Get Started tab for How-To steps and examples. 30 | 31 | ### Option 2: Cloud using Azure 32 | 33 | For more experienced users, deploy the stack on Azure using the 'Deploy to Azure' button below. 34 | 35 | > Note: This requires MPS, RPS, and Sample Web UI images to be built and accessible in a Container Image Registry such as Azure Container Registry (ACR), Docker Hub, or other options. 36 | 37 | [![Deploy to Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2Fdevice-management-toolkit%2Fcloud-deployment%2Fv2.5.0%2FazureDeploy.json) 38 | 39 | Optionally, deploy from AzureCLI using the following commands: 40 | 41 | ```bash 42 | az group create --name openamt --location eastus 43 | az deployment group create --resource-group openamt --template-file azureDeploy.json 44 | ``` 45 | 46 | 47 | Additional deployments, such as Kubernetes via Azure (AKS) or AWS (EKS), can be found in our [Documentation Site][docs]. 48 | 49 | ## Additional Resources 50 | 51 | - For detailed documentation and Getting Started, [visit the docs site][docs]. 52 | 53 | - Find a bug? Or have ideas for new features? [Open a new Issue](./issues). 54 | 55 | - Discover a vulnerability or do you have a security concern? [See our Security policy](SECURITY.md) for our reporting process. 56 | 57 | - Need additional support or want to get the latest news and events about Open AMT? Connect with the team directly through Discord. 58 | 59 | [![Discord Banner 1](https://discordapp.com/api/guilds/1063200098680582154/widget.png?style=banner2)](https://discord.gg/DKHeUNEWVH) 60 | 61 | [docs]: https://device-management-toolkit.github.io/docs 62 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | Intel is committed to rapidly addressing security vulnerabilities affecting our customers and providing clear guidance on the solution, impact, severity and mitigation. 3 | 4 | ## Reporting a Vulnerability 5 | Please report any security vulnerabilities in this project utilizing the guidelines [here](https://www.intel.com/content/www/us/en/security-center/vulnerability-handling-guidelines.html). 6 | -------------------------------------------------------------------------------- /aks.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.1", 4 | "parameters": { 5 | "clusterName": { 6 | "type": "string", 7 | "metadata": { 8 | "description": "The name of the Managed Cluster resource." 9 | } 10 | }, 11 | "location": { 12 | "type": "string", 13 | "defaultValue": "[resourceGroup().location]", 14 | "metadata": { 15 | "description": "The location of the Managed Cluster resource." 16 | } 17 | }, 18 | "osDiskSizeGB": { 19 | "type": "int", 20 | "defaultValue": 0, 21 | "minValue": 0, 22 | "maxValue": 1023, 23 | "metadata": { 24 | "description": "Disk size (in GB) to provision for each of the agent pool nodes. This value ranges from 0 to 1023. Specifying 0 will apply the default disk size for that agentVMSize." 25 | } 26 | }, 27 | "agentCount": { 28 | "type": "int", 29 | "defaultValue": 3, 30 | "minValue": 1, 31 | "maxValue": 50, 32 | "metadata": { 33 | "description": "The number of nodes for the cluster." 34 | } 35 | }, 36 | "agentVMSize": { 37 | "type": "string", 38 | "defaultValue": "Standard_DS2_v2", 39 | "metadata": { 40 | "description": "The size of the Virtual Machine." 41 | } 42 | }, 43 | "linuxAdminUsername": { 44 | "type": "string", 45 | "metadata": { 46 | "description": "User name for the Linux Virtual Machines." 47 | } 48 | }, 49 | "sshRSAPublicKey": { 50 | "type": "string", 51 | "metadata": { 52 | "description": "Configure all linux machines with the SSH RSA public key string. Your key should include three parts, for example 'ssh-rsa AAAAB...snip...UcyupgH azureuser@linuxvm'" 53 | } 54 | }, 55 | "osType": { 56 | "type": "string", 57 | "defaultValue": "Linux", 58 | "allowedValues": [ 59 | "Linux" 60 | ], 61 | "metadata": { 62 | "description": "The type of operating system." 63 | } 64 | }, 65 | "DBadministratorLogin": { 66 | "type": "string", 67 | "minLength": 1, 68 | "metadata": { 69 | "description": "Database administrator login name" 70 | } 71 | }, 72 | "DBadministratorLoginPassword": { 73 | "type": "securestring", 74 | "minLength": 8, 75 | "metadata": { 76 | "description": "Database administrator password" 77 | } 78 | }, 79 | "availabilityZone": { 80 | "type": "string", 81 | "defaultValue": "" 82 | }, 83 | "virtualNetworkExternalId": { 84 | "type": "string", 85 | "defaultValue": "" 86 | }, 87 | "subnetName": { 88 | "type": "string", 89 | "defaultValue": "" 90 | }, 91 | "privateDnsZoneArmResourceId": { 92 | "type": "string", 93 | "defaultValue": "" 94 | } 95 | }, 96 | "variables": { 97 | "postgresServerName": "[concat(parameters('clusterName'),'-sql')]" 98 | }, 99 | "resources": [ 100 | { 101 | "type": "Microsoft.ContainerService/managedClusters", 102 | "apiVersion": "2021-03-01", 103 | "name": "[parameters('clusterName')]", 104 | "location": "[parameters('location')]", 105 | "dependsOn": [ 106 | "[resourceId('Microsoft.DBforPostgreSQL/flexibleServers/', variables('postgresServerName'))]" 107 | ], 108 | "properties": { 109 | "dnsPrefix": "[parameters('clusterName')]", 110 | "agentPoolProfiles": [ 111 | { 112 | "name": "agentpool", 113 | "osDiskSizeGB": "[parameters('osDiskSizeGB')]", 114 | "count": "[parameters('agentCount')]", 115 | "vmSize": "[parameters('agentVMSize')]", 116 | "osType": "[parameters('osType')]", 117 | "type": "VirtualMachineScaleSets", 118 | "storageProfile": "ManagedDisks", 119 | "enableNodePublicIP": true, 120 | "mode": "System" 121 | } 122 | ], 123 | "linuxProfile": { 124 | "adminUsername": "[parameters('linuxAdminUsername')]", 125 | "ssh": { 126 | "publicKeys": [ 127 | { 128 | "keyData": "[parameters('sshRSAPublicKey')]" 129 | } 130 | ] 131 | } 132 | } 133 | }, 134 | "identity": { 135 | "type": "SystemAssigned" 136 | } 137 | }, 138 | { 139 | "type": "Microsoft.DBforPostgreSQL/flexibleServers", 140 | "apiVersion": "2021-06-01", 141 | "name": "[variables('postgresServerName')]", 142 | "location": "[parameters('location')]", 143 | "sku": { 144 | "name": "Standard_B2s", 145 | "tier": "Burstable" 146 | }, 147 | "properties": { 148 | "version": "16", 149 | "administratorLogin": "[parameters('DBadministratorLogin')]", 150 | "administratorLoginPassword": "[parameters('DBadministratorLoginPassword')]", 151 | "network": { 152 | "delegatedSubnetResourceId": "[if(empty(parameters('virtualNetworkExternalId')), json('null'), json(format('{0}/subnets/{1}', parameters('virtualNetworkExternalId'), parameters('subnetName'))))]", 153 | "privateDnsZoneArmResourceId": "[if(empty(parameters('virtualNetworkExternalId')), json('null'), parameters('privateDnsZoneArmResourceId'))]" 154 | }, 155 | "highAvailability": { 156 | "mode": "Disabled" 157 | }, 158 | "storage": { 159 | "storageSizeGB": 32 160 | }, 161 | "backup": { 162 | "backupRetentionDays": 7, 163 | "geoRedundantBackup": "Disabled" 164 | }, 165 | "availabilityZone": "[parameters('availabilityZone')]" 166 | } 167 | }, 168 | { 169 | "type": "Microsoft.DBforPostgreSQL/flexibleServers/configurations", 170 | "apiVersion": "2021-06-01", 171 | "name": "[concat(variables('postgresServerName'), '/azure.extensions')]", 172 | "dependsOn": [ 173 | "[resourceId('Microsoft.DBforPostgreSQL/flexibleServers', variables('postgresServerName'))]" 174 | ], 175 | "properties": { 176 | "value": "CITEXT", 177 | "source": "user-override" 178 | } 179 | } 180 | ], 181 | "outputs": { 182 | "MPSDatabaseConnectionString": { 183 | "type": "string", 184 | "value": "[concat('postgresql://',parameters('DBadministratorLogin'),'@',variables('postgresServerName'),':',parameters('DBadministratorLoginPassword'),'@',variables('postgresServerName'),'.postgres.database.azure.com:5432/mpsdb?sslmode=require')]" 185 | }, 186 | "RPSDatabaseConnectionString": { 187 | "type": "string", 188 | "value": "[concat('postgresql://',parameters('DBadministratorLogin'),'@',variables('postgresServerName'),':',parameters('DBadministratorLoginPassword'),'@',variables('postgresServerName'),'.postgres.database.azure.com:5432/rpsdb?sslmode=require')]" 189 | }, 190 | "controlPlaneFQDN": { 191 | "type": "string", 192 | "value": "[reference(parameters('clusterName')).fqdn]" 193 | }, 194 | "FQDNSuffix": { 195 | "type": "string", 196 | "value": "[concat(parameters('location'),'.cloudapp.azure.com')]" 197 | } 198 | } 199 | } -------------------------------------------------------------------------------- /azureDeploy.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "location": { 6 | "type": "string", 7 | "defaultValue": "[resourceGroup().location]" 8 | }, 9 | "containerStackName": { 10 | "type": "string", 11 | "defaultValue": "device-management-toolkit" 12 | }, 13 | "registry": { 14 | "type": "string", 15 | "defaultValue": "docker.io", 16 | "metadata": { 17 | "description": "Name of the Registry." 18 | } 19 | }, 20 | "registryUsername": { 21 | "type": "securestring", 22 | "metadata": { 23 | "description": "Username for the registry" 24 | } 25 | }, 26 | "registryPassword": { 27 | "type": "securestring", 28 | "metadata": { 29 | "description": "Password for the registry" 30 | } 31 | }, 32 | "vaultToken": { 33 | "type": "securestring", 34 | "metadata": { 35 | "description": "Specifies the root token to use for Vault in DEV mode" 36 | } 37 | }, 38 | "rpsImageName": { 39 | "defaultValue": "intel/oact-rps:latest", 40 | "type": "string", 41 | "metadata": { 42 | "description": "Name of the RPS image to deploy from specified registry" 43 | } 44 | }, 45 | "mpsImageName": { 46 | "defaultValue": "intel/oact-mps:latest", 47 | "type": "string", 48 | "metadata": { 49 | "description": "Name of the MPS image to deploy from specified registry" 50 | } 51 | }, 52 | "sampleWebUIImageName": { 53 | "defaultValue": "intel/oact-webui:latest", 54 | "type": "string", 55 | "metadata": { 56 | "description": "Name of the Sample WebUI image to deploy from specified registry" 57 | } 58 | }, 59 | "fqdn": { 60 | "type": "string", 61 | "metadata": { 62 | "description": "Name of the FQDN you wish to use to access this deployment (i.e. \"sample\" will result in an FQDN of sample.westus.azurecontainer.io)" 63 | } 64 | }, 65 | "useAllowlist": { 66 | "defaultValue": "false", 67 | "type": "string", 68 | "metadata": { 69 | "description": "For details on this property view the configuration documentation located under \"Microservices\" in the Device Management Toolkit documentation on https://device-management-toolkit.github.io/docs/" 70 | } 71 | }, 72 | "dbAdminUsername": { 73 | "type": "securestring", 74 | "defaultValue": "postgresadmin", 75 | "metadata": { 76 | "description": "For details on this property view the configuration documentation located under \"Microservices\" in the Device Management Toolkit documentation on https://device-management-toolkit.github.io/docs/" 77 | } 78 | }, 79 | "dbAdminPassword": { 80 | "type": "securestring", 81 | "defaultValue": "admin123", 82 | "metadata": { 83 | "description": "For details on this property view the configuration documentation located under \"Microservices\" in the Device Management Toolkit documentation on https://device-management-toolkit.github.io/docs/" 84 | } 85 | }, 86 | "mpsAdminUsername": { 87 | "type": "securestring", 88 | "metadata": { 89 | "description": "For details on this property view the configuration documentation located under \"Microservices\" in the Device Management Toolkit documentation on https://device-management-toolkit.github.io/docs/" 90 | } 91 | }, 92 | "mpsAdminPassword": { 93 | "type": "securestring", 94 | "metadata": { 95 | "description": "For details on this property view the configuration documentation located under \"Microservices\" in the Device Management Toolkit documentation on https://device-management-toolkit.github.io/docs/" 96 | } 97 | }, 98 | "tokenExpiration": { 99 | "defaultValue": "1440", 100 | "type": "string", 101 | "metadata": { 102 | "description": "Specifies the duration (in minutes) that a token will be valid for" 103 | } 104 | } 105 | }, 106 | "resources": [ 107 | { 108 | "type": "Microsoft.ContainerInstance/containerGroups", 109 | "apiVersion": "2019-12-01", 110 | "name": "[parameters('containerStackName')]", 111 | "location": "[parameters('location')]", 112 | "properties": { 113 | "sku": "Standard", 114 | "containers": [ 115 | { 116 | "name": "rps", 117 | "properties": { 118 | "image": "[concat(parameters('registry'), '/', parameters('rpsImageName'))]", 119 | "ports": [ 120 | { 121 | "port": 8080 122 | }, 123 | { 124 | "port": 8081 125 | } 126 | ], 127 | "environmentVariables": [ 128 | { 129 | "name": "RPS_VAULT_TOKEN", 130 | "value": "[parameters('vaultToken')]" 131 | }, 132 | { 133 | "name": "RPS_CONNECTION_STRING", 134 | "value": "[concat('postgresql://',parameters('dbAdminUsername'),':',parameters('dbAdminPassword'),'@localhost:5432/rpsdb')]" 135 | } 136 | ], 137 | "resources": { 138 | "requests": { 139 | "cpu": 0.5, 140 | "memoryInGb": 1.0 141 | } 142 | } 143 | } 144 | }, 145 | { 146 | "name": "mps", 147 | "properties": { 148 | "image": "[concat(parameters('registry'), '/', parameters('mpsImageName'))]", 149 | "resources": { 150 | "requests": { 151 | "cpu": 0.5, 152 | "memoryInGb": 1.0 153 | } 154 | }, 155 | "environmentVariables": [ 156 | { 157 | "name": "MPS_COMMON_NAME", 158 | "value": "[concat(parameters('fqdn'), '.', parameters('location'),'.azurecontainer.io')]" 159 | }, 160 | { 161 | "name": "MPS_WEB_ADMIN_USER", 162 | "value": "[parameters('mpsAdminUsername')]" 163 | }, 164 | { 165 | "name": "MPS_WEB_ADMIN_PASSWORD", 166 | "value": "[parameters('mpsAdminPassword')]" 167 | }, 168 | { 169 | "name": "MPS_JWT_EXPIRATION", 170 | "value": "[parameters('tokenExpiration')]" 171 | }, 172 | { 173 | "name": "MPS_JWT_SECRET", 174 | "value": "supersecret" 175 | }, 176 | { 177 | "name": "MPS_VAULT_TOKEN", 178 | "value": "[parameters('vaultToken')]" 179 | }, 180 | { 181 | "name": "MPS_CONNECTION_STRING", 182 | "value": "[concat('postgresql://',parameters('dbAdminUsername'),':',parameters('dbAdminPassword'),'@localhost:5432/mpsdb')]" 183 | } 184 | ], 185 | "ports": [ 186 | { 187 | "port": 4433 188 | }, 189 | { 190 | "port": 3000 191 | } 192 | ] 193 | } 194 | }, 195 | { 196 | "name": "webui", 197 | "properties": { 198 | "image": "[concat(parameters('registry'), '/', parameters('sampleWebUIImageName'))]", 199 | "ports": [ 200 | { 201 | "port": 80 202 | } 203 | ], 204 | "environmentVariables": [ 205 | { 206 | "name": "MPS_SERVER", 207 | "value": "[concat('https://',parameters('fqdn'), '.', parameters('location'), '.azurecontainer.io:8443/mps')]" 208 | }, 209 | { 210 | "name": "RPS_SERVER", 211 | "value": "[concat('https://',parameters('fqdn'), '.', parameters('location'), '.azurecontainer.io:8443/rps')]" 212 | } 213 | ], 214 | "volumeMounts": [ 215 | { 216 | "name": "nginx-config", 217 | "mountPath": "/etc/nginx/conf.d" 218 | } 219 | ], 220 | "resources": { 221 | "requests": { 222 | "cpu": 0.5, 223 | "memoryInGb": 1.0 224 | } 225 | } 226 | } 227 | }, 228 | { 229 | "name": "vault", 230 | "properties": { 231 | "image": "hashicorp/vault:latest", 232 | "environmentVariables": [ 233 | { 234 | "name": "VAULT_DEV_ROOT_TOKEN_ID", 235 | "value": "[parameters('vaultToken')]" 236 | }, 237 | { 238 | "name": "VAULT_DEV_LISTEN_ADDRESS", 239 | "value": "0.0.0.0:8200" 240 | } 241 | ], 242 | "resources": { 243 | "requests": { 244 | "cpu": 0.5, 245 | "memoryInGb": 1.0 246 | } 247 | } 248 | } 249 | }, 250 | { 251 | "name": "kong", 252 | "properties": { 253 | "image": "kong:2.3", 254 | "ports": [ 255 | { 256 | "port": 8443 257 | } 258 | ], 259 | "command": [ 260 | "kong", 261 | "start", 262 | "--vv" 263 | ], 264 | "environmentVariables": [ 265 | { 266 | "name": "KONG_DATABASE", 267 | "value": "off" 268 | }, 269 | { 270 | "name": "KONG_CASSANDRA_CONTACT_POINTS", 271 | "value": "kong-database" 272 | }, 273 | { 274 | "name": "KONG_ADMIN_LISTEN", 275 | "value": "0.0.0.0:8001" 276 | }, 277 | { 278 | "name": "KONG_ADMIN_LISTEN_SSL", 279 | "value": "0.0.0.0:8444" 280 | }, 281 | { 282 | "name": "KONG_NGINX_DAEMON", 283 | "value": "off" 284 | }, 285 | { 286 | "name": "KONG_DECLARATIVE_CONFIG", 287 | "value": "/home/kong/kong.yaml" 288 | }, 289 | { 290 | "name": "KONG_LOG_LEVEL", 291 | "value": "debug" 292 | } 293 | ], 294 | "volumeMounts": [ 295 | { 296 | "name": "kong-config", 297 | "mountPath": "/home/kong/" 298 | } 299 | ], 300 | "resources": { 301 | "requests": { 302 | "cpu": 0.5, 303 | "memoryInGb": 1.0 304 | } 305 | } 306 | } 307 | }, 308 | { 309 | "name": "db", 310 | "properties": { 311 | "image": "postgres:17", 312 | "ports": [ 313 | { 314 | "port": 5432 315 | } 316 | ], 317 | "environmentVariables": [ 318 | { 319 | "name": "POSTGRES_DB", 320 | "value": "rpsdb" 321 | }, 322 | { 323 | "name": "POSTGRES_USER", 324 | "value": "postgresadmin" 325 | }, 326 | { 327 | "name": "POSTGRES_PASSWORD", 328 | "value": "admin123" 329 | } 330 | ], 331 | "volumeMounts": [ 332 | { 333 | "name": "db-config", 334 | "mountPath": "/docker-entrypoint-initdb.d" 335 | } 336 | ], 337 | "resources": { 338 | "requests": { 339 | "cpu": 0.5, 340 | "memoryInGb": 1.0 341 | } 342 | } 343 | } 344 | } 345 | ], 346 | "osType": "Linux", 347 | "restartPolicy": "OnFailure", 348 | "imageRegistryCredentials": [ 349 | { 350 | "server": "[parameters('registry')]", 351 | "username": "[parameters('registryUsername')]", 352 | "password": "[parameters('registryPassword')]" 353 | } 354 | ], 355 | "ipAddress": { 356 | "dnsNameLabel": "[parameters('fqdn')]", 357 | "type": "Public", 358 | "ports": [ 359 | { 360 | "protocol": "tcp", 361 | "port": 4433 362 | }, 363 | { 364 | "protocol": "tcp", 365 | "port": 8443 366 | } 367 | ] 368 | }, 369 | "volumes": [ 370 | { 371 | "name": "db-config", 372 | "secret": { 373 | "init.sql": "Q1JFQVRFIEVYVEVOU0lPTiBJRiBOT1QgRVhJU1RTIGNpdGV4dDsNCkNSRUFURSBVU0VSIHJwc2RiOw0KQ1JFQVRFIFRBQkxFIElGIE5PVCBFWElTVFMgY2lyYWNvbmZpZ3MoDQogIGNpcmFfY29uZmlnX25hbWUgY2l0ZXh0IE5PVCBOVUxMLA0KICBtcHNfc2VydmVyX2FkZHJlc3MgdmFyY2hhcigyNTYpLA0KICBtcHNfcG9ydCBpbnRlZ2VyLA0KICB1c2VyX25hbWUgdmFyY2hhcig0MCksDQogIHBhc3N3b3JkIHZhcmNoYXIoNjMpLA0KICBjb21tb25fbmFtZSB2YXJjaGFyKDI1NiksDQogIHNlcnZlcl9hZGRyZXNzX2Zvcm1hdCBpbnRlZ2VyLA0KICBhdXRoX21ldGhvZCBpbnRlZ2VyLA0KICBtcHNfcm9vdF9jZXJ0aWZpY2F0ZSB0ZXh0LA0KICBwcm94eWRldGFpbHMgdGV4dCwNCiAgdGVuYW50X2lkIHZhcmNoYXIoMzYpIE5PVCBOVUxMLA0KICBQUklNQVJZIEtFWSAoY2lyYV9jb25maWdfbmFtZSwgdGVuYW50X2lkKQ0KKTsNCkNSRUFURSBUQUJMRSBJRiBOT1QgRVhJU1RTIGllZWU4MDIxeGNvbmZpZ3MoDQogICAgcHJvZmlsZV9uYW1lIGNpdGV4dCwNCiAgICBhdXRoX3Byb3RvY29sIGludGVnZXIsDQogICAgc2VydmVybmFtZSBWQVJDSEFSKDI1NSksDQogICAgZG9tYWluIFZBUkNIQVIoMjU1KSwNCiAgICB1c2VybmFtZSBWQVJDSEFSKDI1NSksDQogICAgcGFzc3dvcmQgVkFSQ0hBUigyNTUpLA0KICAgIHJvYW1pbmdfaWRlbnRpdHkgVkFSQ0hBUigyNTUpLA0KICAgIGFjdGl2ZV9pbl9zMCBCT09MRUFOLA0KICAgIHB4ZV90aW1lb3V0IGludGVnZXIsDQogICAgd2lyZWRfaW50ZXJmYWNlIEJPT0xFQU4gTk9UIE5VTEwsDQogICAgdGVuYW50X2lkIHZhcmNoYXIoMzYpIE5PVCBOVUxMLA0KICAgIFBSSU1BUlkgS0VZIChwcm9maWxlX25hbWUsIHRlbmFudF9pZCkNCik7DQpDUkVBVEUgVEFCTEUgSUYgTk9UIEVYSVNUUyB3aXJlbGVzc2NvbmZpZ3MoDQogIHdpcmVsZXNzX3Byb2ZpbGVfbmFtZSBjaXRleHQgTk9UIE5VTEwsDQogIGF1dGhlbnRpY2F0aW9uX21ldGhvZCBpbnRlZ2VyLA0KICBlbmNyeXB0aW9uX21ldGhvZCBpbnRlZ2VyLA0KICBzc2lkIHZhcmNoYXIoMzIpLA0KICBwc2tfdmFsdWUgaW50ZWdlciwNCiAgcHNrX3Bhc3NwaHJhc2UgdmFyY2hhcig2MyksDQogIGxpbmtfcG9saWN5IGludFtdLA0KICBjcmVhdGlvbl9kYXRlIHRpbWVzdGFtcCwNCiAgY3JlYXRlZF9ieSB2YXJjaGFyKDQwKSwNCiAgdGVuYW50X2lkIHZhcmNoYXIoMzYpIE5PVCBOVUxMLA0KICBpZWVlODAyMXhfcHJvZmlsZV9uYW1lIGNpdGV4dCwNCiAgRk9SRUlHTiBLRVkgKGllZWU4MDIxeF9wcm9maWxlX25hbWUsdGVuYW50X2lkKSAgUkVGRVJFTkNFUyBpZWVlODAyMXhjb25maWdzKHByb2ZpbGVfbmFtZSx0ZW5hbnRfaWQpLA0KICBQUklNQVJZIEtFWSAod2lyZWxlc3NfcHJvZmlsZV9uYW1lLCB0ZW5hbnRfaWQpDQopOw0KQ1JFQVRFIFRBQkxFIElGIE5PVCBFWElTVFMgcHJvZmlsZXMoDQogIHByb2ZpbGVfbmFtZSBjaXRleHQgTk9UIE5VTEwsDQogIGFjdGl2YXRpb24gdmFyY2hhcigyMCkgTk9UIE5VTEwsDQogIGFtdF9wYXNzd29yZCB2YXJjaGFyKDQwKSwNCiAgZ2VuZXJhdGVfcmFuZG9tX3Bhc3N3b3JkIEJPT0xFQU4gTk9UIE5VTEwsDQogIGNpcmFfY29uZmlnX25hbWUgY2l0ZXh0LA0KICBGT1JFSUdOIEtFWSAoY2lyYV9jb25maWdfbmFtZSx0ZW5hbnRfaWQpICBSRUZFUkVOQ0VTIGNpcmFjb25maWdzKGNpcmFfY29uZmlnX25hbWUsdGVuYW50X2lkKSwNCiAgY3JlYXRpb25fZGF0ZSB0aW1lc3RhbXAsDQogIGNyZWF0ZWRfYnkgdmFyY2hhcig0MCksDQogIG1lYnhfcGFzc3dvcmQgdmFyY2hhcig0MCksDQogIGdlbmVyYXRlX3JhbmRvbV9tZWJ4X3Bhc3N3b3JkIEJPT0xFQU4gTk9UIE5VTEwsDQogIHRhZ3MgdGV4dFtdLA0KICBkaGNwX2VuYWJsZWQgQk9PTEVBTiwNCiAgaXBfc3luY19lbmFibGVkIEJPT0xFQU4gTlVMTCwNCiAgbG9jYWxfd2lmaV9zeW5jX2VuYWJsZWQgQk9PTEVBTiBOVUxMLA0KICB0ZW5hbnRfaWQgdmFyY2hhcigzNikgTk9UIE5VTEwsDQogIHRsc19tb2RlIGludGVnZXIgTlVMTCwNCiAgdXNlcl9jb25zZW50IHZhcmNoYXIoNykgTlVMTCwNCiAgaWRlcl9lbmFibGVkIEJPT0xFQU4gTlVMTCwNCiAga3ZtX2VuYWJsZWQgQk9PTEVBTiBOVUxMLA0KICBzb2xfZW5hYmxlZCBCT09MRUFOIE5VTEwsDQogIHRsc19zaWduaW5nX2F1dGhvcml0eSB2YXJjaGFyKDQwKSBOVUxMLA0KICBpZWVlODAyMXhfcHJvZmlsZV9uYW1lIGNpdGV4dCwNCiAgRk9SRUlHTiBLRVkgKGllZWU4MDIxeF9wcm9maWxlX25hbWUsdGVuYW50X2lkKSAgUkVGRVJFTkNFUyBpZWVlODAyMXhjb25maWdzKHByb2ZpbGVfbmFtZSx0ZW5hbnRfaWQpLA0KICBQUklNQVJZIEtFWSAocHJvZmlsZV9uYW1lLCB0ZW5hbnRfaWQpDQopOw0KQ1JFQVRFIFRBQkxFIElGIE5PVCBFWElTVFMgcHJvZmlsZXNfd2lyZWxlc3Njb25maWdzKA0KICB3aXJlbGVzc19wcm9maWxlX25hbWUgY2l0ZXh0LA0KICBwcm9maWxlX25hbWUgY2l0ZXh0LA0KICBGT1JFSUdOIEtFWSAod2lyZWxlc3NfcHJvZmlsZV9uYW1lLHRlbmFudF9pZCkgIFJFRkVSRU5DRVMgd2lyZWxlc3Njb25maWdzKHdpcmVsZXNzX3Byb2ZpbGVfbmFtZSx0ZW5hbnRfaWQpLA0KICBGT1JFSUdOIEtFWSAocHJvZmlsZV9uYW1lLHRlbmFudF9pZCkgIFJFRkVSRU5DRVMgcHJvZmlsZXMocHJvZmlsZV9uYW1lLHRlbmFudF9pZCksDQogIHByaW9yaXR5IGludGVnZXIsDQogIGNyZWF0aW9uX2RhdGUgdGltZXN0YW1wLA0KICBjcmVhdGVkX2J5IHZhcmNoYXIoNDApLA0KICB0ZW5hbnRfaWQgdmFyY2hhcigzNikgTk9UIE5VTEwsDQogIFBSSU1BUlkgS0VZICh3aXJlbGVzc19wcm9maWxlX25hbWUsIHByb2ZpbGVfbmFtZSwgcHJpb3JpdHksIHRlbmFudF9pZCkNCik7DQpDUkVBVEUgVEFCTEUgSUYgTk9UIEVYSVNUUyBkb21haW5zKA0KICBuYW1lIGNpdGV4dCBOT1QgTlVMTCwNCiAgZG9tYWluX3N1ZmZpeCBjaXRleHQgTk9UIE5VTEwsDQogIHByb3Zpc2lvbmluZ19jZXJ0IHRleHQsDQogIHByb3Zpc2lvbmluZ19jZXJ0X3N0b3JhZ2VfZm9ybWF0IHZhcmNoYXIoNDApLA0KICBwcm92aXNpb25pbmdfY2VydF9rZXkgdGV4dCwNCiAgY3JlYXRpb25fZGF0ZSB0aW1lc3RhbXAsDQogIGV4cGlyYXRpb25fZGF0ZSB0aW1lc3RhbXAsDQogIGNyZWF0ZWRfYnkgdmFyY2hhcig0MCksDQogIHRlbmFudF9pZCB2YXJjaGFyKDM2KSBOT1QgTlVMTCwNCiAgQ09OU1RSQUlOVCBkb21haW5uYW1lIFVOSVFVRSAobmFtZSwgdGVuYW50X2lkKSwNCiAgQ09OU1RSQUlOVCBkb21haW5zdWZmaXggVU5JUVVFIChkb21haW5fc3VmZml4LCB0ZW5hbnRfaWQpLA0KICBQUklNQVJZIEtFWSAobmFtZSwgZG9tYWluX3N1ZmZpeCwgdGVuYW50X2lkKQ0KKTsNCkNSRUFURSBVTklRVUUgSU5ERVggbG93ZXJfbmFtZV9zdWZmaXhfaWR4IE9OIGRvbWFpbnMgKChsb3dlcihuYW1lKSksIChsb3dlcihkb21haW5fc3VmZml4KSkpOw0KQ1JFQVRFIERBVEFCQVNFIG1wc2RiOw0KDQpcY29ubmVjdCBtcHNkYg0KDQpDUkVBVEUgVEFCTEUgSUYgTk9UIEVYSVNUUyBkZXZpY2VzKA0KICAgICAgZ3VpZCB1dWlkIE5PVCBOVUxMLA0KICAgICAgdGFncyB0ZXh0W10sDQogICAgICBob3N0bmFtZSB2YXJjaGFyKDI1NiksDQogICAgICBtcHNpbnN0YW5jZSB0ZXh0LCANCiAgICAgIGNvbm5lY3Rpb25zdGF0dXMgYm9vbGVhbiwNCiAgICAgIG1wc3VzZXJuYW1lIHRleHQsDQogICAgICB0ZW5hbnRpZCB2YXJjaGFyKDM2KSBOT1QgTlVMTCwNCiAgICAgIGZyaWVuZGx5bmFtZSB2YXJjaGFyKDI1NiksDQogICAgICBkbnNzdWZmaXggdmFyY2hhcigyNTYpLA0KICAgICAgbGFzdGNvbm5lY3RlZCB0aW1lc3RhbXAgd2l0aCB0aW1lIHpvbmUsDQogICAgICBsYXN0c2VlbiB0aW1lc3RhbXAgd2l0aCB0aW1lIHpvbmUsDQogICAgICBsYXN0ZGlzY29ubmVjdGVkIHRpbWVzdGFtcCB3aXRoIHRpbWUgem9uZSwNCiAgICAgIGRldmljZWluZm8gSlNPTiwNCiAgICAgIENPTlNUUkFJTlQgZGV2aWNlX2d1aWQgVU5JUVVFKGd1aWQpLA0KICAgICAgUFJJTUFSWSBLRVkgKGd1aWQsdGVuYW50aWQpDQogICAgKTs=" 374 | } 375 | }, 376 | { 377 | "name": "nginx-config", 378 | "secret": { 379 | "nginx.conf": "c2VydmVyIHsNCiAgICBsaXN0ZW4gODAgZGVmYXVsdF9zZXJ2ZXI7DQogICAgbGlzdGVuIFs6Ol06ODAgZGVmYXVsdF9zZXJ2ZXI7DQogICAgc2VydmVyX25hbWUgXzsNCiANCg0KICAgIGxvY2F0aW9uIC8gew0KICAgICAgICByb290ICAgL3Vzci9zaGFyZS9uZ2lueC9odG1sOw0KICAgICAgICBpbmRleCAgaW5kZXguaHRtbCBpbmRleC5odG07DQogICAgfQ0KDQogICAgZXJyb3JfcGFnZSAgNDA0ICAgICAgICAgICAgICAvaW5kZXguaHRtbDsNCg0KICAgICMgcmVkaXJlY3Qgc2VydmVyIGVycm9yIHBhZ2VzIHRvIHRoZSBzdGF0aWMgcGFnZSAvNTB4Lmh0bWwNCiAgICAjDQogICAgZXJyb3JfcGFnZSAgIDUwMCA1MDIgNTAzIDUwNCAgLzUweC5odG1sOw0KICAgIGxvY2F0aW9uID0gLzUweC5odG1sIHsNCiAgICAgICAgcm9vdCAgIC91c3Ivc2hhcmUvbmdpbngvaHRtbDsNCiAgICB9DQp9DQoNCg==" 380 | } 381 | }, 382 | { 383 | "name": "kong-config", 384 | "secret": { 385 | "kong.yaml": "X2Zvcm1hdF92ZXJzaW9uOiAiMi4xIgpfdHJhbnNmb3JtOiB0cnVlCgpzZXJ2aWNlczoKLSBuYW1lOiBtcHMtcmVzdAogIGhvc3Q6IDEyNy4wLjAuMQogIHBvcnQ6IDMwMDAKICB0YWdzOgogIC0gbXBzCiAgcm91dGVzOgogIC0gbmFtZTogbXBzLXJvdXRlCiAgICBzdHJpcF9wYXRoOiB0cnVlCiAgICBwYXRoczoKICAgIC0gL21wcwoKLSBuYW1lOiBtcHMtcmVzdC12MgogIGhvc3Q6IDEyNy4wLjAuMQogIHBvcnQ6IDMwMDAKICBwYXRoOiAvYXBpL3YxL2F1dGhvcml6ZQogIHRhZ3M6CiAgLSBtcHMKICByb3V0ZXM6CiAgLSBuYW1lOiBtcHMtbG9naW4tcm91dGUKICAgIHN0cmlwX3BhdGg6IHRydWUKICAgIHBhdGhzOgogICAgLSAvbXBzL2xvZ2luL2FwaS92MS9hdXRob3JpemUKCi0gbmFtZTogbXBzLXJlZGlyZWN0aW9uCiAgaG9zdDogMTI3LjAuMC4xCiAgcG9ydDogMzAwMAogIHBhdGg6IC9yZWxheQogIHRhZ3M6CiAgLSBtcHMKICByb3V0ZXM6CiAgLSBuYW1lOiBtcHMtcmVkaXJlY3Rpb24tcm91dGUKICAgIHN0cmlwX3BhdGg6IHRydWUKICAgIHBhdGhzOgogICAgLSAvbXBzL3dzL3JlbGF5CgotIG5hbWU6IHJwcy1yZXN0CiAgaG9zdDogMTI3LjAuMC4xCiAgcG9ydDogODA4MSAgCiAgdGFnczoKICAtIHJwcwogIHJvdXRlczoKICAtIG5hbWU6IHJwcy1yb3V0ZQogICAgc3RyaXBfcGF0aDogdHJ1ZQogICAgcGF0aHM6CiAgICAtIC9ycHMKCi0gbmFtZTogcnBzLXdzCiAgaG9zdDogMTI3LjAuMC4xCiAgcG9ydDogODA4MAogIHRhZ3M6CiAgLSBycHMKICByb3V0ZXM6CiAgLSBuYW1lOiBycHMtYWN0aXZhdGUtcm91dGUKICAgIHN0cmlwX3BhdGg6IHRydWUKICAgIHBhdGhzOgogICAgLSAvYWN0aXZhdGUKICAtIG5hbWU6IHJwcy1kZWFjdGl2YXRlLXJvdXRlCiAgICBzdHJpcF9wYXRoOiB0cnVlCiAgICBwYXRoczoKICAgIC0gL2RlYWN0aXZhdGUKICAtIG5hbWU6IHJwcy1tYWludGVuYW5jZS1yb3V0ZQogICAgc3RyaXBfcGF0aDogdHJ1ZQogICAgcGF0aHM6CiAgICAtIC9tYWludGVuYW5jZQoKLSBuYW1lOiB2YXVsdC1hcGkKICBob3N0OiAxMjcuMC4wLjEKICBwb3J0OiA4MjAwIAogIHRhZ3M6CiAgLSB2YXVsdAogIHJvdXRlczoKICAtIG5hbWU6IHZhdWx0LXJvdXRlCiAgICBzdHJpcF9wYXRoOiB0cnVlCiAgICBwYXRoczoKICAgIC0gL3ZhdWx0CgotIG5hbWU6IG1vc3F1aXR0by13cwogIGhvc3Q6IDEyNy4wLjAuMQogIHBvcnQ6IDkwMDEKICB0YWdzOgogIC0gbW9zcXVpdHRvCiAgcm91dGVzOgogIC0gbmFtZTogbW9zcXVpdHRvLXJvdXRlCiAgICBzdHJpcF9wYXRoOiB0cnVlCiAgICBwYXRoczoKICAgIC0gL21vc3F1aXR0bwoKLSBuYW1lOiB3ZWIKICBob3N0OiAxMjcuMC4wLjEKICBwb3J0OiA4MAogIHRhZ3M6CiAgLSB3ZWIKICByb3V0ZXM6CiAgLSBuYW1lOiB3ZWItcm91dGUKICAgIHBhdGhzOgogICAgLSAvCgpwbHVnaW5zOgotIG5hbWU6IGNvcnMgCi0gbmFtZTogand0CiAgcm91dGU6IHJwcy1yb3V0ZQogIGNvbmZpZzoKICAgIGNsYWltc190b192ZXJpZnk6CiAgICAtIGV4cAotIG5hbWU6IGp3dAogIHJvdXRlOiBtcHMtcm91dGUKICBjb25maWc6CiAgICBjbGFpbXNfdG9fdmVyaWZ5OgogICAgLSBleHAKCmNvbnN1bWVyczoKICAtIHVzZXJuYW1lOiBhZG1pbgpqd3Rfc2VjcmV0czoKICAtIGNvbnN1bWVyOiBhZG1pbgogICAga2V5OiA5RW1SSlRiSWlJYjRiSWVTc21nY1dJanJSNkh5RVRxYyAjc2FtcGxlIGtleQogICAgc2VjcmV0OiAic3VwZXJzZWNyZXQiCg==" 386 | } 387 | }, 388 | { 389 | "name": "private", 390 | "emptyDir": {} 391 | } 392 | ] 393 | } 394 | } 395 | ] 396 | } -------------------------------------------------------------------------------- /build.ps1: -------------------------------------------------------------------------------- 1 | $ip = Read-Host "Please enter your IP Address" 2 | ((Get-Content ./mps/.mpsrc) -replace('"common_name":.*"',('"common_name": "' + $ip + '"'))) | Set-Content ./mps/.mpsrc 3 | ((Get-Content ./sample-web-ui/src/environments/environment.ts) -replace('mpsServer:.*',('mpsServer: "https://' + $ip + ':3000",'))) | Set-Content ./sample-web-ui/src/environments/environment.ts 4 | ((Get-Content ./sample-web-ui/src/environments/environment.ts) -replace('rpsServer:.*',('rpsServer: "https://' + $ip + ':8081",'))) | Set-Content ./sample-web-ui/src/environments/environment.ts 5 | 6 | cd ./mps 7 | npm install 8 | cd ../rps 9 | npm install 10 | cd ../sample-web-ui 11 | npm install 12 | cd .. -------------------------------------------------------------------------------- /data/init.sql: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Copyright (c) Intel Corporation 2020 3 | * SPDX-License-Identifier: Apache-2.0 4 | **********************************************************************/ 5 | SELECT 'CREATE DATABASE rpsdb' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'rpsdb')\gexec 6 | 7 | \connect rpsdb 8 | 9 | CREATE EXTENSION IF NOT EXISTS citext; 10 | 11 | CREATE TABLE IF NOT EXISTS ciraconfigs( 12 | cira_config_name citext NOT NULL, 13 | mps_server_address varchar(256), 14 | mps_port integer, 15 | user_name varchar(40), 16 | password varchar(63), 17 | common_name varchar(256), 18 | server_address_format integer, 19 | auth_method integer, 20 | mps_root_certificate text, 21 | proxydetails text, 22 | tenant_id varchar(36) NOT NULL, 23 | PRIMARY KEY (cira_config_name, tenant_id) 24 | ); 25 | CREATE TABLE IF NOT EXISTS ieee8021xconfigs( 26 | profile_name citext, 27 | auth_protocol integer, 28 | servername VARCHAR(255), 29 | domain VARCHAR(255), 30 | username VARCHAR(255), 31 | password VARCHAR(255), 32 | roaming_identity VARCHAR(255), 33 | active_in_s0 BOOLEAN, 34 | pxe_timeout integer, 35 | wired_interface BOOLEAN NOT NULL, 36 | tenant_id varchar(36) NOT NULL, 37 | PRIMARY KEY (profile_name, tenant_id) 38 | ); 39 | CREATE TABLE IF NOT EXISTS wirelessconfigs( 40 | wireless_profile_name citext NOT NULL, 41 | authentication_method integer, 42 | encryption_method integer, 43 | ssid varchar(32), 44 | psk_value integer, 45 | psk_passphrase varchar(63), 46 | link_policy int[], 47 | creation_date timestamp, 48 | created_by varchar(40), 49 | tenant_id varchar(36) NOT NULL, 50 | ieee8021x_profile_name citext, 51 | FOREIGN KEY (ieee8021x_profile_name,tenant_id) REFERENCES ieee8021xconfigs(profile_name,tenant_id), 52 | PRIMARY KEY (wireless_profile_name, tenant_id) 53 | ); 54 | CREATE TABLE IF NOT EXISTS profiles( 55 | profile_name citext NOT NULL, 56 | activation varchar(20) NOT NULL, 57 | amt_password varchar(40), 58 | generate_random_password BOOLEAN NOT NULL, 59 | cira_config_name citext, 60 | FOREIGN KEY (cira_config_name,tenant_id) REFERENCES ciraconfigs(cira_config_name,tenant_id), 61 | creation_date timestamp, 62 | created_by varchar(40), 63 | mebx_password varchar(40), 64 | generate_random_mebx_password BOOLEAN NOT NULL, 65 | tags text[], 66 | dhcp_enabled BOOLEAN, 67 | ip_sync_enabled BOOLEAN NULL, 68 | local_wifi_sync_enabled BOOLEAN NULL, 69 | tenant_id varchar(36) NOT NULL, 70 | tls_mode integer NULL, 71 | user_consent varchar(7) NULL, 72 | ider_enabled BOOLEAN NULL, 73 | kvm_enabled BOOLEAN NULL, 74 | sol_enabled BOOLEAN NULL, 75 | tls_signing_authority varchar(40) NULL, 76 | ieee8021x_profile_name citext, 77 | FOREIGN KEY (ieee8021x_profile_name,tenant_id) REFERENCES ieee8021xconfigs(profile_name,tenant_id), 78 | PRIMARY KEY (profile_name, tenant_id) 79 | ); 80 | CREATE TABLE IF NOT EXISTS profiles_wirelessconfigs( 81 | wireless_profile_name citext, 82 | profile_name citext, 83 | FOREIGN KEY (wireless_profile_name,tenant_id) REFERENCES wirelessconfigs(wireless_profile_name,tenant_id), 84 | FOREIGN KEY (profile_name,tenant_id) REFERENCES profiles(profile_name,tenant_id), 85 | priority integer, 86 | creation_date timestamp, 87 | created_by varchar(40), 88 | tenant_id varchar(36) NOT NULL, 89 | PRIMARY KEY (wireless_profile_name, profile_name, priority, tenant_id) 90 | ); 91 | CREATE TABLE IF NOT EXISTS domains( 92 | name citext NOT NULL, 93 | domain_suffix citext NOT NULL, 94 | provisioning_cert text, 95 | provisioning_cert_storage_format varchar(40), 96 | provisioning_cert_key text, 97 | creation_date timestamp, 98 | expiration_date timestamp, 99 | created_by varchar(40), 100 | tenant_id varchar(36) NOT NULL, 101 | CONSTRAINT domainname UNIQUE (name, tenant_id), 102 | CONSTRAINT domainsuffix UNIQUE (domain_suffix, tenant_id), 103 | PRIMARY KEY (name, domain_suffix, tenant_id) 104 | ); 105 | 106 | -------------------------------------------------------------------------------- /data/initMPS.sql: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Copyright (c) Intel Corporation 2021 3 | * SPDX-License-Identifier: Apache-2.0 4 | **********************************************************************/ 5 | SELECT 'CREATE DATABASE mpsdb' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'mpsdb')\gexec 6 | 7 | \connect mpsdb 8 | 9 | CREATE TABLE IF NOT EXISTS devices( 10 | guid uuid NOT NULL, 11 | tags text[], 12 | hostname varchar(256), 13 | mpsinstance text, 14 | connectionstatus boolean, 15 | mpsusername text, 16 | tenantid varchar(36) NOT NULL, 17 | friendlyname varchar(256), 18 | dnssuffix varchar(256), 19 | lastconnected timestamp with time zone, 20 | lastseen timestamp with time zone, 21 | lastdisconnected timestamp with time zone, 22 | deviceinfo JSON, 23 | CONSTRAINT device_guid UNIQUE(guid), 24 | PRIMARY KEY (guid, tenantid) 25 | ); 26 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | #/********************************************************************* 2 | # Copyright (c) Intel Corporation 2020 3 | # SPDX-License-Identifier: Apache-2.0 4 | #**********************************************************************/ 5 | name: device-management-toolkit 6 | 7 | services: 8 | webui: 9 | restart: always 10 | image: intel/oact-webui:latest 11 | networks: 12 | - openamtnetwork 13 | build: 14 | context: ./sample-web-ui 15 | dockerfile: ./Dockerfile 16 | environment: 17 | RPS_SERVER: https://${MPS_COMMON_NAME}/rps 18 | MPS_SERVER: https://${MPS_COMMON_NAME}/mps 19 | VAULT_SERVER: https://${MPS_COMMON_NAME}/vault 20 | volumes: 21 | - ./nginx.conf:/etc/nginx/conf.d/default.conf 22 | rps: 23 | restart: always 24 | image: intel/oact-rps:latest 25 | networks: 26 | - openamtnetwork 27 | build: 28 | context: ./rps 29 | dockerfile: ./Dockerfile 30 | env_file: 31 | - .env 32 | healthcheck: 33 | interval: 12s 34 | timeout: 12s 35 | retries: 3 36 | test: ["CMD", "node", "rps/dist/Healthcheck.js"] 37 | environment: 38 | RPS_MPS_SERVER: http://mps:3000 39 | RPS_SECRETS_PATH: ${SECRETS_PATH} 40 | RPS_VAULT_TOKEN: ${VAULT_TOKEN} 41 | RPS_VAULT_ADDRESS: ${VAULT_ADDRESS} 42 | RPS_CONNECTION_STRING: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/rpsdb 43 | RPS_CONSUL_ENABLED: ${CONSUL_ENABLED} 44 | RPS_CONSUL_HOST: ${CONSUL_HOST} 45 | RPS_CONSUL_PORT: ${CONSUL_PORT} 46 | mps: 47 | restart: always 48 | image: intel/oact-mps:latest 49 | networks: 50 | - openamtnetwork 51 | build: 52 | context: ./mps 53 | dockerfile: ./Dockerfile 54 | ports: 55 | - "${MPSPORT}:4433" 56 | env_file: 57 | - .env 58 | healthcheck: 59 | interval: 12s 60 | timeout: 12s 61 | retries: 3 62 | test: ["CMD", "node", "mps/dist/Healthcheck.js"] 63 | environment: 64 | MPS_INSTANCE_NAME: '{{.Task.Name}}' 65 | MPS_SECRETS_PATH: ${SECRETS_PATH} 66 | MPS_VAULT_TOKEN: ${VAULT_TOKEN} 67 | MPS_VAULT_ADDRESS: ${VAULT_ADDRESS} 68 | MPS_CONNECTION_STRING: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/mpsdb 69 | MPS_CONSUL_ENABLED: ${CONSUL_ENABLED} 70 | MPS_CONSUL_HOST: ${CONSUL_HOST} 71 | MPS_CONSUL_PORT: ${CONSUL_PORT} 72 | volumes: 73 | - private-volume:/mps-microservice/private 74 | mpsrouter: 75 | restart: always 76 | image: intel/oact-mpsrouter:latest 77 | environment: 78 | MPS_CONNECTION_STRING: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/mpsdb?sslmode=disable 79 | PORT: ${PORT} 80 | MPS_PORT: ${MPSWEBPORT} 81 | healthcheck: 82 | interval: 12s 83 | timeout: 12s 84 | retries: 3 85 | test: ["CMD", "/app","--health"] 86 | build: 87 | context: ./mps-router 88 | dockerfile: ./Dockerfile 89 | networks: 90 | - openamtnetwork 91 | db: 92 | restart: always 93 | image: postgres:17 94 | build: 95 | context: ./pg 96 | dockerfile: ./Dockerfile 97 | # command: -c ssl=on -c ssl_cert_file=/var/lib/postgresql/server.crt -c ssl_key_file=/var/lib/postgresql/server.key 98 | networks: 99 | - openamtnetwork 100 | healthcheck: 101 | test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d rpsdb"] 102 | interval: 2s 103 | timeout: 3s 104 | retries: 30 105 | environment: 106 | POSTGRES_DB: rpsdb 107 | POSTGRES_USER: ${POSTGRES_USER} 108 | POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} 109 | ports: 110 | - 5432:5432 111 | volumes: 112 | - ./data:/docker-entrypoint-initdb.d 113 | vault: 114 | restart: always 115 | image: hashicorp/vault 116 | networks: 117 | - openamtnetwork 118 | ports: 119 | - 8200:8200 120 | environment: 121 | VAULT_DEV_ROOT_TOKEN_ID: ${VAULT_TOKEN} 122 | VAULT_DEV_LISTEN_ADDRESS: 0.0.0.0:8200 123 | cap_add: 124 | - IPC_LOCK 125 | consul: 126 | restart: always 127 | image: hashicorp/consul 128 | networks: 129 | - openamtnetwork 130 | ports: 131 | - 8500:8500 132 | profiles: 133 | - consul 134 | volumes: 135 | - type: volume 136 | source: consul-config 137 | target: /consul/config 138 | volume: {} 139 | - type: volume 140 | source: consul-data 141 | target: /consul/data 142 | volume: {} 143 | command: "agent -server -ui -node=OACT-1 -bootstrap-expect=1 -client=0.0.0.0" 144 | kong: 145 | restart: always 146 | image: kong:3.1 147 | healthcheck: 148 | test: ["CMD", "kong", "health"] 149 | interval: 10s 150 | timeout: 10s 151 | retries: 10 152 | command: 153 | - "kong" 154 | - "start" 155 | - "--vv" 156 | environment: 157 | - KONG_DATABASE=off 158 | - KONG_CASSANDRA_CONTACT_POINTS=kong-database 159 | - KONG_ADMIN_LISTEN=0.0.0.0:8001 160 | - KONG_ADMIN_LISTEN_SSL=0.0.0.0:8444 161 | - KONG_NGINX_DAEMON=off 162 | - KONG_DECLARATIVE_CONFIG=/home/kong/kong.yml 163 | - KONG_PROXY_ERROR_LOG=/dev/stderr 164 | - KONG_PROXY_ACCESS_LOG=/dev/stdout 165 | - KONG_ADMIN_ACCESS_LOG=/dev/stdout 166 | - KONG_ADMIN_ERROR_LOG=/dev/stderr 167 | - KONG_DNS_ORDER=LAST,A,CNAME 168 | - KONG_UPSTREAM_KEEPALIVE_POOL_SIZE=0 169 | networks: 170 | - openamtnetwork 171 | volumes: 172 | - ./kong.yaml:/home/kong/kong.yml 173 | ports: 174 | - 443:8443 175 | - 8001:8001 176 | mosquitto: 177 | restart: always 178 | image: eclipse-mosquitto 179 | ports: 180 | - 8883:8883 181 | volumes: 182 | - ./mosquitto.conf:/mosquitto/config/mosquitto.conf 183 | networks: 184 | - openamtnetwork 185 | profiles: 186 | - "mqtt" 187 | volumes: 188 | app-volume: 189 | private-volume: 190 | consul-config: 191 | consul-data: 192 | networks: 193 | openamtnetwork: 194 | driver: "bridge" 195 | -------------------------------------------------------------------------------- /kong.conf: -------------------------------------------------------------------------------- 1 | dns_order = LAST,A,CNAME -------------------------------------------------------------------------------- /kong.yaml: -------------------------------------------------------------------------------- 1 | #********************************************************************* 2 | # Copyright (c) Intel Corporation 2018-2019 3 | # SPDX-License-Identifier: Apache-2.0 4 | #********************************************************************* 5 | 6 | # Metadata fields start with an underscore (_) 7 | # Fields that do not start with an underscore represent Kong entities and attributes 8 | 9 | # _format_version is mandatory, 10 | # it specifies the minimum version of Kong that supports the format 11 | 12 | _format_version: "2.1" 13 | 14 | # _transform is optional, defaulting to true. 15 | # It specifies whether schema transformations should be applied when importing this file 16 | # as a rule of thumb, leave this setting to true if you are importing credentials 17 | # with plain passwords, which need to be encrypted/hashed before storing on the database. 18 | # On the other hand, if you are reimporting a database with passwords already encrypted/hashed, 19 | # set it to false. 20 | 21 | _transform: true 22 | 23 | # Each Kong entity (core entity or custom entity introduced by a plugin) 24 | # can be listed in the top-level as an array of objects: 25 | 26 | services: 27 | - name: mps-rest 28 | host: mpsrouter 29 | port: 8003 30 | tags: 31 | - mps 32 | routes: 33 | - name: mps-route 34 | strip_path: true 35 | paths: 36 | - /mps 37 | - name: device-power-state-route 38 | strip_path: true 39 | paths: 40 | - /device/power/state/(?[a-fA-F0-9\-]+) 41 | - name: device-power-action-route 42 | strip_path: true 43 | paths: 44 | - /device/power/action/(?[a-fA-F0-9\-]+) 45 | 46 | 47 | - name: mps-redirection 48 | host: mps 49 | port: 3000 50 | path: /relay 51 | tags: 52 | - mps 53 | routes: 54 | - name: mps-redirection-route 55 | strip_path: true 56 | paths: 57 | - /mps/ws/relay 58 | 59 | 60 | - name: mps-rest-v2 61 | host: mps 62 | port: 3000 63 | path: /api/v1/authorize 64 | tags: 65 | - mps 66 | routes: 67 | - name: mps-login-route 68 | strip_path: true 69 | paths: 70 | - /mps/login/api/v1/authorize 71 | 72 | - name: rps-rest 73 | host: rps 74 | port: 8081 75 | tags: 76 | - rps 77 | routes: 78 | - name: rps-route 79 | strip_path: true 80 | paths: 81 | - /rps 82 | 83 | - name: rps-ws 84 | host: rps 85 | port: 8080 86 | tags: 87 | - rps 88 | routes: 89 | - name: rps-activate-route 90 | strip_path: true 91 | paths: 92 | - /activate 93 | - name: rps-deactivate-route 94 | strip_path: true 95 | paths: 96 | - /deactivate 97 | - name: rps-maintenance-route 98 | strip_path: true 99 | paths: 100 | - /maintenance 101 | 102 | # uncomment to use with enterprise assistant 103 | # - name: rps-ea 104 | # host: rps 105 | # port: 8082 106 | # tags: 107 | # - rps 108 | # routes: 109 | # - name: rps-ea-route 110 | # strip_path: true 111 | # paths: 112 | # - /ea 113 | 114 | - name: vault-api 115 | host: vault 116 | port: 8200 117 | tags: 118 | - vault 119 | routes: 120 | - name: vault-route 121 | strip_path: true 122 | paths: 123 | - /vault 124 | 125 | - name: mosquitto-ws 126 | host: mosquitto 127 | port: 9001 128 | tags: 129 | - mosquitto 130 | routes: 131 | - name: mosquitto-route 132 | strip_path: true 133 | paths: 134 | - /mosquitto 135 | 136 | - name: web 137 | host: webui 138 | port: 80 139 | tags: 140 | - web 141 | routes: 142 | - name: web-route 143 | paths: 144 | - / 145 | 146 | plugins: 147 | - name: cors 148 | - name: jwt 149 | route: rps-route 150 | config: 151 | claims_to_verify: 152 | - exp 153 | - name: jwt 154 | service: mps-rest 155 | config: 156 | claims_to_verify: 157 | - exp 158 | 159 | - name: request-transformer 160 | route: device-power-state-route 161 | config: 162 | replace: 163 | uri: "/api/v1/amt/power/state/$(uri_captures['id'])" 164 | - name: request-transformer 165 | route: device-power-action-route 166 | config: 167 | replace: 168 | uri: "/api/v1/amt/power/action/$(uri_captures['id'])" 169 | 170 | consumers: 171 | - username: admin 172 | jwt_secrets: 173 | - consumer: admin 174 | key: 9EmRJTbIiIb4bIeSsmgcWIjrR6HyETqc #sample key 175 | secret: 176 | 177 | 178 | 179 | # routes: 180 | # - name: another-route 181 | # # Relationships can also be specified between top-level entities, 182 | # # either by name or by id 183 | # service: example-service 184 | # hosts: ["hello.com"] 185 | 186 | # consumers: 187 | # - username: example-user 188 | # # Custom entities from plugin can also be specified 189 | # # If they specify a foreign-key relationshp, they can also be nested 190 | # keyauth_credentials: 191 | # - key: my-key 192 | # plugins: 193 | # - name: rate-limiting 194 | # _comment: "these are default rate-limits for user example-user" 195 | # config: 196 | # policy: local 197 | # second: 5 198 | # hour: 10000 199 | 200 | # When an entity has multiple foreign-key relationships 201 | # (e.g. a plugin matching on both consumer and service) 202 | # it must be specified as a top-level entity, and not through 203 | # nesting. 204 | 205 | # plugins: 206 | # - name: rate-limiting 207 | # consumer: example-user 208 | # service: another-service 209 | # _comment: "example-user is extra limited when using another-service" 210 | # config: 211 | # hour: 2 212 | # # tags are for your organization only and have no meaning for Kong: 213 | # tags: 214 | # - extra_limits 215 | # - my_tag 216 | -------------------------------------------------------------------------------- /kubernetes/charts/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | .vscode/ 23 | -------------------------------------------------------------------------------- /kubernetes/charts/Chart.lock: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - name: vault 3 | repository: https://helm.releases.hashicorp.com 4 | version: 0.28.0 5 | - name: kong 6 | repository: https://charts.konghq.com 7 | version: 2.39.3 8 | digest: sha256:07824e8583d5b834eec0615f81623c27bd598f77b036401158020136f5fbd8f6 9 | generated: "2024-07-10T13:06:41.2849165-07:00" 10 | -------------------------------------------------------------------------------- /kubernetes/charts/Chart.yaml: -------------------------------------------------------------------------------- 1 | #/********************************************************************* 2 | # Copyright (c) Intel Corporation 2020 3 | # SPDX-License-Identifier: Apache-2.0 4 | #**********************************************************************/ 5 | apiVersion: v2 6 | name: Chart to install MPS, RPS and Backend db 7 | description: A Helm chart for Kubernetes 8 | 9 | # A chart can be either an 'application' or a 'library' chart. 10 | # 11 | # Application charts are a collection of templates that can be packaged into versioned archives 12 | # to be deployed. 13 | # 14 | # Library charts provide useful utilities or functions for the chart developer. They're included as 15 | # a dependency of application charts to inject those utilities and functions into the rendering 16 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 17 | type: application 18 | 19 | # This is the chart version. This version number should be incremented each time you make changes 20 | # to the chart and its templates, including the app version. 21 | version: 1.0.0 22 | 23 | # This is the version number of the application being deployed. This version number should be 24 | # incremented each time you make changes to the application. 25 | appVersion: 1.4.0 26 | 27 | dependencies: 28 | - name: vault 29 | version: "^0.28.0" 30 | repository: https://helm.releases.hashicorp.com 31 | 32 | - name: kong 33 | version: "^2.39.3" 34 | repository: https://charts.konghq.com 35 | -------------------------------------------------------------------------------- /kubernetes/charts/charts/kong-2.39.3.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/device-management-toolkit/cloud-deployment/02835de32c3a6c38e313a3b4c102e493e1e05456/kubernetes/charts/charts/kong-2.39.3.tgz -------------------------------------------------------------------------------- /kubernetes/charts/charts/vault-0.28.0.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/device-management-toolkit/cloud-deployment/02835de32c3a6c38e313a3b4c102e493e1e05456/kubernetes/charts/charts/vault-0.28.0.tgz -------------------------------------------------------------------------------- /kubernetes/charts/secrets.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: mpsweb 5 | type: Opaque 6 | stringData: 7 | user: 8 | password: 9 | --- 10 | apiVersion: v1 11 | kind: Secret 12 | metadata: 13 | name: rps 14 | type: Opaque 15 | stringData: 16 | connectionString: postgresql://:@:5432/rpsdb?sslmode= 17 | --- 18 | apiVersion: v1 19 | kind: Secret 20 | metadata: 21 | name: mps 22 | type: Opaque 23 | stringData: 24 | connectionString: postgresql://:@:5432/mpsdb?sslmode= 25 | --- 26 | apiVersion: v1 27 | kind: Secret 28 | metadata: 29 | name: mpsrouter 30 | type: Opaque 31 | stringData: 32 | connectionString: postgresql://:@:5432/mpsdb?sslmode= 33 | --- 34 | apiVersion: v1 35 | kind: Secret 36 | metadata: 37 | name: open-amt-admin-jwt 38 | labels: 39 | konghq.com/credential: jwt 40 | type: Opaque 41 | stringData: 42 | kongCredType: jwt 43 | key: admin-issuer 44 | algorithm: HS256 45 | secret: 46 | --- 47 | apiVersion: v1 48 | kind: Secret 49 | metadata: 50 | name: open-amt-admin-acl 51 | labels: 52 | konghq.com/credential: acl 53 | type: Opaque 54 | stringData: 55 | kongCredType: acl 56 | group: open-amt-admin 57 | --- 58 | apiVersion: v1 59 | kind: Secret 60 | metadata: 61 | name: vault 62 | labels: 63 | app: vault 64 | type: Opaque 65 | stringData: 66 | vaultKey: 67 | --- -------------------------------------------------------------------------------- /kubernetes/charts/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "installServersChart.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | If release name contains chart name it will be used as a full name. 13 | */}} 14 | {{- define "installServersChart.fullname" -}} 15 | {{- if .Values.fullnameOverride -}} 16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} 17 | {{- else -}} 18 | {{- $name := default .Chart.Name .Values.nameOverride -}} 19 | {{- if contains $name .Release.Name -}} 20 | {{- .Release.Name | trunc 63 | trimSuffix "-" -}} 21 | {{- else -}} 22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 23 | {{- end -}} 24 | {{- end -}} 25 | {{- end -}} 26 | 27 | {{/* 28 | Create chart name and version as used by the chart label. 29 | */}} 30 | {{- define "installServersChart.chart" -}} 31 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} 32 | {{- end -}} 33 | 34 | {{/* 35 | Common labels 36 | */}} 37 | {{- define "installServersChart.labels" -}} 38 | helm.sh/chart: {{ include "installServersChart.chart" . }} 39 | {{ include "installServersChart.selectorLabels" . }} 40 | {{- if .Chart.AppVersion }} 41 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 42 | {{- end }} 43 | app.kubernetes.io/managed-by: {{ .Release.Service }} 44 | {{- end -}} 45 | 46 | {{/* 47 | Selector labels 48 | */}} 49 | {{- define "installServersChart.selectorLabels" -}} 50 | app.kubernetes.io/name: {{ include "installServersChart.name" . }} 51 | app.kubernetes.io/instance: {{ .Release.Name }} 52 | {{- end -}} 53 | 54 | {{/* 55 | Create the name of the service account to use 56 | */}} 57 | {{- define "installServersChart.serviceAccountName" -}} 58 | {{- if .Values.serviceAccount.create -}} 59 | {{ default (include "installServersChart.fullname" .) .Values.serviceAccount.name }} 60 | {{- else -}} 61 | {{ default "default" .Values.serviceAccount.name }} 62 | {{- end -}} 63 | {{- end -}} 64 | -------------------------------------------------------------------------------- /kubernetes/charts/templates/kong.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: web-mps 5 | namespace: default 6 | annotations: 7 | konghq.com/strip-path: "true" 8 | konghq.com/plugins: open-amt-cors 9 | spec: 10 | ingressClassName: kong 11 | rules: 12 | - http: 13 | paths: 14 | - path: / 15 | pathType: Prefix 16 | backend: 17 | service: 18 | name: webui 19 | port: 20 | number: 80 21 | - path: /activate 22 | pathType: Prefix 23 | backend: 24 | service: 25 | name: rps 26 | port: 27 | number: 8080 28 | - path: /deactivate 29 | pathType: Prefix 30 | backend: 31 | service: 32 | name: rps 33 | port: 34 | number: 8080 35 | - path: /maintenance 36 | pathType: Prefix 37 | backend: 38 | service: 39 | name: rps 40 | port: 41 | number: 8080 42 | --- 43 | apiVersion: networking.k8s.io/v1 44 | kind: Ingress 45 | metadata: 46 | name: web-mps-login 47 | namespace: default 48 | annotations: 49 | konghq.com/strip-path: "true" 50 | konghq.com/plugins: open-amt-cors,api-login-rewrite 51 | spec: 52 | ingressClassName: kong 53 | rules: 54 | - http: 55 | paths: 56 | - path: /mps/login/api/v1/authorize 57 | pathType: Exact 58 | backend: 59 | service: 60 | name: mps 61 | port: 62 | number: 3000 63 | --- 64 | apiVersion: configuration.konghq.com/v1 65 | kind: KongPlugin 66 | metadata: 67 | name: api-login-rewrite 68 | config: 69 | replace: 70 | uri: "/api/v1/authorize" 71 | plugin: request-transformer 72 | --- 73 | apiVersion: networking.k8s.io/v1 74 | kind: Ingress 75 | metadata: 76 | name: mps-redirection 77 | namespace: default 78 | annotations: 79 | konghq.com/strip-path: "true" 80 | konghq.com/plugins: open-amt-cors,mps-redirection-rewrite 81 | spec: 82 | ingressClassName: kong 83 | rules: 84 | - http: 85 | paths: 86 | - path: /mps/ws/relay/(.*) 87 | pathType: Prefix 88 | backend: 89 | service: 90 | name: mpsrouter 91 | port: 92 | number: 8003 93 | --- 94 | apiVersion: configuration.konghq.com/v1 95 | kind: KongPlugin 96 | metadata: 97 | name: mps-redirection-rewrite 98 | config: 99 | replace: 100 | uri: "/relay/$(uri_captures[1])" 101 | plugin: request-transformer 102 | --- 103 | apiVersion: networking.k8s.io/v1 104 | kind: Ingress 105 | metadata: 106 | name: rps 107 | namespace: default 108 | annotations: 109 | konghq.com/strip-path: "true" 110 | konghq.com/plugins: open-amt-jwt, open-amt-cors,admin-acl 111 | spec: 112 | ingressClassName: kong 113 | rules: 114 | - http: 115 | paths: 116 | - path: /rps 117 | pathType: Prefix 118 | backend: 119 | service: 120 | name: rps 121 | port: 122 | number: 8081 123 | --- 124 | apiVersion: networking.k8s.io/v1 125 | kind: Ingress 126 | metadata: 127 | name: mps 128 | namespace: default 129 | annotations: 130 | konghq.com/strip-path: "true" 131 | konghq.com/plugins: open-amt-jwt,open-amt-cors, admin-acl 132 | spec: 133 | ingressClassName: kong 134 | rules: 135 | - http: 136 | paths: 137 | - path: /mps 138 | pathType: Prefix 139 | backend: 140 | service: 141 | name: mpsrouter 142 | port: 143 | number: 8003 144 | --- 145 | apiVersion: configuration.konghq.com/v1beta1 146 | kind: TCPIngress 147 | metadata: 148 | name: cira-ingress 149 | annotations: 150 | kubernetes.io/ingress.class: kong 151 | spec: 152 | rules: 153 | - port: 4433 154 | backend: 155 | serviceName: mps 156 | servicePort: 4433 157 | --- 158 | apiVersion: configuration.konghq.com/v1 159 | kind: KongPlugin 160 | metadata: 161 | name: open-amt-jwt 162 | plugin: jwt 163 | config: 164 | claims_to_verify: 165 | - exp 166 | --- 167 | apiVersion: configuration.konghq.com/v1 168 | kind: KongPlugin 169 | metadata: 170 | name: open-amt-cors 171 | plugin: cors 172 | --- 173 | apiVersion: configuration.konghq.com/v1 174 | kind: KongConsumer 175 | metadata: 176 | name: admin 177 | annotations: 178 | kubernetes.io/ingress.class: kong 179 | username: admin 180 | credentials: 181 | - open-amt-admin-jwt 182 | - open-amt-admin-acl 183 | --- 184 | apiVersion: configuration.konghq.com/v1 185 | kind: KongPlugin 186 | metadata: 187 | name: admin-acl 188 | plugin: acl 189 | config: 190 | allow: ["open-amt-admin"] 191 | -------------------------------------------------------------------------------- /kubernetes/charts/templates/mps.yaml: -------------------------------------------------------------------------------- 1 | #/********************************************************************* 2 | # Copyright (c) Intel Corporation 2020 3 | # SPDX-License-Identifier: Apache-2.0 4 | #**********************************************************************/ 5 | apiVersion: v1 6 | kind: Service 7 | metadata: 8 | labels: 9 | app: mps 10 | name: mps 11 | spec: 12 | ports: 13 | - port: 4433 14 | name: cira 15 | protocol: TCP 16 | targetPort: 4433 17 | - port: 3000 18 | name: webapi 19 | protocol: TCP 20 | targetPort: 3000 21 | selector: 22 | app: mps 23 | --- 24 | apiVersion: apps/v1 25 | kind: Deployment 26 | metadata: 27 | name: mps 28 | namespace: default 29 | spec: 30 | replicas: {{ .Values.mps.replicaCount }} 31 | selector: 32 | matchLabels: 33 | app: mps 34 | template: 35 | metadata: 36 | labels: 37 | app: mps 38 | spec: 39 | imagePullSecrets: 40 | - name: registrycredentials 41 | containers: 42 | - name: mps 43 | image: {{ .Values.images.mps }} 44 | readinessProbe: 45 | httpGet: 46 | path: /api/v1/health 47 | port: 3000 48 | periodSeconds: 12 49 | timeoutSeconds: 12 50 | failureThreshold: 3 51 | env: 52 | - name: "MPS_LOG_LEVEL" 53 | value: "{{ .Values.mps.logLevel }}" 54 | - name: "MPS_COMMON_NAME" 55 | value: "{{ .Values.mps.commonName }}" 56 | - name: "MPS_CONNECTION_STRING" 57 | valueFrom: 58 | secretKeyRef: 59 | name: mps 60 | key: connectionString 61 | - name: "MPS_VAULT_ADDRESS" 62 | value: "http://{{ .Release.Name }}-vault:8200" 63 | - name: "MPS_SECRETS_PATH" 64 | value: 'kv/data/' 65 | - name: "MPS_PORT" 66 | value: '4433' 67 | - name: "MPS_INSTANCE_NAME" 68 | valueFrom: 69 | fieldRef: 70 | fieldPath: status.podIP 71 | - name: "MPS_JWT_EXPIRATION" 72 | value: "{{ .Values.mps.jwtExpiration }}" 73 | - name: "MPS_JWT_SECRET" 74 | valueFrom: 75 | secretKeyRef: 76 | name: open-amt-admin-jwt 77 | key: secret 78 | - name: "MPS_JWT_ISSUER" 79 | valueFrom: 80 | secretKeyRef: 81 | name: open-amt-admin-jwt 82 | key: key 83 | - name: MPS_WEB_ADMIN_USER 84 | valueFrom: 85 | secretKeyRef: 86 | name: mpsweb 87 | key: user 88 | - name: MPS_WEB_ADMIN_PASSWORD 89 | valueFrom: 90 | secretKeyRef: 91 | name: mpsweb 92 | key: password 93 | - name: MPS_VAULT_TOKEN 94 | valueFrom: 95 | secretKeyRef: 96 | name: vault 97 | key: vaultKey 98 | ports: 99 | - containerPort: 3000 100 | name: mps 101 | - containerPort: 4433 102 | name: mpsws 103 | -------------------------------------------------------------------------------- /kubernetes/charts/templates/mpsrouter.yaml: -------------------------------------------------------------------------------- 1 | #/********************************************************************* 2 | # Copyright (c) Intel Corporation 2020 3 | # SPDX-License-Identifier: Apache-2.0 4 | #**********************************************************************/ 5 | apiVersion: v1 6 | kind: Service 7 | metadata: 8 | labels: 9 | app: mpsrouter 10 | name: mpsrouter 11 | spec: 12 | ports: 13 | - port: 8003 14 | name: mpsrouter 15 | protocol: TCP 16 | targetPort: 8003 17 | selector: 18 | app: mpsrouter 19 | --- 20 | apiVersion: apps/v1 21 | kind: Deployment 22 | metadata: 23 | name: mpsrouter 24 | namespace: default 25 | spec: 26 | replicas: {{ .Values.mpsrouter.replicaCount }} 27 | selector: 28 | matchLabels: 29 | app: mpsrouter 30 | template: 31 | metadata: 32 | annotations: 33 | kuma.io/direct-access-services: "mps_default_svc_3000" 34 | labels: 35 | app: mpsrouter 36 | spec: 37 | imagePullSecrets: 38 | - name: registrycredentials 39 | containers: 40 | - name: mpsrouter 41 | securityContext: 42 | runAsUser: 999 43 | runAsNonRoot: true 44 | allowPrivilegeEscalation: false 45 | image: {{ .Values.images.mpsrouter }} 46 | readinessProbe: 47 | exec: 48 | command: ["/app","--health"] 49 | initialDelaySeconds: 5 50 | periodSeconds: 5 51 | env: 52 | - name: "MPS_CONNECTION_STRING" 53 | valueFrom: 54 | secretKeyRef: 55 | name: mpsrouter 56 | key: connectionString 57 | - name: "PORT" 58 | value: "8003" 59 | - name: "MPS_PORT" 60 | value: "3000" 61 | ports: 62 | - containerPort: 8003 63 | name: mpsrouter 64 | 65 | -------------------------------------------------------------------------------- /kubernetes/charts/templates/rps.yaml: -------------------------------------------------------------------------------- 1 | #/********************************************************************* 2 | # Copyright (c) Intel Corporation 2020 3 | # SPDX-License-Identifier: Apache-2.0 4 | #**********************************************************************/ 5 | apiVersion: v1 6 | kind: Service 7 | metadata: 8 | labels: 9 | app: rps 10 | name: rps 11 | spec: 12 | ports: 13 | - port: 8080 14 | name: websockets 15 | protocol: TCP 16 | targetPort: 8080 17 | - port: 8081 18 | name: webapi 19 | protocol: TCP 20 | targetPort: 8081 21 | selector: 22 | app: rps 23 | --- 24 | apiVersion: apps/v1 25 | kind: Deployment 26 | metadata: 27 | name: rps 28 | namespace: default 29 | spec: 30 | replicas: {{ .Values.rps.replicaCount }} 31 | selector: 32 | matchLabels: 33 | app: rps 34 | template: 35 | metadata: 36 | labels: 37 | app: rps 38 | spec: 39 | imagePullSecrets: 40 | - name: registrycredentials 41 | containers: 42 | - name: rps 43 | securityContext: 44 | runAsUser: 999 45 | runAsNonRoot: true 46 | allowPrivilegeEscalation: false 47 | image: {{ .Values.images.rps }} 48 | readinessProbe: 49 | httpGet: 50 | path: /api/v1/admin/health 51 | port: 8081 52 | initialDelaySeconds: 5 53 | periodSeconds: 5 54 | env: 55 | - name: "RPS_LOG_LEVEL" 56 | value: "{{ .Values.rps.logLevel }}" 57 | - name: "RPS_VAULT_ADDRESS" 58 | value: "http://{{ .Release.Name }}-vault:8200" 59 | - name: "RPS_SECRETS_PATH" 60 | value: 'kv/data/' 61 | - name: "RPS_MPS_SERVER" 62 | value: "http://mps:3000" 63 | - name: "RPS_CONNECTION_STRING" 64 | valueFrom: 65 | secretKeyRef: 66 | name: rps 67 | key: connectionString 68 | - name: RPS_VAULT_TOKEN 69 | valueFrom: 70 | secretKeyRef: 71 | name: vault 72 | key: vaultKey 73 | ports: 74 | - containerPort: 8080 75 | name: rps 76 | - containerPort: 8081 77 | name: rpsweb 78 | -------------------------------------------------------------------------------- /kubernetes/charts/templates/webui.yaml: -------------------------------------------------------------------------------- 1 | #/********************************************************************* 2 | # Copyright (c) Intel Corporation 2020 3 | # SPDX-License-Identifier: Apache-2.0 4 | #**********************************************************************/ 5 | apiVersion: v1 6 | kind: ConfigMap 7 | metadata: 8 | name: nginx-config-file 9 | labels: 10 | app: nginx-conf 11 | data: 12 | nginx.conf: | 13 | server { 14 | listen 80 default_server; 15 | listen [::]:80 default_server; 16 | server_name _; 17 | 18 | location / { 19 | root /usr/share/nginx/html; 20 | index index.html index.htm; 21 | } 22 | 23 | error_page 404 /index.html; 24 | 25 | # redirect server error pages to the static page /50x.html 26 | # 27 | error_page 500 502 503 504 /50x.html; 28 | location = /50x.html { 29 | root /usr/share/nginx/html; 30 | } 31 | } 32 | --- 33 | apiVersion: v1 34 | kind: Service 35 | metadata: 36 | labels: 37 | app: webui 38 | name: webui 39 | spec: 40 | ports: 41 | - port: 80 42 | name: webui 43 | protocol: TCP 44 | targetPort: 80 45 | selector: 46 | app: webui 47 | --- 48 | apiVersion: apps/v1 49 | kind: Deployment 50 | metadata: 51 | name: webui 52 | spec: 53 | replicas: {{ .Values.ui.replicaCount }} 54 | selector: 55 | matchLabels: 56 | app: webui 57 | template: 58 | metadata: 59 | labels: 60 | app: webui 61 | spec: 62 | imagePullSecrets: 63 | - name: registrycredentials 64 | volumes: 65 | - name: nginx-conf 66 | configMap: 67 | name: nginx-config-file 68 | items: 69 | - key: nginx.conf 70 | path: nginx.conf 71 | containers: 72 | - name: webui 73 | image: {{.Values.images.webui}} 74 | volumeMounts: 75 | - name: nginx-conf 76 | mountPath: /etc/nginx/conf.d/default.conf 77 | subPath: nginx.conf 78 | env: 79 | - name: "MPS_SERVER" 80 | value: "https://{{.Values.mps.commonName}}/mps" 81 | - name: "RPS_SERVER" 82 | value: "https://{{.Values.mps.commonName}}/rps" 83 | ports: 84 | - containerPort: 80 85 | name: ui -------------------------------------------------------------------------------- /kubernetes/charts/values.yaml: -------------------------------------------------------------------------------- 1 | #/********************************************************************* 2 | # Copyright (c) Intel Corporation 2020 3 | # SPDX-License-Identifier: Apache-2.0 4 | #**********************************************************************/ 5 | # Default values for installServersChart. 6 | # This is a YAML-formatted file. 7 | # Declare variables to be passed into your templates. 8 | 9 | images: 10 | mps: "intel/oact-mps:latest" 11 | rps: "intel/oact-rps:latest" 12 | webui: "intel/oact-webui:latest" 13 | mpsrouter: "intel/oact-mpsrouter:latest" 14 | mps: 15 | commonName: 16 | replicaCount: 1 17 | logLevel: "silly" 18 | jwtExpiration: 1440 19 | ui: 20 | replicaCount: 1 21 | rps: 22 | replicaCount: 1 23 | logLevel: "silly" 24 | vault: 25 | injector: 26 | annotations: 27 | kuma.io/sidecar-injection: disabled 28 | server: 29 | annotations: 30 | kuma.io/sidecar-injection: disabled 31 | ui: 32 | annotations: 33 | kuma.io/sidecar-injection: disabled 34 | enabled: true 35 | serviceType: "LoadBalancer" 36 | kong: 37 | podAnnotations: 38 | kuma.io/sidecar-injection: enabled 39 | kuma.io/gateway: enabled 40 | env: 41 | UPSTREAM_KEEPALIVE_POOL_SIZE: 0 42 | proxy: 43 | annotations: 44 | service.beta.kubernetes.io/azure-dns-label-name: "" 45 | stream: 46 | - containerPort: 4433 47 | servicePort: 4433 48 | parameters: [] 49 | http: 50 | enabled: false 51 | mpsrouter: 52 | replicaCount: 1 53 | -------------------------------------------------------------------------------- /kubernetes/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "auths": { 3 | "https://index.docker.io/v1/": { 4 | "auth": "" 5 | } 6 | }, 7 | "HttpHeaders": { 8 | "User-Agent": "Docker-Client/18.09.1 (windows)" 9 | } 10 | } -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | .PHONY: build run 2 | 3 | build: 4 | read -p "Enter IP Address:" ip; \ 5 | sed -i -e "s|\"common_name\": \".*|\"common_name\": \"$$ip\"\,|g" ./mps/.mpsrc -e "s|localhost|$$ip|g" ./sample-web-ui/src/environments/environment.ts 6 | cd ./mps && npm install 7 | cd ./rps && npm install 8 | cd ./sample-web-ui && npm install 9 | 10 | MICROSERVICES= \ 11 | run-ui & \ 12 | run-mps & \ 13 | run-rps \ 14 | 15 | .PHONY: $(MICROSERVICES) 16 | 17 | run-rps: 18 | (cd ./rps && npm run devx) 19 | 20 | run-ui: 21 | (cd ./sample-web-ui && npm start) 22 | 23 | run-mps: 24 | (cd ./mps && npm run devx) 25 | 26 | run: 27 | echo "run each service in a separate terminal window (i.e. make run-ui)" 28 | 29 | -------------------------------------------------------------------------------- /mosquitto.conf: -------------------------------------------------------------------------------- 1 | # Config file for mosquitto 2 | # 3 | # See mosquitto.conf(5) for more information. 4 | # 5 | # Default values are shown, uncomment to change. 6 | # 7 | # Use the # character to indicate a comment, but only if it is the 8 | # very first character on the line. 9 | 10 | # ================================================================= 11 | # General configuration 12 | # ================================================================= 13 | 14 | allow_anonymous true 15 | listener 8883 16 | listener 9001 17 | protocol websockets 18 | 19 | # Use per listener security settings. 20 | # 21 | # It is recommended this option be set before any other options. 22 | # 23 | # If this option is set to true, then all authentication and access control 24 | # options are controlled on a per listener basis. The following options are 25 | # affected: 26 | # 27 | # password_file acl_file psk_file auth_plugin auth_opt_* allow_anonymous 28 | # auto_id_prefix allow_zero_length_clientid 29 | # 30 | # Note that if set to true, then a durable client (i.e. with clean session set 31 | # to false) that has disconnected will use the ACL settings defined for the 32 | # listener that it was most recently connected to. 33 | # 34 | # The default behaviour is for this to be set to false, which maintains the 35 | # setting behaviour from previous versions of mosquitto. 36 | #per_listener_settings false 37 | 38 | 39 | # This option controls whether a client is allowed to connect with a zero 40 | # length client id or not. This option only affects clients using MQTT v3.1.1 41 | # and later. If set to false, clients connecting with a zero length client id 42 | # are disconnected. If set to true, clients will be allocated a client id by 43 | # the broker. This means it is only useful for clients with clean session set 44 | # to true. 45 | #allow_zero_length_clientid true 46 | 47 | # If allow_zero_length_clientid is true, this option allows you to set a prefix 48 | # to automatically generated client ids to aid visibility in logs. 49 | # Defaults to 'auto-' 50 | #auto_id_prefix auto- 51 | 52 | # This option affects the scenario when a client subscribes to a topic that has 53 | # retained messages. It is possible that the client that published the retained 54 | # message to the topic had access at the time they published, but that access 55 | # has been subsequently removed. If check_retain_source is set to true, the 56 | # default, the source of a retained message will be checked for access rights 57 | # before it is republished. When set to false, no check will be made and the 58 | # retained message will always be published. This affects all listeners. 59 | #check_retain_source true 60 | 61 | # QoS 1 and 2 messages will be allowed inflight per client until this limit 62 | # is exceeded. Defaults to 0. (No maximum) 63 | # See also max_inflight_messages 64 | #max_inflight_bytes 0 65 | 66 | # The maximum number of QoS 1 and 2 messages currently inflight per 67 | # client. 68 | # This includes messages that are partway through handshakes and 69 | # those that are being retried. Defaults to 20. Set to 0 for no 70 | # maximum. Setting to 1 will guarantee in-order delivery of QoS 1 71 | # and 2 messages. 72 | #max_inflight_messages 20 73 | 74 | # For MQTT v5 clients, it is possible to have the server send a "server 75 | # keepalive" value that will override the keepalive value set by the client. 76 | # This is intended to be used as a mechanism to say that the server will 77 | # disconnect the client earlier than it anticipated, and that the client should 78 | # use the new keepalive value. The max_keepalive option allows you to specify 79 | # that clients may only connect with keepalive less than or equal to this 80 | # value, otherwise they will be sent a server keepalive telling them to use 81 | # max_keepalive. This only applies to MQTT v5 clients. The maximum value 82 | # allowable is 65535. Do not set below 10. 83 | #max_keepalive 65535 84 | 85 | # For MQTT v5 clients, it is possible to have the server send a "maximum packet 86 | # size" value that will instruct the client it will not accept MQTT packets 87 | # with size greater than max_packet_size bytes. This applies to the full MQTT 88 | # packet, not just the payload. Setting this option to a positive value will 89 | # set the maximum packet size to that number of bytes. If a client sends a 90 | # packet which is larger than this value, it will be disconnected. This applies 91 | # to all clients regardless of the protocol version they are using, but v3.1.1 92 | # and earlier clients will of course not have received the maximum packet size 93 | # information. Defaults to no limit. Setting below 20 bytes is forbidden 94 | # because it is likely to interfere with ordinary client operation, even with 95 | # very small payloads. 96 | #max_packet_size 0 97 | 98 | # QoS 1 and 2 messages above those currently in-flight will be queued per 99 | # client until this limit is exceeded. Defaults to 0. (No maximum) 100 | # See also max_queued_messages. 101 | # If both max_queued_messages and max_queued_bytes are specified, packets will 102 | # be queued until the first limit is reached. 103 | #max_queued_bytes 0 104 | 105 | # Set the maximum QoS supported. Clients publishing at a QoS higher than 106 | # specified here will be disconnected. 107 | #max_qos 2 108 | 109 | # The maximum number of QoS 1 and 2 messages to hold in a queue per client 110 | # above those that are currently in-flight. Defaults to 1000. Set 111 | # to 0 for no maximum (not recommended). 112 | # See also queue_qos0_messages. 113 | # See also max_queued_bytes. 114 | #max_queued_messages 1000 115 | # 116 | # This option sets the maximum number of heap memory bytes that the broker will 117 | # allocate, and hence sets a hard limit on memory use by the broker. Memory 118 | # requests that exceed this value will be denied. The effect will vary 119 | # depending on what has been denied. If an incoming message is being processed, 120 | # then the message will be dropped and the publishing client will be 121 | # disconnected. If an outgoing message is being sent, then the individual 122 | # message will be dropped and the receiving client will be disconnected. 123 | # Defaults to no limit. 124 | #memory_limit 0 125 | 126 | # This option sets the maximum publish payload size that the broker will allow. 127 | # Received messages that exceed this size will not be accepted by the broker. 128 | # The default value is 0, which means that all valid MQTT messages are 129 | # accepted. MQTT imposes a maximum payload size of 268435455 bytes. 130 | #message_size_limit 0 131 | 132 | # This option allows persistent clients (those with clean session set to false) 133 | # to be removed if they do not reconnect within a certain time frame. 134 | # 135 | # This is a non-standard option in MQTT V3.1 but allowed in MQTT v3.1.1. 136 | # 137 | # Badly designed clients may set clean session to false whilst using a randomly 138 | # generated client id. This leads to persistent clients that will never 139 | # reconnect. This option allows these clients to be removed. 140 | # 141 | # The expiration period should be an integer followed by one of h d w m y for 142 | # hour, day, week, month and year respectively. For example 143 | # 144 | # persistent_client_expiration 2m 145 | # persistent_client_expiration 14d 146 | # persistent_client_expiration 1y 147 | # 148 | # The default if not set is to never expire persistent clients. 149 | #persistent_client_expiration 150 | 151 | # Write process id to a file. Default is a blank string which means 152 | # a pid file shouldn't be written. 153 | # This should be set to /var/run/mosquitto/mosquitto.pid if mosquitto is 154 | # being run automatically on boot with an init script and 155 | # start-stop-daemon or similar. 156 | #pid_file 157 | 158 | # Set to true to queue messages with QoS 0 when a persistent client is 159 | # disconnected. These messages are included in the limit imposed by 160 | # max_queued_messages and max_queued_bytes 161 | # Defaults to false. 162 | # This is a non-standard option for the MQTT v3.1 spec but is allowed in 163 | # v3.1.1. 164 | #queue_qos0_messages false 165 | 166 | # Set to false to disable retained message support. If a client publishes a 167 | # message with the retain bit set, it will be disconnected if this is set to 168 | # false. 169 | #retain_available true 170 | 171 | # Disable Nagle's algorithm on client sockets. This has the effect of reducing 172 | # latency of individual messages at the potential cost of increasing the number 173 | # of packets being sent. 174 | #set_tcp_nodelay false 175 | 176 | # Time in seconds between updates of the $SYS tree. 177 | # Set to 0 to disable the publishing of the $SYS tree. 178 | #sys_interval 10 179 | 180 | # The MQTT specification requires that the QoS of a message delivered to a 181 | # subscriber is never upgraded to match the QoS of the subscription. Enabling 182 | # this option changes this behaviour. If upgrade_outgoing_qos is set true, 183 | # messages sent to a subscriber will always match the QoS of its subscription. 184 | # This is a non-standard option explicitly disallowed by the spec. 185 | #upgrade_outgoing_qos false 186 | 187 | # When run as root, drop privileges to this user and its primary 188 | # group. 189 | # Set to root to stay as root, but this is not recommended. 190 | # If set to "mosquitto", or left unset, and the "mosquitto" user does not exist 191 | # then it will drop privileges to the "nobody" user instead. 192 | # If run as a non-root user, this setting has no effect. 193 | # Note that on Windows this has no effect and so mosquitto should be started by 194 | # the user you wish it to run as. 195 | #user mosquitto 196 | 197 | # ================================================================= 198 | # Listeners 199 | # ================================================================= 200 | 201 | # Listen on a port/ip address combination. By using this variable 202 | # multiple times, mosquitto can listen on more than one port. If 203 | # this variable is used and neither bind_address nor port given, 204 | # then the default listener will not be started. 205 | # The port number to listen on must be given. Optionally, an ip 206 | # address or host name may be supplied as a second argument. In 207 | # this case, mosquitto will attempt to bind the listener to that 208 | # address and so restrict access to the associated network and 209 | # interface. By default, mosquitto will listen on all interfaces. 210 | # Note that for a websockets listener it is not possible to bind to a host 211 | # name. 212 | # 213 | # On systems that support Unix Domain Sockets, it is also possible 214 | # to create a # Unix socket rather than opening a TCP socket. In 215 | # this case, the port number should be set to 0 and a unix socket 216 | # path must be provided, e.g. 217 | # listener 0 /tmp/mosquitto.sock 218 | # 219 | # listener port-number [ip address/host name/unix socket path] 220 | #listener 221 | 222 | # By default, a listener will attempt to listen on all supported IP protocol 223 | # versions. If you do not have an IPv4 or IPv6 interface you may wish to 224 | # disable support for either of those protocol versions. In particular, note 225 | # that due to the limitations of the websockets library, it will only ever 226 | # attempt to open IPv6 sockets if IPv6 support is compiled in, and so will fail 227 | # if IPv6 is not available. 228 | # 229 | # Set to `ipv4` to force the listener to only use IPv4, or set to `ipv6` to 230 | # force the listener to only use IPv6. If you want support for both IPv4 and 231 | # IPv6, then do not use the socket_domain option. 232 | # 233 | #socket_domain 234 | 235 | # Bind the listener to a specific interface. This is similar to 236 | # the [ip address/host name] part of the listener definition, but is useful 237 | # when an interface has multiple addresses or the address may change. If used 238 | # with the [ip address/host name] part of the listener definition, then the 239 | # bind_interface option will take priority. 240 | # Not available on Windows. 241 | # 242 | # Example: bind_interface eth0 243 | #bind_interface 244 | 245 | # When a listener is using the websockets protocol, it is possible to serve 246 | # http data as well. Set http_dir to a directory which contains the files you 247 | # wish to serve. If this option is not specified, then no normal http 248 | # connections will be possible. 249 | #http_dir 250 | 251 | # The maximum number of client connections to allow. This is 252 | # a per listener setting. 253 | # Default is -1, which means unlimited connections. 254 | # Note that other process limits mean that unlimited connections 255 | # are not really possible. Typically the default maximum number of 256 | # connections possible is around 1024. 257 | #max_connections -1 258 | 259 | # The listener can be restricted to operating within a topic hierarchy using 260 | # the mount_point option. This is achieved be prefixing the mount_point string 261 | # to all topics for any clients connected to this listener. This prefixing only 262 | # happens internally to the broker; the client will not see the prefix. 263 | #mount_point 264 | 265 | # Choose the protocol to use when listening. 266 | # This can be either mqtt or websockets. 267 | # Certificate based TLS may be used with websockets, except that only the 268 | # cafile, certfile, keyfile, ciphers, and ciphers_tls13 options are supported. 269 | #protocol mqtt 270 | 271 | # Set use_username_as_clientid to true to replace the clientid that a client 272 | # connected with with its username. This allows authentication to be tied to 273 | # the clientid, which means that it is possible to prevent one client 274 | # disconnecting another by using the same clientid. 275 | # If a client connects with no username it will be disconnected as not 276 | # authorised when this option is set to true. 277 | # Do not use in conjunction with clientid_prefixes. 278 | # See also use_identity_as_username. 279 | #use_username_as_clientid 280 | 281 | # Change the websockets headers size. This is a global option, it is not 282 | # possible to set per listener. This option sets the size of the buffer used in 283 | # the libwebsockets library when reading HTTP headers. If you are passing large 284 | # header data such as cookies then you may need to increase this value. If left 285 | # unset, or set to 0, then the default of 1024 bytes will be used. 286 | #websockets_headers_size 287 | 288 | # ----------------------------------------------------------------- 289 | # Certificate based SSL/TLS support 290 | # ----------------------------------------------------------------- 291 | # The following options can be used to enable certificate based SSL/TLS support 292 | # for this listener. Note that the recommended port for MQTT over TLS is 8883, 293 | # but this must be set manually. 294 | # 295 | # See also the mosquitto-tls man page and the "Pre-shared-key based SSL/TLS 296 | # support" section. Only one of certificate or PSK encryption support can be 297 | # enabled for any listener. 298 | 299 | # Both of certfile and keyfile must be defined to enable certificate based 300 | # TLS encryption. 301 | 302 | # Path to the PEM encoded server certificate. 303 | #certfile 304 | 305 | # Path to the PEM encoded keyfile. 306 | #keyfile 307 | 308 | # If you wish to control which encryption ciphers are used, use the ciphers 309 | # option. The list of available ciphers can be optained using the "openssl 310 | # ciphers" command and should be provided in the same format as the output of 311 | # that command. This applies to TLS 1.2 and earlier versions only. Use 312 | # ciphers_tls1.3 for TLS v1.3. 313 | #ciphers 314 | 315 | # Choose which TLS v1.3 ciphersuites are used for this listener. 316 | # Defaults to "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256" 317 | #ciphers_tls1.3 318 | 319 | # If you have require_certificate set to true, you can create a certificate 320 | # revocation list file to revoke access to particular client certificates. If 321 | # you have done this, use crlfile to point to the PEM encoded revocation file. 322 | #crlfile 323 | 324 | # To allow the use of ephemeral DH key exchange, which provides forward 325 | # security, the listener must load DH parameters. This can be specified with 326 | # the dhparamfile option. The dhparamfile can be generated with the command 327 | # e.g. "openssl dhparam -out dhparam.pem 2048" 328 | #dhparamfile 329 | 330 | # By default an TLS enabled listener will operate in a similar fashion to a 331 | # https enabled web server, in that the server has a certificate signed by a CA 332 | # and the client will verify that it is a trusted certificate. The overall aim 333 | # is encryption of the network traffic. By setting require_certificate to true, 334 | # the client must provide a valid certificate in order for the network 335 | # connection to proceed. This allows access to the broker to be controlled 336 | # outside of the mechanisms provided by MQTT. 337 | #require_certificate false 338 | 339 | # cafile and capath define methods of accessing the PEM encoded 340 | # Certificate Authority certificates that will be considered trusted when 341 | # checking incoming client certificates. 342 | # cafile defines the path to a file containing the CA certificates. 343 | # capath defines a directory that will be searched for files 344 | # containing the CA certificates. For capath to work correctly, the 345 | # certificate files must have ".crt" as the file ending and you must run 346 | # "openssl rehash " each time you add/remove a certificate. 347 | #cafile 348 | #capath 349 | 350 | 351 | # If require_certificate is true, you may set use_identity_as_username to true 352 | # to use the CN value from the client certificate as a username. If this is 353 | # true, the password_file option will not be used for this listener. 354 | #use_identity_as_username false 355 | 356 | # ----------------------------------------------------------------- 357 | # Pre-shared-key based SSL/TLS support 358 | # ----------------------------------------------------------------- 359 | # The following options can be used to enable PSK based SSL/TLS support for 360 | # this listener. Note that the recommended port for MQTT over TLS is 8883, but 361 | # this must be set manually. 362 | # 363 | # See also the mosquitto-tls man page and the "Certificate based SSL/TLS 364 | # support" section. Only one of certificate or PSK encryption support can be 365 | # enabled for any listener. 366 | 367 | # The psk_hint option enables pre-shared-key support for this listener and also 368 | # acts as an identifier for this listener. The hint is sent to clients and may 369 | # be used locally to aid authentication. The hint is a free form string that 370 | # doesn't have much meaning in itself, so feel free to be creative. 371 | # If this option is provided, see psk_file to define the pre-shared keys to be 372 | # used or create a security plugin to handle them. 373 | #psk_hint 374 | 375 | # When using PSK, the encryption ciphers used will be chosen from the list of 376 | # available PSK ciphers. If you want to control which ciphers are available, 377 | # use the "ciphers" option. The list of available ciphers can be optained 378 | # using the "openssl ciphers" command and should be provided in the same format 379 | # as the output of that command. 380 | #ciphers 381 | 382 | # Set use_identity_as_username to have the psk identity sent by the client used 383 | # as its username. Authentication will be carried out using the PSK rather than 384 | # the MQTT username/password and so password_file will not be used for this 385 | # listener. 386 | #use_identity_as_username false 387 | 388 | 389 | # ================================================================= 390 | # Persistence 391 | # ================================================================= 392 | 393 | # If persistence is enabled, save the in-memory database to disk 394 | # every autosave_interval seconds. If set to 0, the persistence 395 | # database will only be written when mosquitto exits. See also 396 | # autosave_on_changes. 397 | # Note that writing of the persistence database can be forced by 398 | # sending mosquitto a SIGUSR1 signal. 399 | #autosave_interval 1800 400 | 401 | # If true, mosquitto will count the number of subscription changes, retained 402 | # messages received and queued messages and if the total exceeds 403 | # autosave_interval then the in-memory database will be saved to disk. 404 | # If false, mosquitto will save the in-memory database to disk by treating 405 | # autosave_interval as a time in seconds. 406 | #autosave_on_changes false 407 | 408 | # Save persistent message data to disk (true/false). 409 | # This saves information about all messages, including 410 | # subscriptions, currently in-flight messages and retained 411 | # messages. 412 | # retained_persistence is a synonym for this option. 413 | #persistence false 414 | 415 | # The filename to use for the persistent database, not including 416 | # the path. 417 | #persistence_file mosquitto.db 418 | 419 | # Location for persistent database. 420 | # Default is an empty string (current directory). 421 | # Set to e.g. /var/lib/mosquitto if running as a proper service on Linux or 422 | # similar. 423 | #persistence_location 424 | 425 | 426 | # ================================================================= 427 | # Logging 428 | # ================================================================= 429 | 430 | # Places to log to. Use multiple log_dest lines for multiple 431 | # logging destinations. 432 | # Possible destinations are: stdout stderr syslog topic file dlt 433 | # 434 | # stdout and stderr log to the console on the named output. 435 | # 436 | # syslog uses the userspace syslog facility which usually ends up 437 | # in /var/log/messages or similar. 438 | # 439 | # topic logs to the broker topic '$SYS/broker/log/', 440 | # where severity is one of D, E, W, N, I, M which are debug, error, 441 | # warning, notice, information and message. Message type severity is used by 442 | # the subscribe/unsubscribe log_types and publishes log messages to 443 | # $SYS/broker/log/M/susbcribe or $SYS/broker/log/M/unsubscribe. 444 | # 445 | # The file destination requires an additional parameter which is the file to be 446 | # logged to, e.g. "log_dest file /var/log/mosquitto.log". The file will be 447 | # closed and reopened when the broker receives a HUP signal. Only a single file 448 | # destination may be configured. 449 | # 450 | # The dlt destination is for the automotive `Diagnostic Log and Trace` tool. 451 | # This requires that Mosquitto has been compiled with DLT support. 452 | # 453 | # Note that if the broker is running as a Windows service it will default to 454 | # "log_dest none" and neither stdout nor stderr logging is available. 455 | # Use "log_dest none" if you wish to disable logging. 456 | #log_dest stderr 457 | 458 | # Types of messages to log. Use multiple log_type lines for logging 459 | # multiple types of messages. 460 | # Possible types are: debug, error, warning, notice, information, 461 | # none, subscribe, unsubscribe, websockets, all. 462 | # Note that debug type messages are for decoding the incoming/outgoing 463 | # network packets. They are not logged in "topics". 464 | #log_type error 465 | #log_type warning 466 | #log_type notice 467 | #log_type information 468 | 469 | 470 | # If set to true, client connection and disconnection messages will be included 471 | # in the log. 472 | #connection_messages true 473 | 474 | # If using syslog logging (not on Windows), messages will be logged to the 475 | # "daemon" facility by default. Use the log_facility option to choose which of 476 | # local0 to local7 to log to instead. The option value should be an integer 477 | # value, e.g. "log_facility 5" to use local5. 478 | #log_facility 479 | 480 | # If set to true, add a timestamp value to each log message. 481 | #log_timestamp true 482 | 483 | # Set the format of the log timestamp. If left unset, this is the number of 484 | # seconds since the Unix epoch. 485 | # This is a free text string which will be passed to the strftime function. To 486 | # get an ISO 8601 datetime, for example: 487 | # log_timestamp_format %Y-%m-%dT%H:%M:%S 488 | #log_timestamp_format 489 | 490 | # Change the websockets logging level. This is a global option, it is not 491 | # possible to set per listener. This is an integer that is interpreted by 492 | # libwebsockets as a bit mask for its lws_log_levels enum. See the 493 | # libwebsockets documentation for more details. "log_type websockets" must also 494 | # be enabled. 495 | #websockets_log_level 0 496 | 497 | 498 | # ================================================================= 499 | # Security 500 | # ================================================================= 501 | 502 | # If set, only clients that have a matching prefix on their 503 | # clientid will be allowed to connect to the broker. By default, 504 | # all clients may connect. 505 | # For example, setting "secure-" here would mean a client "secure- 506 | # client" could connect but another with clientid "mqtt" couldn't. 507 | #clientid_prefixes 508 | 509 | # Boolean value that determines whether clients that connect 510 | # without providing a username are allowed to connect. If set to 511 | # false then a password file should be created (see the 512 | # password_file option) to control authenticated client access. 513 | # 514 | # Defaults to false, unless there are no listeners defined in the configuration 515 | # file, in which case it is set to true, but connections are only allowed from 516 | # the local machine. 517 | #allow_anonymous false 518 | 519 | # ----------------------------------------------------------------- 520 | # Default authentication and topic access control 521 | # ----------------------------------------------------------------- 522 | 523 | # Control access to the broker using a password file. This file can be 524 | # generated using the mosquitto_passwd utility. If TLS support is not compiled 525 | # into mosquitto (it is recommended that TLS support should be included) then 526 | # plain text passwords are used, in which case the file should be a text file 527 | # with lines in the format: 528 | # username:password 529 | # The password (and colon) may be omitted if desired, although this 530 | # offers very little in the way of security. 531 | # 532 | # See the TLS client require_certificate and use_identity_as_username options 533 | # for alternative authentication options. If an auth_plugin is used as well as 534 | # password_file, the auth_plugin check will be made first. 535 | #password_file 536 | 537 | # Access may also be controlled using a pre-shared-key file. This requires 538 | # TLS-PSK support and a listener configured to use it. The file should be text 539 | # lines in the format: 540 | # identity:key 541 | # The key should be in hexadecimal format without a leading "0x". 542 | # If an auth_plugin is used as well, the auth_plugin check will be made first. 543 | #psk_file 544 | 545 | # Control access to topics on the broker using an access control list 546 | # file. If this parameter is defined then only the topics listed will 547 | # have access. 548 | # If the first character of a line of the ACL file is a # it is treated as a 549 | # comment. 550 | # Topic access is added with lines of the format: 551 | # 552 | # topic [read|write|readwrite|deny] 553 | # 554 | # The access type is controlled using "read", "write", "readwrite" or "deny". 555 | # This parameter is optional (unless contains a space character) - if 556 | # not given then the access is read/write. can contain the + or # 557 | # wildcards as in subscriptions. 558 | # 559 | # The "deny" option can used to explicity deny access to a topic that would 560 | # otherwise be granted by a broader read/write/readwrite statement. Any "deny" 561 | # topics are handled before topics that grant read/write access. 562 | # 563 | # The first set of topics are applied to anonymous clients, assuming 564 | # allow_anonymous is true. User specific topic ACLs are added after a 565 | # user line as follows: 566 | # 567 | # user 568 | # 569 | # The username referred to here is the same as in password_file. It is 570 | # not the clientid. 571 | # 572 | # 573 | # If is also possible to define ACLs based on pattern substitution within the 574 | # topic. The patterns available for substition are: 575 | # 576 | # %c to match the client id of the client 577 | # %u to match the username of the client 578 | # 579 | # The substitution pattern must be the only text for that level of hierarchy. 580 | # 581 | # The form is the same as for the topic keyword, but using pattern as the 582 | # keyword. 583 | # Pattern ACLs apply to all users even if the "user" keyword has previously 584 | # been given. 585 | # 586 | # If using bridges with usernames and ACLs, connection messages can be allowed 587 | # with the following pattern: 588 | # pattern write $SYS/broker/connection/%c/state 589 | # 590 | # pattern [read|write|readwrite] 591 | # 592 | # Example: 593 | # 594 | # pattern write sensor/%u/data 595 | # 596 | # If an auth_plugin is used as well as acl_file, the auth_plugin check will be 597 | # made first. 598 | #acl_file 599 | 600 | # ----------------------------------------------------------------- 601 | # External authentication and topic access plugin options 602 | # ----------------------------------------------------------------- 603 | 604 | # External authentication and access control can be supported with the 605 | # auth_plugin option. This is a path to a loadable plugin. See also the 606 | # auth_opt_* options described below. 607 | # 608 | # The auth_plugin option can be specified multiple times to load multiple 609 | # plugins. The plugins will be processed in the order that they are specified 610 | # here. If the auth_plugin option is specified alongside either of 611 | # password_file or acl_file then the plugin checks will be made first. 612 | # 613 | #auth_plugin 614 | 615 | # If the auth_plugin option above is used, define options to pass to the 616 | # plugin here as described by the plugin instructions. All options named 617 | # using the format auth_opt_* will be passed to the plugin, for example: 618 | # 619 | # auth_opt_db_host 620 | # auth_opt_db_port 621 | # auth_opt_db_username 622 | # auth_opt_db_password 623 | 624 | 625 | # ================================================================= 626 | # Bridges 627 | # ================================================================= 628 | 629 | # A bridge is a way of connecting multiple MQTT brokers together. 630 | # Create a new bridge using the "connection" option as described below. Set 631 | # options for the bridges using the remaining parameters. You must specify the 632 | # address and at least one topic to subscribe to. 633 | # 634 | # Each connection must have a unique name. 635 | # 636 | # The address line may have multiple host address and ports specified. See 637 | # below in the round_robin description for more details on bridge behaviour if 638 | # multiple addresses are used. Note that if you use an IPv6 address, then you 639 | # are required to specify a port. 640 | # 641 | # The direction that the topic will be shared can be chosen by 642 | # specifying out, in or both, where the default value is out. 643 | # The QoS level of the bridged communication can be specified with the next 644 | # topic option. The default QoS level is 0, to change the QoS the topic 645 | # direction must also be given. 646 | # 647 | # The local and remote prefix options allow a topic to be remapped when it is 648 | # bridged to/from the remote broker. This provides the ability to place a topic 649 | # tree in an appropriate location. 650 | # 651 | # For more details see the mosquitto.conf man page. 652 | # 653 | # Multiple topics can be specified per connection, but be careful 654 | # not to create any loops. 655 | # 656 | # If you are using bridges with cleansession set to false (the default), then 657 | # you may get unexpected behaviour from incoming topics if you change what 658 | # topics you are subscribing to. This is because the remote broker keeps the 659 | # subscription for the old topic. If you have this problem, connect your bridge 660 | # with cleansession set to true, then reconnect with cleansession set to false 661 | # as normal. 662 | #connection 663 | #address [:] [[:]] 664 | #topic [[[out | in | both] qos-level] local-prefix remote-prefix] 665 | 666 | # If you need to have the bridge connect over a particular network interface, 667 | # use bridge_bind_address to tell the bridge which local IP address the socket 668 | # should bind to, e.g. `bridge_bind_address 192.168.1.10` 669 | #bridge_bind_address 670 | 671 | # If a bridge has topics that have "out" direction, the default behaviour is to 672 | # send an unsubscribe request to the remote broker on that topic. This means 673 | # that changing a topic direction from "in" to "out" will not keep receiving 674 | # incoming messages. Sending these unsubscribe requests is not always 675 | # desirable, setting bridge_attempt_unsubscribe to false will disable sending 676 | # the unsubscribe request. 677 | #bridge_attempt_unsubscribe true 678 | 679 | # Set the version of the MQTT protocol to use with for this bridge. Can be one 680 | # of mqttv50, mqttv311 or mqttv31. Defaults to mqttv311. 681 | #bridge_protocol_version mqttv311 682 | 683 | # Set the clean session variable for this bridge. 684 | # When set to true, when the bridge disconnects for any reason, all 685 | # messages and subscriptions will be cleaned up on the remote 686 | # broker. Note that with cleansession set to true, there may be a 687 | # significant amount of retained messages sent when the bridge 688 | # reconnects after losing its connection. 689 | # When set to false, the subscriptions and messages are kept on the 690 | # remote broker, and delivered when the bridge reconnects. 691 | #cleansession false 692 | 693 | # Set the amount of time a bridge using the lazy start type must be idle before 694 | # it will be stopped. Defaults to 60 seconds. 695 | #idle_timeout 60 696 | 697 | # Set the keepalive interval for this bridge connection, in 698 | # seconds. 699 | #keepalive_interval 60 700 | 701 | # Set the clientid to use on the local broker. If not defined, this defaults to 702 | # 'local.'. If you are bridging a broker to itself, it is important 703 | # that local_clientid and clientid do not match. 704 | #local_clientid 705 | 706 | # If set to true, publish notification messages to the local and remote brokers 707 | # giving information about the state of the bridge connection. Retained 708 | # messages are published to the topic $SYS/broker/connection//state 709 | # unless the notification_topic option is used. 710 | # If the message is 1 then the connection is active, or 0 if the connection has 711 | # failed. 712 | # This uses the last will and testament feature. 713 | #notifications true 714 | 715 | # Choose the topic on which notification messages for this bridge are 716 | # published. If not set, messages are published on the topic 717 | # $SYS/broker/connection//state 718 | #notification_topic 719 | 720 | # Set the client id to use on the remote end of this bridge connection. If not 721 | # defined, this defaults to 'name.hostname' where name is the connection name 722 | # and hostname is the hostname of this computer. 723 | # This replaces the old "clientid" option to avoid confusion. "clientid" 724 | # remains valid for the time being. 725 | #remote_clientid 726 | 727 | # Set the password to use when connecting to a broker that requires 728 | # authentication. This option is only used if remote_username is also set. 729 | # This replaces the old "password" option to avoid confusion. "password" 730 | # remains valid for the time being. 731 | #remote_password 732 | 733 | # Set the username to use when connecting to a broker that requires 734 | # authentication. 735 | # This replaces the old "username" option to avoid confusion. "username" 736 | # remains valid for the time being. 737 | #remote_username 738 | 739 | # Set the amount of time a bridge using the automatic start type will wait 740 | # until attempting to reconnect. 741 | # This option can be configured to use a constant delay time in seconds, or to 742 | # use a backoff mechanism based on "Decorrelated Jitter", which adds a degree 743 | # of randomness to when the restart occurs. 744 | # 745 | # Set a constant timeout of 20 seconds: 746 | # restart_timeout 20 747 | # 748 | # Set backoff with a base (start value) of 10 seconds and a cap (upper limit) of 749 | # 60 seconds: 750 | # restart_timeout 10 30 751 | # 752 | # Defaults to jitter with a base of 5 and cap of 30 753 | #restart_timeout 5 30 754 | 755 | # If the bridge has more than one address given in the address/addresses 756 | # configuration, the round_robin option defines the behaviour of the bridge on 757 | # a failure of the bridge connection. If round_robin is false, the default 758 | # value, then the first address is treated as the main bridge connection. If 759 | # the connection fails, the other secondary addresses will be attempted in 760 | # turn. Whilst connected to a secondary bridge, the bridge will periodically 761 | # attempt to reconnect to the main bridge until successful. 762 | # If round_robin is true, then all addresses are treated as equals. If a 763 | # connection fails, the next address will be tried and if successful will 764 | # remain connected until it fails 765 | #round_robin false 766 | 767 | # Set the start type of the bridge. This controls how the bridge starts and 768 | # can be one of three types: automatic, lazy and once. Note that RSMB provides 769 | # a fourth start type "manual" which isn't currently supported by mosquitto. 770 | # 771 | # "automatic" is the default start type and means that the bridge connection 772 | # will be started automatically when the broker starts and also restarted 773 | # after a short delay (30 seconds) if the connection fails. 774 | # 775 | # Bridges using the "lazy" start type will be started automatically when the 776 | # number of queued messages exceeds the number set with the "threshold" 777 | # parameter. It will be stopped automatically after the time set by the 778 | # "idle_timeout" parameter. Use this start type if you wish the connection to 779 | # only be active when it is needed. 780 | # 781 | # A bridge using the "once" start type will be started automatically when the 782 | # broker starts but will not be restarted if the connection fails. 783 | #start_type automatic 784 | 785 | # Set the number of messages that need to be queued for a bridge with lazy 786 | # start type to be restarted. Defaults to 10 messages. 787 | # Must be less than max_queued_messages. 788 | #threshold 10 789 | 790 | # If try_private is set to true, the bridge will attempt to indicate to the 791 | # remote broker that it is a bridge not an ordinary client. If successful, this 792 | # means that loop detection will be more effective and that retained messages 793 | # will be propagated correctly. Not all brokers support this feature so it may 794 | # be necessary to set try_private to false if your bridge does not connect 795 | # properly. 796 | #try_private true 797 | 798 | # Some MQTT brokers do not allow retained messages. MQTT v5 gives a mechanism 799 | # for brokers to tell clients that they do not support retained messages, but 800 | # this is not possible for MQTT v3.1.1 or v3.1. If you need to bridge to a 801 | # v3.1.1 or v3.1 broker that does not support retained messages, set the 802 | # bridge_outgoing_retain option to false. This will remove the retain bit on 803 | # all outgoing messages to that bridge, regardless of any other setting. 804 | #bridge_outgoing_retain true 805 | 806 | # If you wish to restrict the size of messages sent to a remote bridge, use the 807 | # bridge_max_packet_size option. This sets the maximum number of bytes for 808 | # the total message, including headers and payload. 809 | # Note that MQTT v5 brokers may provide their own maximum-packet-size property. 810 | # In this case, the smaller of the two limits will be used. 811 | # Set to 0 for "unlimited". 812 | #bridge_max_packet_size 0 813 | 814 | 815 | # ----------------------------------------------------------------- 816 | # Certificate based SSL/TLS support 817 | # ----------------------------------------------------------------- 818 | # Either bridge_cafile or bridge_capath must be defined to enable TLS support 819 | # for this bridge. 820 | # bridge_cafile defines the path to a file containing the 821 | # Certificate Authority certificates that have signed the remote broker 822 | # certificate. 823 | # bridge_capath defines a directory that will be searched for files containing 824 | # the CA certificates. For bridge_capath to work correctly, the certificate 825 | # files must have ".crt" as the file ending and you must run "openssl rehash 826 | # " each time you add/remove a certificate. 827 | #bridge_cafile 828 | #bridge_capath 829 | 830 | 831 | # If the remote broker has more than one protocol available on its port, e.g. 832 | # MQTT and WebSockets, then use bridge_alpn to configure which protocol is 833 | # requested. Note that WebSockets support for bridges is not yet available. 834 | #bridge_alpn 835 | 836 | # When using certificate based encryption, bridge_insecure disables 837 | # verification of the server hostname in the server certificate. This can be 838 | # useful when testing initial server configurations, but makes it possible for 839 | # a malicious third party to impersonate your server through DNS spoofing, for 840 | # example. Use this option in testing only. If you need to resort to using this 841 | # option in a production environment, your setup is at fault and there is no 842 | # point using encryption. 843 | #bridge_insecure false 844 | 845 | # Path to the PEM encoded client certificate, if required by the remote broker. 846 | #bridge_certfile 847 | 848 | # Path to the PEM encoded client private key, if required by the remote broker. 849 | #bridge_keyfile 850 | 851 | # ----------------------------------------------------------------- 852 | # PSK based SSL/TLS support 853 | # ----------------------------------------------------------------- 854 | # Pre-shared-key encryption provides an alternative to certificate based 855 | # encryption. A bridge can be configured to use PSK with the bridge_identity 856 | # and bridge_psk options. These are the client PSK identity, and pre-shared-key 857 | # in hexadecimal format with no "0x". Only one of certificate and PSK based 858 | # encryption can be used on one 859 | # bridge at once. 860 | #bridge_identity 861 | #bridge_psk 862 | 863 | 864 | # ================================================================= 865 | # External config files 866 | # ================================================================= 867 | 868 | # External configuration files may be included by using the 869 | # include_dir option. This defines a directory that will be searched 870 | # for config files. All files that end in '.conf' will be loaded as 871 | # a configuration file. It is best to have this as the last option 872 | # in the main file. This option will only be processed from the main 873 | # configuration file. The directory specified must not contain the 874 | # main configuration file. 875 | # Files within include_dir will be loaded sorted in case-sensitive 876 | # alphabetical order, with capital letters ordered first. If this option is 877 | # given multiple times, all of the files from the first instance will be 878 | # processed before the next instance. See the man page for examples. 879 | #include_dir -------------------------------------------------------------------------------- /nginx.conf: -------------------------------------------------------------------------------- 1 | 2 | server { 3 | listen 80 default_server; 4 | listen [::]:80 default_server; 5 | server_name _; 6 | 7 | 8 | location / { 9 | root /usr/share/nginx/html; 10 | index index.html index.htm; 11 | } 12 | 13 | error_page 404 /index.html; 14 | 15 | # redirect server error pages to the static page /50x.html 16 | # 17 | error_page 500 502 503 504 /50x.html; 18 | location = /50x.html { 19 | root /usr/share/nginx/html; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /pg/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM postgres:17@sha256:fe3f571d128e8efadcd8b2fde0e2b73ebab6dbec33f6bfe69d98c682c7d8f7bd 2 | COPY pg_hba.conf /var/lib/postgresql/ 3 | RUN openssl req -new -x509 -days 365 -nodes -text -out /var/lib/postgresql/server.crt -keyout /var/lib/postgresql/server.key -subj "/CN=vprodemo.com" 4 | RUN chmod 600 /var/lib/postgresql/server.key 5 | RUN chown postgres:postgres /var/lib/postgresql/server.key -------------------------------------------------------------------------------- /pg/pg_hba.conf: -------------------------------------------------------------------------------- 1 | # PostgreSQL Client Authentication Configuration File 2 | # =================================================== 3 | # 4 | # Refer to the "Client Authentication" section in the PostgreSQL 5 | # documentation for a complete description of this file. A short 6 | # synopsis follows. 7 | # 8 | # This file controls: which hosts are allowed to connect, how clients 9 | # are authenticated, which PostgreSQL user names they can use, which 10 | # databases they can access. Records take one of these forms: 11 | # 12 | # local DATABASE USER METHOD [OPTIONS] 13 | # host DATABASE USER ADDRESS METHOD [OPTIONS] 14 | # hostssl DATABASE USER ADDRESS METHOD [OPTIONS] 15 | # hostnossl DATABASE USER ADDRESS METHOD [OPTIONS] 16 | # hostgssenc DATABASE USER ADDRESS METHOD [OPTIONS] 17 | # hostnogssenc DATABASE USER ADDRESS METHOD [OPTIONS] 18 | # 19 | # (The uppercase items must be replaced by actual values.) 20 | # 21 | # The first field is the connection type: "local" is a Unix-domain 22 | # socket, "host" is either a plain or SSL-encrypted TCP/IP socket, 23 | # "hostssl" is an SSL-encrypted TCP/IP socket, and "hostnossl" is a 24 | # non-SSL TCP/IP socket. Similarly, "hostgssenc" uses a 25 | # GSSAPI-encrypted TCP/IP socket, while "hostnogssenc" uses a 26 | # non-GSSAPI socket. 27 | # 28 | # DATABASE can be "all", "sameuser", "samerole", "replication", a 29 | # database name, or a comma-separated list thereof. The "all" 30 | # keyword does not match "replication". Access to replication 31 | # must be enabled in a separate record (see example below). 32 | # 33 | # USER can be "all", a user name, a group name prefixed with "+", or a 34 | # comma-separated list thereof. In both the DATABASE and USER fields 35 | # you can also write a file name prefixed with "@" to include names 36 | # from a separate file. 37 | # 38 | # ADDRESS specifies the set of hosts the record matches. It can be a 39 | # host name, or it is made up of an IP address and a CIDR mask that is 40 | # an integer (between 0 and 32 (IPv4) or 128 (IPv6) inclusive) that 41 | # specifies the number of significant bits in the mask. A host name 42 | # that starts with a dot (.) matches a suffix of the actual host name. 43 | # Alternatively, you can write an IP address and netmask in separate 44 | # columns to specify the set of hosts. Instead of a CIDR-address, you 45 | # can write "samehost" to match any of the server's own IP addresses, 46 | # or "samenet" to match any address in any subnet that the server is 47 | # directly connected to. 48 | # 49 | # METHOD can be "trust", "reject", "md5", "password", "scram-sha-256", 50 | # "gss", "sspi", "ident", "peer", "pam", "ldap", "radius" or "cert". 51 | # Note that "password" sends passwords in clear text; "md5" or 52 | # "scram-sha-256" are preferred since they send encrypted passwords. 53 | # 54 | # OPTIONS are a set of options for the authentication in the format 55 | # NAME=VALUE. The available options depend on the different 56 | # authentication methods -- refer to the "Client Authentication" 57 | # section in the documentation for a list of which options are 58 | # available for which authentication methods. 59 | # 60 | # Database and user names containing spaces, commas, quotes and other 61 | # special characters must be quoted. Quoting one of the keywords 62 | # "all", "sameuser", "samerole" or "replication" makes the name lose 63 | # its special character, and just match a database or username with 64 | # that name. 65 | # 66 | # This file is read on server startup and when the server receives a 67 | # SIGHUP signal. If you edit the file on a running system, you have to 68 | # SIGHUP the server for the changes to take effect, run "pg_ctl reload", 69 | # or execute "SELECT pg_reload_conf()". 70 | # 71 | # Put your actual configuration here 72 | # ---------------------------------- 73 | # 74 | # If you want to allow non-local connections, you need to add more 75 | # "host" records. In that case you will also need to make PostgreSQL 76 | # listen on a non-local interface via the listen_addresses 77 | # configuration parameter, or via the -i or -h command line switches. 78 | 79 | # CAUTION: Configuring the system for local "trust" authentication 80 | # allows any local user to connect as any PostgreSQL user, including 81 | # the database superuser. If you do not trust all your local users, 82 | # use another authentication method. 83 | 84 | 85 | # TYPE DATABASE USER ADDRESS METHOD 86 | 87 | # "local" is for Unix domain socket connections only 88 | local all all trust 89 | # IPv4 local connections: 90 | # IPv6 local connections: 91 | # Allow replication connections from localhost, by a user with the 92 | # replication privilege. 93 | local replication all trust 94 | hostssl all all 0.0.0.0/0 md5 95 | hostssl all all 0.0.0.0/0 cert -------------------------------------------------------------------------------- /sdle.yaml: -------------------------------------------------------------------------------- 1 | # The following represents a list of the projects to process, the Jenkins pipeline will execute 2 | # each independently in an isolated workspace and in parallel. 3 | # 4 | # The following attributes are required for each project: 5 | # sdle_project_id : the id of project in sdle 6 | # owner: the account owner of the GitHub repository 7 | # repo: the name of the GitHub repository 8 | # branch: the name of the branch within the repo that contains the workflow artifact to download 9 | # artifacts: a comma-delimited string of artifact names to download 10 | # folders: a comma-delimited string of folder names that the respective artifact should be downloaded to 11 | # 12 | - sdle_project_id: 20340 13 | owner: open-amt-cloud-toolkit 14 | repo: rps 15 | branch: main 16 | artifacts: report 17 | folders: artifacts/CodeQL 18 | - sdle_project_id: 20340 19 | owner: open-amt-cloud-toolkit 20 | repo: ui-toolkit 21 | branch: main 22 | artifacts: report 23 | folders: artifacts/CodeQL 24 | - sdle_project_id: 20340 25 | owner: open-amt-cloud-toolkit 26 | repo: mps 27 | branch: main 28 | artifacts: report 29 | folders: artifacts/CodeQL 30 | - sdle_project_id: 20340 31 | owner: open-amt-cloud-toolkit 32 | repo: sample-web-ui 33 | branch: main 34 | artifacts: report 35 | folders: artifacts/CodeQL 36 | - sdle_project_id: 20340 37 | owner: open-amt-cloud-toolkit 38 | repo: mps-router 39 | branch: main 40 | artifacts: report 41 | folders: artifacts/CodeQL 42 | - sdle_project_id: 20340 43 | owner: open-amt-cloud-toolkit 44 | repo: ui-toolkit-angular 45 | branch: main 46 | artifacts: report 47 | folders: artifacts/CodeQL 48 | - sdle_project_id: 20340 49 | owner: open-amt-cloud-toolkit 50 | repo: ui-toolkit-react 51 | branch: main 52 | artifacts: report 53 | folders: artifacts/CodeQL 54 | - sdle_project_id: 20340 55 | owner: open-amt-cloud-toolkit 56 | repo: rpc-go 57 | branch: main 58 | artifacts: report 59 | folders: artifacts/CodeQL 60 | - sdle_project_id: 20340 61 | owner: open-amt-cloud-toolkit 62 | repo: wsman-messages 63 | branch: main 64 | artifacts: report 65 | folders: artifacts/CodeQL 66 | - sdle_project_id: 20340 67 | owner: open-amt-cloud-toolkit 68 | repo: go-wsman-messages 69 | branch: main 70 | artifacts: report 71 | folders: artifacts/CodeQL --------------------------------------------------------------------------------