Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fc5121c41e | ||
|
|
6e7ededc30 | ||
|
|
0867ba08f4 | ||
|
|
21ec3b30ad | ||
|
|
219eba67bc | ||
|
|
7c51776c57 | ||
|
|
e73bded6ae | ||
|
|
25a99a4fb6 | ||
|
|
10c128ee3b | ||
|
|
1efc3a08aa | ||
|
|
03376f0ae6 | ||
|
|
13d5c46b1a | ||
|
|
96b648634f | ||
|
|
ec59ee2b1c | ||
|
|
bea40ec622 | ||
|
|
cc0edf311c | ||
|
|
66fb4b2451 | ||
|
|
ec6ec7511e | ||
|
|
9404300a9e | ||
|
|
8cb16dc46c | ||
|
|
f9af4f0092 | ||
|
|
723101b779 | ||
|
|
825c9556b6 | ||
|
|
071e0bd617 | ||
|
|
4e57c863ab | ||
|
|
87f84e0c24 | ||
|
|
fd5143286f | ||
|
|
40ebbf8b09 | ||
|
|
f51124cfdb | ||
|
|
1bea4882ca | ||
|
|
ea3d040b53 | ||
|
|
80d9ce2ec1 | ||
|
|
45931be4da | ||
|
|
c340d9ab89 | ||
|
|
3bcc5aabd8 | ||
|
|
4004431c6a | ||
|
|
3064e51bc1 | ||
|
|
e83bb425af | ||
|
|
27abf9e2d9 | ||
|
|
89e072401c | ||
|
|
85bce84356 | ||
|
|
2bc314d271 | ||
|
|
e60b774d05 | ||
|
|
c6a917d21b | ||
|
|
f9e85aa9aa | ||
|
|
c0cecda312 | ||
|
|
bfd984d248 | ||
|
|
ae5a03250f | ||
|
|
07c25d766e | ||
|
|
12a986b2ba | ||
|
|
5e5c25be82 | ||
|
|
17db3cba68 | ||
|
|
7de68bacae | ||
|
|
74f3ce516b | ||
|
|
6d97b15591 | ||
|
|
72cf7b0d71 | ||
|
|
45db2ad5a6 | ||
|
|
2f27a4cfc0 | ||
|
|
e6642959be | ||
|
|
11009d6f33 | ||
|
|
e9d2f249b8 | ||
|
|
ff6f1ab2ff | ||
|
|
ea578c4207 | ||
|
|
4d02503790 | ||
|
|
355ebb12db | ||
|
|
c177abb978 | ||
|
|
0094cef9f5 | ||
|
|
80b992668d | ||
|
|
365545d61c | ||
|
|
1a7b3f578c | ||
|
|
40c1b3c6b5 | ||
|
|
09c60c7bcb | ||
|
|
7b6f625d3e | ||
|
|
3797bc3a60 | ||
|
|
26adb96396 | ||
|
|
e419b8ee6a | ||
|
|
bca65d8d5a | ||
|
|
f20723df37 | ||
|
|
3f238140b4 | ||
|
|
8788b5ec9a | ||
|
|
e66efa7cc3 | ||
|
|
bc0fc1aa87 | ||
|
|
fc4344c6c5 | ||
|
|
7106f36686 | ||
|
|
28e65dbf4f | ||
|
|
0a9a6c5a67 | ||
|
|
720a9b56ee | ||
|
|
3157525eb6 | ||
|
|
12e0982d4b | ||
|
|
ea460c1391 | ||
|
|
2f6e36c035 | ||
|
|
fc82980d68 | ||
|
|
8d217aab2b | ||
|
|
7e89f28949 | ||
|
|
5a7e09c70c | ||
|
|
a92701701c | ||
|
|
6397cd80a6 | ||
|
|
9b403b3159 | ||
|
|
9b1f052a56 | ||
|
|
7e5db0bc3d | ||
|
|
966e16863a | ||
|
|
c0b1373851 | ||
|
|
b9b4e33f5a | ||
|
|
534c4419e7 | ||
|
|
1c65de4a80 | ||
|
|
5c8e93f5e9 | ||
|
|
5e3e61bc49 | ||
|
|
2394df8435 | ||
|
|
a1655312fd | ||
|
|
fcb9468c59 | ||
|
|
3692922b3b | ||
|
|
0691b57e40 | ||
|
|
87e0a075c1 | ||
|
|
a6b9ae4610 | ||
|
|
e75e908340 | ||
|
|
9ca1beaa0e | ||
|
|
91fe148df4 | ||
|
|
4cb9565ca0 | ||
|
|
eddbdb23d0 | ||
|
|
5762b0df4d | ||
|
|
e421b8efc0 | ||
|
|
2d1e15a7bb | ||
|
|
dd92321b81 | ||
|
|
dce45031cb | ||
|
|
2666ec8244 | ||
|
|
3674d07762 | ||
|
|
dccf06cb0c | ||
|
|
c64e8a2993 | ||
|
|
5ae490c28c | ||
|
|
bedcdee048 | ||
|
|
bd394d9517 | ||
|
|
a6bdc4fa24 | ||
|
|
3e9a06a5b5 | ||
|
|
19908768a4 | ||
|
|
4274a045f7 | ||
|
|
1270458430 | ||
|
|
4c342061d3 | ||
|
|
5ce83d9239 | ||
|
|
148f2db941 | ||
|
|
f65f483611 | ||
|
|
cc9003a118 | ||
|
|
20f8c99013 | ||
|
|
536ebc1c0f | ||
|
|
79a932bebb | ||
|
|
f246c24a08 | ||
|
|
d31cfca138 | ||
|
|
298e804500 | ||
|
|
f9cd1c331f | ||
|
|
a0fa66a14d | ||
|
|
086d9da028 | ||
|
|
9b20b150eb | ||
|
|
6bbddc56b1 | ||
|
|
0870a8f623 | ||
|
|
98c16ad422 | ||
|
|
9156c8612e | ||
|
|
a43756895d | ||
|
|
adc50a939f | ||
|
|
37cbb74c76 | ||
|
|
80b633a063 | ||
|
|
bd65c91ff9 | ||
|
|
c550faddb4 | ||
|
|
5e7c25a1fa | ||
|
|
ded8bdadd1 | ||
|
|
13da35c06b | ||
|
|
d52957d87b | ||
|
|
33d359e692 | ||
|
|
626bdc2c92 | ||
|
|
edba33bbda | ||
|
|
5d32d987bc | ||
|
|
6c59baa413 | ||
|
|
c2c0b38187 | ||
|
|
1d7892230c | ||
|
|
ece9c9b0c8 | ||
|
|
9a43c74e60 | ||
|
|
eb4ec5f6de | ||
|
|
a39b208b48 | ||
|
|
22353e7df6 | ||
|
|
713ffd8d1b | ||
|
|
6e75439652 | ||
|
|
be96daa499 | ||
|
|
9f11e8a25d | ||
|
|
8be4e93a3c | ||
|
|
a78522e09a | ||
|
|
a26662eca5 | ||
|
|
d72fa0d6e3 | ||
|
|
bd5e3da1f4 | ||
|
|
f74f4d4a20 | ||
|
|
9bd45164bf | ||
|
|
363879c3c3 | ||
|
|
0b4fd6765e | ||
|
|
c8839d6db1 | ||
|
|
ac5110d94a | ||
|
|
78bcc103c2 | ||
|
|
fe0cffdf0b | ||
|
|
79f4c2bc5d | ||
|
|
9843310dfb | ||
|
|
db75b2e292 | ||
|
|
ac1d98bbec | ||
|
|
0c6744581d | ||
|
|
fb345f045e | ||
|
|
b1085def48 | ||
|
|
499b0fde31 | ||
|
|
bbf9c95267 | ||
|
|
2dbcc1c0af | ||
|
|
6d88206491 | ||
|
|
de20df445c | ||
|
|
45ad7a8f3b | ||
|
|
798cfc6828 | ||
|
|
d93986c4e2 | ||
|
|
879c196887 | ||
|
|
98170ed01e | ||
|
|
47a218cf8f | ||
|
|
879a58dcb8 | ||
|
|
f100190ac1 | ||
|
|
0902e42cb0 | ||
|
|
6b0958e4d8 | ||
|
|
82ea70f44b | ||
|
|
0bb72040db | ||
|
|
9d9a38510b | ||
|
|
a54aecee07 | ||
|
|
7dab184bb9 | ||
|
|
f068ac0b0c | ||
|
|
d07c33ca41 | ||
|
|
f073de774d | ||
|
|
1040a05880 | ||
|
|
002f64d676 | ||
|
|
c09efbae10 | ||
|
|
060f995f94 | ||
|
|
f1c5c99664 | ||
|
|
af5fb8e814 | ||
|
|
cf5334556f | ||
|
|
5c6c9bb69f | ||
|
|
26a77edbc7 | ||
|
|
3fc865d226 | ||
|
|
47d7ceccf7 | ||
|
|
38df28be55 | ||
|
|
6d7c86a08c | ||
|
|
58a31b880b | ||
|
|
453ab7911d | ||
|
|
93c8d481fd | ||
|
|
956f6fd04d | ||
|
|
912be13744 | ||
|
|
fc1b91c8f9 | ||
|
|
8e40b01caf | ||
|
|
20181c978f | ||
|
|
db78f1ae4d | ||
|
|
592bb15022 | ||
|
|
f002e14673 | ||
|
|
a1b455e5eb | ||
|
|
786e6130cd | ||
|
|
4db8b8e1e7 | ||
|
|
4be8d10323 | ||
|
|
c79a1fca79 | ||
|
|
d2d332b7d1 | ||
|
|
022ac0fffe | ||
|
|
f3622fb92b | ||
|
|
f8b5dcd824 | ||
|
|
056008e13e | ||
|
|
ea03d6e488 |
No files matched your search
+2
-2
@@ -1,8 +1,8 @@
|
||||
schema_version = 1
|
||||
|
||||
project {
|
||||
license = "MPL-2.0"
|
||||
copyright_year = 2020
|
||||
license = "BUSL-1.1"
|
||||
copyright_year = 2024
|
||||
|
||||
# (OPTIONAL) A list of globs that should not have copyright/license headers.
|
||||
# Supports doublestar glob patterns for more flexibility in defining which
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Copyright (c) HashiCorp, Inc.
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
# SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
contact_links:
|
||||
- name: Ask a question
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
# Copyright (c) HashiCorp, Inc.
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
# SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
addons:
|
||||
- changed-files:
|
||||
|
||||
@@ -1,24 +1,15 @@
|
||||
:tickets: [Jira ticket](https://hashicorp.atlassian.net/browse/JIRA_TICKET_NUMBER)
|
||||
|
||||
## Description
|
||||
|
||||
# Description
|
||||
<!-- Add a brief description of changes here -->
|
||||
|
||||
## Screenshots (if appropriate):
|
||||
<!-- Uncomment line below to manually add link to JIRA ticket -->
|
||||
<!-- :tickets: [Jira ticket](https://hashicorp.atlassian.net/browse/JIRA_TICKET_NUMBER) -->
|
||||
|
||||
## Screenshots (if appropriate)
|
||||
|
||||
## How to Test
|
||||
|
||||
<!-- Add steps to test this change. Include any other necessary relevant links -->
|
||||
|
||||
<!--
|
||||
Replace PATH_TO_FEATURE with Vercel link
|
||||
-->
|
||||
|
||||
:technologist: [Admin preview](PATH_TO_FEATURE)
|
||||
|
||||
:desktop_computer: [Desktop preview](PATH_TO_FEATURE)
|
||||
|
||||
## Checklist:
|
||||
## Checklist
|
||||
<!-- strikethrough the checklist item that is not relevant to your change -->
|
||||
|
||||
- [ ] I have added before and after screenshots for UI changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (c) HashiCorp, Inc.
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
# SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
|
||||
@@ -11,25 +11,25 @@ jobs:
|
||||
name: Install dependencies
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
|
||||
id: node-modules-cache
|
||||
with:
|
||||
path: "**/node_modules"
|
||||
key: node-modules-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
node-modules-
|
||||
- uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: 16
|
||||
node-version: 20
|
||||
- run: yarn install
|
||||
build-admin-ui-oss:
|
||||
name: Build Admin UI OSS
|
||||
needs: [dependencies]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
|
||||
id: node-modules-cache
|
||||
with:
|
||||
path: "**/node_modules"
|
||||
@@ -37,17 +37,17 @@ jobs:
|
||||
restore-keys: |
|
||||
node-modules-
|
||||
- name: Build
|
||||
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: 16
|
||||
node-version: 20
|
||||
- run: yarn run build:ui:admin:oss
|
||||
- name: Upload artifact admin-ui
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
|
||||
with:
|
||||
name: admin-ui
|
||||
path: ./ui/admin/dist/
|
||||
- name: Upload artifact OSS admin UI
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
|
||||
with:
|
||||
name: admin-ui-oss
|
||||
path: ./ui/admin/dist/
|
||||
@@ -56,8 +56,8 @@ jobs:
|
||||
needs: [dependencies]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
|
||||
id: node-modules-cache
|
||||
with:
|
||||
path: "**/node_modules"
|
||||
@@ -65,12 +65,12 @@ jobs:
|
||||
restore-keys: |
|
||||
node-modules-
|
||||
- name: Build
|
||||
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: 16
|
||||
node-version: 20
|
||||
- run: yarn run build:ui:admin:enterprise
|
||||
- name: Upload artifact enterprise admin UI
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
|
||||
with:
|
||||
name: admin-ui-ent
|
||||
path: ./ui/admin/dist/
|
||||
@@ -79,8 +79,8 @@ jobs:
|
||||
needs: [dependencies]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
|
||||
id: node-modules-cache
|
||||
with:
|
||||
path: "**/node_modules"
|
||||
@@ -88,12 +88,12 @@ jobs:
|
||||
restore-keys: |
|
||||
node-modules-
|
||||
- name: Build
|
||||
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: 16
|
||||
node-version: 20
|
||||
- run: yarn run build:ui:admin:hcp
|
||||
- name: Upload artifact HCP admin UI
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
|
||||
with:
|
||||
name: admin-ui-hcp
|
||||
path: ./ui/admin/dist/
|
||||
@@ -30,11 +30,11 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@4b6aa0b07da05d6e43d0e5f9c8596a6532ce1c85 # codeql-bundle-v2.15.3
|
||||
uses: github/codeql-action/init@8f1a6fed33af5212fab8a999d004627ae8901d1b # codeql-bundle-v2.17.5
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
@@ -54,4 +54,4 @@ jobs:
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@4b6aa0b07da05d6e43d0e5f9c8596a6532ce1c85 # codeql-bundle-v2.15.3
|
||||
uses: github/codeql-action/analyze@8f1a6fed33af5212fab8a999d004627ae8901d1b # codeql-bundle-v2.17.5
|
||||
@@ -0,0 +1,10 @@
|
||||
name: Check Copyright Headers
|
||||
on: pull_request
|
||||
jobs:
|
||||
copywrite:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- uses: hashicorp/setup-copywrite@32638da2d4e81d56a0764aa1547882fc4d209636 # v1.1.3
|
||||
- name: Check Header Compliance
|
||||
run: copywrite headers --plan
|
||||
+39
-20
@@ -29,13 +29,6 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.JIRA_SYNC_GITHUB_TOKEN }}
|
||||
|
||||
- name: Login
|
||||
uses: atlassian/gajira-login@45fd029b9f1d6d8926c6f04175aa80c0e42c9026 # v3.0.1
|
||||
env:
|
||||
JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }}
|
||||
JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }}
|
||||
JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }}
|
||||
|
||||
- name: Set ticket type
|
||||
if: github.event.action == 'opened' && !steps.boundary-team-role.outputs.role
|
||||
id: set-ticket-type
|
||||
@@ -49,6 +42,10 @@ jobs:
|
||||
- name: Create ticket
|
||||
if: github.event.action == 'opened' && !steps.boundary-team-role.outputs.role
|
||||
uses: tomhjp/gh-action-jira-create@3ed1789cad3521292e591a7cfa703215ec1348bf # v0.2.1
|
||||
env:
|
||||
JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }}
|
||||
JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }}
|
||||
JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }}
|
||||
with:
|
||||
project: ICU
|
||||
issuetype: "GH Issue"
|
||||
@@ -62,27 +59,49 @@ jobs:
|
||||
if: github.event.action != 'opened'
|
||||
id: search
|
||||
uses: tomhjp/gh-action-jira-search@04700b457f317c3e341ce90da5a3ff4ce058f2fa # v0.2.2
|
||||
env:
|
||||
JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }}
|
||||
JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }}
|
||||
JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }}
|
||||
with:
|
||||
# cf[10089] is Issue Link custom field
|
||||
jql: 'issuetype = "GH Issue" and cf[10089]="${{ github.event.issue.html_url || github.event.pull_request.html_url }}"'
|
||||
|
||||
- name: Sync comment
|
||||
if: github.event.action == 'created' && steps.search.outputs.issue
|
||||
uses: atlassian/gajira-comment@164913891625fe50e9836957902e0bf7d9ef99a8 # v3.0.1
|
||||
uses: tomhjp/gh-action-jira-comment@6eb6b9ead70221916b6badd118c24535ed220bd9 # v0.2.0
|
||||
env:
|
||||
JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }}
|
||||
JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }}
|
||||
JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }}
|
||||
with:
|
||||
issue: ${{ steps.search.outputs.issue }}
|
||||
comment: "${{ github.actor }} ${{ github.event.review.state || 'commented' }}:\n\n${{ github.event.comment.body || github.event.review.body }}\n\n${{ github.event.comment.html_url || github.event.review.html_url }}"
|
||||
|
||||
- name: Close ticket
|
||||
if: (github.event.action == 'closed' || github.event.action == 'deleted') && steps.search.outputs.issue
|
||||
uses: atlassian/gajira-transition@38fc9cd61b03d6a53dd35fcccda172fe04b36de3 # v3.0.1
|
||||
with:
|
||||
issue: ${{ steps.search.outputs.issue }}
|
||||
transition: Done
|
||||
- name: Transitions
|
||||
id: transitions
|
||||
if: steps.search.outputs.issue
|
||||
run: |
|
||||
if [[ "${{ github.event.action }}" == "closed" || "${{ github.event.action }}" == "deleted" ]]; then
|
||||
echo "Closing ticket"
|
||||
echo "name=Done" >> "$GITHUB_OUTPUT"
|
||||
elif [[ "${{ github.event.action }}" == "reopened" ]]; then
|
||||
echo "Reopening ticket"
|
||||
echo "name=Reopen" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
- name: Reopen ticket
|
||||
if: github.event.action == 'reopened' && steps.search.outputs.issue
|
||||
uses: atlassian/gajira-transition@38fc9cd61b03d6a53dd35fcccda172fe04b36de3 # v3.0.1
|
||||
with:
|
||||
issue: ${{ steps.search.outputs.issue }}
|
||||
transition: "To Do"
|
||||
# Transition issue API reference: https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issues/#api-rest-api-3-issue-issueidorkey-transitions-post
|
||||
- name: Transition ticket
|
||||
if: steps.transitions.outputs.name
|
||||
run: |
|
||||
transitions="$(curl --silent \
|
||||
--url "${{ secrets.JIRA_BASE_URL }}rest/api/3/issue/${{ steps.search.outputs.issue }}/transitions" \
|
||||
--user "${{ secrets.JIRA_USER_EMAIL }}:${{ secrets.JIRA_API_TOKEN }}" \
|
||||
--header "Accept: application/json")"
|
||||
id="$(echo "${transitions}" | jq -r '.transitions[] | select(.name == "${{ steps.transitions.outputs.name }}") | .id')"
|
||||
curl --silent \
|
||||
--url "${{ secrets.JIRA_BASE_URL }}rest/api/3/issue/${{ steps.search.outputs.issue }}/transitions" \
|
||||
--user "${{ secrets.JIRA_USER_EMAIL }}:${{ secrets.JIRA_API_TOKEN }}" \
|
||||
--header "Accept: application/json" \
|
||||
--header "Content-Type: application/json" \
|
||||
--data "$(printf '{"transition": {"id": "%s"}}' "${id}")"
|
||||
@@ -6,17 +6,17 @@ jobs:
|
||||
name: Install dependencies
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
|
||||
id: node-modules-cache
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: node-modules-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
node-modules-
|
||||
- uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: 16
|
||||
node-version: 20
|
||||
- run: yarn install
|
||||
|
||||
compliance:
|
||||
@@ -24,17 +24,17 @@ jobs:
|
||||
needs: [dependencies]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
|
||||
id: node-modules-cache
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: node-modules-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
node-modules-
|
||||
- uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: 16
|
||||
node-version: 20
|
||||
- run: yarn run compliance:licenses
|
||||
|
||||
lint:
|
||||
@@ -43,17 +43,17 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
|
||||
id: node-modules-cache
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: node-modules-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
node-modules-
|
||||
- uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: 16
|
||||
node-version: 20
|
||||
- run: yarn lint
|
||||
|
||||
test:
|
||||
@@ -62,13 +62,13 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
|
||||
id: node-modules-cache
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: node-modules-${{ hashFiles('**/yarn.lock') }}
|
||||
- uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: 16
|
||||
node-version: 20
|
||||
- run: yarn test
|
||||
@@ -7,7 +7,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
with:
|
||||
token: ${{ secrets.ELEVATED_GITHUB_TOKEN }}
|
||||
- run: |
|
||||
|
||||
@@ -9,7 +9,7 @@ jobs:
|
||||
trigger-gha-release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- name: Release description
|
||||
run: |
|
||||
echo "Triggering release with a TAG ${GITHUB_REF#refs/tags/}"
|
||||
|
||||
+19
@@ -21,3 +21,22 @@ npm-debug.log*
|
||||
testem.log
|
||||
yarn-error.log
|
||||
.watchman-cookie*
|
||||
|
||||
### VisualStudioCode ###
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
!.vscode/*.code-snippets
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Built Visual Studio Code Extensions
|
||||
*.vsix
|
||||
|
||||
### VisualStudioCode Patch ###
|
||||
# Ignore all local history of files
|
||||
.history
|
||||
.ionide
|
||||
@@ -1,5 +1,5 @@
|
||||
# Copyright (c) HashiCorp, Inc.
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
# SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
url_license = "https://github.com/hashicorp/boundary-ui/blob/main/LICENSE"
|
||||
url_project_website = "https://learn.hashicorp.com/tutorials/boundary/getting-started-desktop-app"
|
||||
|
||||
@@ -1,364 +1,91 @@
|
||||
Copyright (c) 2020 HashiCorp, Inc.
|
||||
|
||||
Mozilla Public License, version 2.0
|
||||
|
||||
1. Definitions
|
||||
|
||||
1.1. "Contributor"
|
||||
|
||||
means each individual or legal entity that creates, contributes to the
|
||||
creation of, or owns Covered Software.
|
||||
|
||||
1.2. "Contributor Version"
|
||||
|
||||
means the combination of the Contributions of others (if any) used by a
|
||||
Contributor and that particular Contributor's Contribution.
|
||||
|
||||
1.3. "Contribution"
|
||||
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
1.4. "Covered Software"
|
||||
|
||||
means Source Code Form to which the initial Contributor has attached the
|
||||
notice in Exhibit A, the Executable Form of such Source Code Form, and
|
||||
Modifications of such Source Code Form, in each case including portions
|
||||
thereof.
|
||||
|
||||
1.5. "Incompatible With Secondary Licenses"
|
||||
means
|
||||
|
||||
a. that the initial Contributor has attached the notice described in
|
||||
Exhibit B to the Covered Software; or
|
||||
|
||||
b. that the Covered Software was made available under the terms of
|
||||
version 1.1 or earlier of the License, but not also under the terms of
|
||||
a Secondary License.
|
||||
|
||||
1.6. "Executable Form"
|
||||
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. "Larger Work"
|
||||
|
||||
means a work that combines Covered Software with other material, in a
|
||||
separate file or files, that is not Covered Software.
|
||||
|
||||
1.8. "License"
|
||||
|
||||
means this document.
|
||||
|
||||
1.9. "Licensable"
|
||||
|
||||
means having the right to grant, to the maximum extent possible, whether
|
||||
at the time of the initial grant or subsequently, any and all of the
|
||||
rights conveyed by this License.
|
||||
|
||||
1.10. "Modifications"
|
||||
|
||||
means any of the following:
|
||||
|
||||
a. any file in Source Code Form that results from an addition to,
|
||||
deletion from, or modification of the contents of Covered Software; or
|
||||
|
||||
b. any new file in Source Code Form that contains any Covered Software.
|
||||
|
||||
1.11. "Patent Claims" of a Contributor
|
||||
|
||||
means any patent claim(s), including without limitation, method,
|
||||
process, and apparatus claims, in any patent Licensable by such
|
||||
Contributor that would be infringed, but for the grant of the License,
|
||||
by the making, using, selling, offering for sale, having made, import,
|
||||
or transfer of either its Contributions or its Contributor Version.
|
||||
|
||||
1.12. "Secondary License"
|
||||
|
||||
means either the GNU General Public License, Version 2.0, the GNU Lesser
|
||||
General Public License, Version 2.1, the GNU Affero General Public
|
||||
License, Version 3.0, or any later versions of those licenses.
|
||||
|
||||
1.13. "Source Code Form"
|
||||
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
1.14. "You" (or "Your")
|
||||
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, "You" includes any entity that controls, is
|
||||
controlled by, or is under common control with You. For purposes of this
|
||||
definition, "control" means (a) the power, direct or indirect, to cause
|
||||
the direction or management of such entity, whether by contract or
|
||||
otherwise, or (b) ownership of more than fifty percent (50%) of the
|
||||
outstanding shares or beneficial ownership of such entity.
|
||||
|
||||
|
||||
2. License Grants and Conditions
|
||||
|
||||
2.1. Grants
|
||||
|
||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
a. under intellectual property rights (other than patent or trademark)
|
||||
Licensable by such Contributor to use, reproduce, make available,
|
||||
modify, display, perform, distribute, and otherwise exploit its
|
||||
Contributions, either on an unmodified basis, with Modifications, or
|
||||
as part of a Larger Work; and
|
||||
|
||||
b. under Patent Claims of such Contributor to make, use, sell, offer for
|
||||
sale, have made, import, and otherwise transfer either its
|
||||
Contributions or its Contributor Version.
|
||||
|
||||
2.2. Effective Date
|
||||
|
||||
The licenses granted in Section 2.1 with respect to any Contribution
|
||||
become effective for each Contribution on the date the Contributor first
|
||||
distributes such Contribution.
|
||||
|
||||
2.3. Limitations on Grant Scope
|
||||
|
||||
The licenses granted in this Section 2 are the only rights granted under
|
||||
this License. No additional rights or licenses will be implied from the
|
||||
distribution or licensing of Covered Software under this License.
|
||||
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
||||
Contributor:
|
||||
|
||||
a. for any code that a Contributor has removed from Covered Software; or
|
||||
|
||||
b. for infringements caused by: (i) Your and any other third party's
|
||||
modifications of Covered Software, or (ii) the combination of its
|
||||
Contributions with other software (except as part of its Contributor
|
||||
Version); or
|
||||
|
||||
c. under Patent Claims infringed by Covered Software in the absence of
|
||||
its Contributions.
|
||||
|
||||
This License does not grant any rights in the trademarks, service marks,
|
||||
or logos of any Contributor (except as may be necessary to comply with
|
||||
the notice requirements in Section 3.4).
|
||||
|
||||
2.4. Subsequent Licenses
|
||||
|
||||
No Contributor makes additional grants as a result of Your choice to
|
||||
distribute the Covered Software under a subsequent version of this
|
||||
License (see Section 10.2) or under the terms of a Secondary License (if
|
||||
permitted under the terms of Section 3.3).
|
||||
|
||||
2.5. Representation
|
||||
|
||||
Each Contributor represents that the Contributor believes its
|
||||
Contributions are its original creation(s) or it has sufficient rights to
|
||||
grant the rights to its Contributions conveyed by this License.
|
||||
|
||||
2.6. Fair Use
|
||||
|
||||
This License is not intended to limit any rights You have under
|
||||
applicable copyright doctrines of fair use, fair dealing, or other
|
||||
equivalents.
|
||||
|
||||
2.7. Conditions
|
||||
|
||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
|
||||
Section 2.1.
|
||||
|
||||
|
||||
3. Responsibilities
|
||||
|
||||
3.1. Distribution of Source Form
|
||||
|
||||
All distribution of Covered Software in Source Code Form, including any
|
||||
Modifications that You create or to which You contribute, must be under
|
||||
the terms of this License. You must inform recipients that the Source
|
||||
Code Form of the Covered Software is governed by the terms of this
|
||||
License, and how they can obtain a copy of this License. You may not
|
||||
attempt to alter or restrict the recipients' rights in the Source Code
|
||||
Form.
|
||||
|
||||
3.2. Distribution of Executable Form
|
||||
|
||||
If You distribute Covered Software in Executable Form then:
|
||||
|
||||
a. such Covered Software must also be made available in Source Code Form,
|
||||
as described in Section 3.1, and You must inform recipients of the
|
||||
Executable Form how they can obtain a copy of such Source Code Form by
|
||||
reasonable means in a timely manner, at a charge no more than the cost
|
||||
of distribution to the recipient; and
|
||||
|
||||
b. You may distribute such Executable Form under the terms of this
|
||||
License, or sublicense it under different terms, provided that the
|
||||
license for the Executable Form does not attempt to limit or alter the
|
||||
recipients' rights in the Source Code Form under this License.
|
||||
|
||||
3.3. Distribution of a Larger Work
|
||||
|
||||
You may create and distribute a Larger Work under terms of Your choice,
|
||||
provided that You also comply with the requirements of this License for
|
||||
the Covered Software. If the Larger Work is a combination of Covered
|
||||
Software with a work governed by one or more Secondary Licenses, and the
|
||||
Covered Software is not Incompatible With Secondary Licenses, this
|
||||
License permits You to additionally distribute such Covered Software
|
||||
under the terms of such Secondary License(s), so that the recipient of
|
||||
the Larger Work may, at their option, further distribute the Covered
|
||||
Software under the terms of either this License or such Secondary
|
||||
License(s).
|
||||
|
||||
3.4. Notices
|
||||
|
||||
You may not remove or alter the substance of any license notices
|
||||
(including copyright notices, patent notices, disclaimers of warranty, or
|
||||
limitations of liability) contained within the Source Code Form of the
|
||||
Covered Software, except that You may alter any license notices to the
|
||||
extent required to remedy known factual inaccuracies.
|
||||
|
||||
3.5. Application of Additional Terms
|
||||
|
||||
You may choose to offer, and to charge a fee for, warranty, support,
|
||||
indemnity or liability obligations to one or more recipients of Covered
|
||||
Software. However, You may do so only on Your own behalf, and not on
|
||||
behalf of any Contributor. You must make it absolutely clear that any
|
||||
such warranty, support, indemnity, or liability obligation is offered by
|
||||
You alone, and You hereby agree to indemnify every Contributor for any
|
||||
liability incurred by such Contributor as a result of warranty, support,
|
||||
indemnity or liability terms You offer. You may include additional
|
||||
disclaimers of warranty and limitations of liability specific to any
|
||||
jurisdiction.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this License
|
||||
with respect to some or all of the Covered Software due to statute,
|
||||
judicial order, or regulation then You must: (a) comply with the terms of
|
||||
this License to the maximum extent possible; and (b) describe the
|
||||
limitations and the code they affect. Such description must be placed in a
|
||||
text file included with all distributions of the Covered Software under
|
||||
this License. Except to the extent prohibited by statute or regulation,
|
||||
such description must be sufficiently detailed for a recipient of ordinary
|
||||
skill to be able to understand it.
|
||||
|
||||
5. Termination
|
||||
|
||||
5.1. The rights granted under this License will terminate automatically if You
|
||||
fail to comply with any of its terms. However, if You become compliant,
|
||||
then the rights granted under this License from a particular Contributor
|
||||
are reinstated (a) provisionally, unless and until such Contributor
|
||||
explicitly and finally terminates Your grants, and (b) on an ongoing
|
||||
basis, if such Contributor fails to notify You of the non-compliance by
|
||||
some reasonable means prior to 60 days after You have come back into
|
||||
compliance. Moreover, Your grants from a particular Contributor are
|
||||
reinstated on an ongoing basis if such Contributor notifies You of the
|
||||
non-compliance by some reasonable means, this is the first time You have
|
||||
received notice of non-compliance with this License from such
|
||||
Contributor, and You become compliant prior to 30 days after Your receipt
|
||||
of the notice.
|
||||
|
||||
5.2. If You initiate litigation against any entity by asserting a patent
|
||||
infringement claim (excluding declaratory judgment actions,
|
||||
counter-claims, and cross-claims) alleging that a Contributor Version
|
||||
directly or indirectly infringes any patent, then the rights granted to
|
||||
You by any and all Contributors for the Covered Software under Section
|
||||
2.1 of this License shall terminate.
|
||||
|
||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
|
||||
license agreements (excluding distributors and resellers) which have been
|
||||
validly granted by You or Your distributors under this License prior to
|
||||
termination shall survive termination.
|
||||
|
||||
6. Disclaimer of Warranty
|
||||
|
||||
Covered Software is provided under this License on an "as is" basis,
|
||||
without warranty of any kind, either expressed, implied, or statutory,
|
||||
including, without limitation, warranties that the Covered Software is free
|
||||
of defects, merchantable, fit for a particular purpose or non-infringing.
|
||||
The entire risk as to the quality and performance of the Covered Software
|
||||
is with You. Should any Covered Software prove defective in any respect,
|
||||
You (not any Contributor) assume the cost of any necessary servicing,
|
||||
repair, or correction. This disclaimer of warranty constitutes an essential
|
||||
part of this License. No use of any Covered Software is authorized under
|
||||
this License except under this disclaimer.
|
||||
|
||||
7. Limitation of Liability
|
||||
|
||||
Under no circumstances and under no legal theory, whether tort (including
|
||||
negligence), contract, or otherwise, shall any Contributor, or anyone who
|
||||
distributes Covered Software as permitted above, be liable to You for any
|
||||
direct, indirect, special, incidental, or consequential damages of any
|
||||
character including, without limitation, damages for lost profits, loss of
|
||||
goodwill, work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses, even if such party shall have been
|
||||
informed of the possibility of such damages. This limitation of liability
|
||||
shall not apply to liability for death or personal injury resulting from
|
||||
such party's negligence to the extent applicable law prohibits such
|
||||
limitation. Some jurisdictions do not allow the exclusion or limitation of
|
||||
incidental or consequential damages, so this exclusion and limitation may
|
||||
not apply to You.
|
||||
|
||||
8. Litigation
|
||||
|
||||
Any litigation relating to this License may be brought only in the courts
|
||||
of a jurisdiction where the defendant maintains its principal place of
|
||||
business and such litigation shall be governed by laws of that
|
||||
jurisdiction, without reference to its conflict-of-law provisions. Nothing
|
||||
in this Section shall prevent a party's ability to bring cross-claims or
|
||||
counter-claims.
|
||||
|
||||
9. Miscellaneous
|
||||
|
||||
This License represents the complete agreement concerning the subject
|
||||
matter hereof. If any provision of this License is held to be
|
||||
unenforceable, such provision shall be reformed only to the extent
|
||||
necessary to make it enforceable. Any law or regulation which provides that
|
||||
the language of a contract shall be construed against the drafter shall not
|
||||
be used to construe this License against a Contributor.
|
||||
|
||||
|
||||
10. Versions of the License
|
||||
|
||||
10.1. New Versions
|
||||
|
||||
Mozilla Foundation is the license steward. Except as provided in Section
|
||||
10.3, no one other than the license steward has the right to modify or
|
||||
publish new versions of this License. Each version will be given a
|
||||
distinguishing version number.
|
||||
|
||||
10.2. Effect of New Versions
|
||||
|
||||
You may distribute the Covered Software under the terms of the version
|
||||
of the License under which You originally received the Covered Software,
|
||||
or under the terms of any subsequent version published by the license
|
||||
steward.
|
||||
|
||||
10.3. Modified Versions
|
||||
|
||||
If you create software not governed by this License, and you want to
|
||||
create a new license for such software, you may create and use a
|
||||
modified version of this License if you rename the license and remove
|
||||
any references to the name of the license steward (except to note that
|
||||
such modified license differs from this License).
|
||||
|
||||
10.4. Distributing Source Code Form that is Incompatible With Secondary
|
||||
Licenses If You choose to distribute Source Code Form that is
|
||||
Incompatible With Secondary Licenses under the terms of this version of
|
||||
the License, the notice described in Exhibit B of this License must be
|
||||
attached.
|
||||
|
||||
Exhibit A - Source Code Form License Notice
|
||||
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file,
|
||||
then You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a
|
||||
notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
|
||||
Exhibit B - "Incompatible With Secondary Licenses" Notice
|
||||
|
||||
This Source Code Form is "Incompatible
|
||||
With Secondary Licenses", as defined by
|
||||
the Mozilla Public License, v. 2.0.
|
||||
License text copyright (c) 2020 MariaDB Corporation Ab, All Rights Reserved.
|
||||
"Business Source License" is a trademark of MariaDB Corporation Ab.
|
||||
|
||||
Parameters
|
||||
|
||||
Licensor: HashiCorp, Inc.
|
||||
Licensed Work: The Licensed Work is (c) 2024 HashiCorp, Inc.
|
||||
Additional Use Grant: You may make production use of the Licensed Work, provided
|
||||
Your use does not include offering the Licensed Work to third
|
||||
parties on a hosted or embedded basis in order to compete with
|
||||
HashiCorp's paid version(s) of the Licensed Work. For purposes
|
||||
of this license:
|
||||
|
||||
A "competitive offering" is a Product that is offered to third
|
||||
parties on a paid basis, including through paid support
|
||||
arrangements, that significantly overlaps with the capabilities
|
||||
of HashiCorp's paid version(s) of the Licensed Work. If Your
|
||||
Product is not a competitive offering when You first make it
|
||||
generally available, it will not become a competitive offering
|
||||
later due to HashiCorp releasing a new version of the Licensed
|
||||
Work with additional capabilities. In addition, Products that
|
||||
are not provided on a paid basis are not competitive.
|
||||
|
||||
"Product" means software that is offered to end users to manage
|
||||
in their own environments or offered as a service on a hosted
|
||||
basis.
|
||||
|
||||
"Embedded" means including the source code or executable code
|
||||
from the Licensed Work in a competitive offering. "Embedded"
|
||||
also means packaging the competitive offering in such a way
|
||||
that the Licensed Work must be accessed or downloaded for the
|
||||
competitive offering to operate.
|
||||
|
||||
Hosting or using the Licensed Work(s) for internal purposes
|
||||
within an organization is not considered a competitive
|
||||
offering. HashiCorp considers your organization to include all
|
||||
of your affiliates under common control.
|
||||
|
||||
For binding interpretive guidance on using HashiCorp products
|
||||
under the Business Source License, please visit our FAQ.
|
||||
(https://www.hashicorp.com/license-faq)
|
||||
Change Date: Four years from the date the Licensed Work is published.
|
||||
Change License: MPL 2.0
|
||||
|
||||
For information about alternative licensing arrangements for the Licensed Work,
|
||||
please contact licensing@hashicorp.com.
|
||||
|
||||
Notice
|
||||
|
||||
Business Source License 1.1
|
||||
|
||||
Terms
|
||||
|
||||
The Licensor hereby grants you the right to copy, modify, create derivative
|
||||
works, redistribute, and make non-production use of the Licensed Work. The
|
||||
Licensor may make an Additional Use Grant, above, permitting limited production use.
|
||||
|
||||
Effective on the Change Date, or the fourth anniversary of the first publicly
|
||||
available distribution of a specific version of the Licensed Work under this
|
||||
License, whichever comes first, the Licensor hereby grants you rights under
|
||||
the terms of the Change License, and the rights granted in the paragraph
|
||||
above terminate.
|
||||
|
||||
If your use of the Licensed Work does not comply with the requirements
|
||||
currently in effect as described in this License, you must purchase a
|
||||
commercial license from the Licensor, its affiliated entities, or authorized
|
||||
resellers, or you must refrain from using the Licensed Work.
|
||||
|
||||
All copies of the original and modified Licensed Work, and derivative works
|
||||
of the Licensed Work, are subject to this License. This License applies
|
||||
separately for each version of the Licensed Work and the Change Date may vary
|
||||
for each version of the Licensed Work released by Licensor.
|
||||
|
||||
You must conspicuously display this License on each original or modified copy
|
||||
of the Licensed Work. If you receive the Licensed Work in original or
|
||||
modified form from a third party, the terms and conditions set forth in this
|
||||
License apply to your use of that work.
|
||||
|
||||
Any use of the Licensed Work in violation of this License will automatically
|
||||
terminate your rights under this License for the current and all other
|
||||
versions of the Licensed Work.
|
||||
|
||||
This License does not grant you any right in any trademark or logo of
|
||||
Licensor or its affiliates (provided that you may use a trademark or logo of
|
||||
Licensor as expressly required by this License).
|
||||
|
||||
TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
|
||||
AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
|
||||
EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
|
||||
TITLE.
|
||||
@@ -67,7 +67,7 @@ You will need the following things properly installed on your computer.
|
||||
|
||||
* [Git][git]
|
||||
* [Node.js][node]
|
||||
* Supported versions: `v16` and `v18`.
|
||||
* Supported versions: `v18` and `v20`.
|
||||
* [Yarn][yarn] installed globally
|
||||
* [Google Chrome][chrome]
|
||||
* [Firefox][firefox]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
+15
-12
@@ -1,17 +1,19 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import sinon from 'sinon';
|
||||
import { typeOf } from '@ember/utils';
|
||||
import { resourceNames } from 'api/handlers/cache-daemon-handler';
|
||||
import { singularize } from 'ember-inflector';
|
||||
|
||||
/**
|
||||
* This test helper can be used to help setup your sinon stubs in your tests.
|
||||
* Must be called after setupMirage.
|
||||
*
|
||||
* ```js
|
||||
* import setupStubs from 'api/test-support/handlers/client-daemon-search';
|
||||
* import setupStubs from 'api/test-support/handlers/cache-daemon-search';
|
||||
*
|
||||
* module('Acceptance | my test', function(hooks) {
|
||||
* setupApplicationTest(hooks);
|
||||
@@ -23,7 +25,7 @@ import { typeOf } from '@ember/utils';
|
||||
* ```
|
||||
*
|
||||
* This will setup a stub for the IPC service and include helper methods to
|
||||
* help setup what the client daemon search command returns.
|
||||
* help setup what the cache daemon search command returns.
|
||||
*
|
||||
* @module Test Helpers
|
||||
* @public
|
||||
@@ -36,20 +38,20 @@ export default function setupStubs(hooks) {
|
||||
this.ipcStub = sinon.stub(ipcService, 'invoke');
|
||||
|
||||
/**
|
||||
* We aim to still use mirage data when stubbing out the client daemon
|
||||
* We aim to still use mirage data when stubbing out the cache daemon
|
||||
* search. However, the handler expects the search data to be raw JSON from
|
||||
* the API which will get serialized. We add back the scope object for it to
|
||||
* get correctly normalized and other fields such as "attributes" from the
|
||||
* API will already be hoisted and will not be re-normalized from mirage data.
|
||||
*
|
||||
* This convenience method can take in multiple types,
|
||||
* e.g. this.stubClientDaemonSearch('targets', 'sessions').
|
||||
* e.g. this.stubCacheDaemonSearch('targets', 'sessions').
|
||||
* This will have sinon stub out each call so the first call to search will
|
||||
* provide all the models from the first parameter you specify,
|
||||
* the second call will provide all the models from the second argument, etc.
|
||||
* @param types
|
||||
*/
|
||||
this.stubClientDaemonSearch = (...types) => {
|
||||
this.stubCacheDaemonSearch = (...types) => {
|
||||
stubTypes = types;
|
||||
|
||||
types.forEach((type, i) => {
|
||||
@@ -64,7 +66,7 @@ export default function setupStubs(hooks) {
|
||||
}
|
||||
|
||||
this.ipcStub
|
||||
.withArgs('searchClientDaemon')
|
||||
.withArgs('searchCacheDaemon')
|
||||
.onCall(i)
|
||||
.returns({
|
||||
[resourceName]: models.map((model) => {
|
||||
@@ -74,7 +76,7 @@ export default function setupStubs(hooks) {
|
||||
this.server.serializerOrRegistry.serialize(model);
|
||||
|
||||
// Serialize the data properly to standard JSON as that is what
|
||||
// we're expecting from the client daemon response
|
||||
// we're expecting from the cache daemon response
|
||||
return JSON.parse(JSON.stringify(modelData));
|
||||
}),
|
||||
});
|
||||
@@ -84,22 +86,23 @@ export default function setupStubs(hooks) {
|
||||
|
||||
hooks.afterEach(function () {
|
||||
// Verify the number of mocks we set up match with how
|
||||
// many times the client daemon was called with
|
||||
// many times the cache daemon was called with
|
||||
sinon.assert.callCount(
|
||||
this.ipcStub.withArgs('searchClientDaemon'),
|
||||
this.ipcStub.withArgs('searchCacheDaemon'),
|
||||
stubTypes.length,
|
||||
);
|
||||
|
||||
stubTypes.forEach((type, i) => {
|
||||
// Assert that the stub was called with the resource we're trying to mock
|
||||
// so we don't mistakenly mock the wrong resource
|
||||
const ipcCall = this.ipcStub.withArgs('searchClientDaemon').getCall(i);
|
||||
const ipcCall = this.ipcStub.withArgs('searchCacheDaemon').getCall(i);
|
||||
let resource = type;
|
||||
if (typeOf(type) === 'object') {
|
||||
resource = type.resource;
|
||||
}
|
||||
|
||||
sinon.assert.match(ipcCall.args[1], { resource });
|
||||
const mappedResourceName = resourceNames[singularize(resource)];
|
||||
sinon.assert.match(ipcCall.args[1], { resource: mappedResourceName });
|
||||
});
|
||||
|
||||
sinon.restore();
|
||||
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
/**
|
||||
* This test helper can help set up and cleanup the database in your tests.
|
||||
*
|
||||
* ```js
|
||||
* import { setupIndexedDb } from 'api/test-support/helpers/indexed-db';
|
||||
*
|
||||
* module('Acceptance | my test', function(hooks) {
|
||||
* setupApplicationTest(hooks);
|
||||
* setupIndexedDb(hooks);
|
||||
*
|
||||
* // add your actual tests here
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @param hooks
|
||||
*/
|
||||
export function setupIndexedDb(hooks) {
|
||||
hooks.beforeEach(function () {
|
||||
const indexedDb = this.owner.lookup('service:indexed-db');
|
||||
indexedDb.setup(`test-indexed-db-${Date.now()}`);
|
||||
});
|
||||
|
||||
hooks.afterEach(async function () {
|
||||
const indexedDb = this.owner.lookup('service:indexed-db');
|
||||
|
||||
await indexedDb.db.delete();
|
||||
});
|
||||
}
|
||||
|
||||
export default setupIndexedDb;
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import ModelAbility from './model';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import ModelAbility from './model';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import ModelAbility from './model';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import ModelAbility from './model';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import ModelAbility from './model';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import ModelAbility from './model';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import ModelAbility from './model';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import ModelAbility from './model';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import ModelAbility from './model';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import ModelAbility from './model';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import { Ability } from 'ember-can';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import ModelAbility from './model';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import ModelAbility from './model';
|
||||
@@ -27,6 +27,13 @@ export default class RoleAbility extends ModelAbility {
|
||||
return this.hasAuthorizedAction('set-grants');
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
get canSetGrantScopes() {
|
||||
return this.hasAuthorizedAction('set-grant-scopes');
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import ModelAbility from './model';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import ModelAbility from './model';
|
||||
@@ -21,6 +21,14 @@ export default class SessionRecordingAbility extends ModelAbility {
|
||||
return !this.model.isUnknown && super.canRead;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only "known" session recording types may be deleted.
|
||||
* @type {boolean}
|
||||
*/
|
||||
get canDelete() {
|
||||
return !this.model.isUnknown && super.canDelete && this.model.isAvailable;
|
||||
}
|
||||
|
||||
get canDownload() {
|
||||
return this.hasAuthorizedAction('download');
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import ModelAbility from './model';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import ModelAbility from './model';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import ModelAbility from './model';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import ModelAbility from './model';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import ModelAbility from './model';
|
||||
@@ -17,4 +17,18 @@ export default class WorkerAbility extends ModelAbility {
|
||||
get canCreateWorkerLed() {
|
||||
return this.hasAuthorizedCollectionAction('create:worker-led');
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
get canSetWorkerTags() {
|
||||
return this.hasAuthorizedAction('set-worker-tags');
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
get canRemoveTags() {
|
||||
return this.hasAuthorizedAction('remove-worker-tags');
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import RESTAdapter from '@ember-data/adapter/rest';
|
||||
@@ -115,6 +115,7 @@ export default class ApplicationAdapter extends RESTAdapter.extend(
|
||||
* @return {Promise} promise
|
||||
*/
|
||||
async query(store, schema, query) {
|
||||
const queryObject = structuredClone(query);
|
||||
let result;
|
||||
let data = [];
|
||||
|
||||
@@ -128,12 +129,12 @@ export default class ApplicationAdapter extends RESTAdapter.extend(
|
||||
// Run this loop as long as the response_type is delta,
|
||||
// which indicates that there are more items in the list
|
||||
do {
|
||||
result = await super.query(store, schema, query);
|
||||
result = await super.query(store, schema, queryObject);
|
||||
//add the result items to a data array
|
||||
if (result && result.items) {
|
||||
data.push(...result.items);
|
||||
//pass in the list token for subsequent calls to fetch the remaining list items
|
||||
query.list_token = result.list_token;
|
||||
queryObject.list_token = result.list_token;
|
||||
}
|
||||
} while (result && result.response_type === 'delta');
|
||||
|
||||
@@ -211,7 +212,10 @@ export default class ApplicationAdapter extends RESTAdapter.extend(
|
||||
handleResponse(status, headers, payload, requestData) {
|
||||
if (this.isInvalid(status, headers, payload)) {
|
||||
const detailedMessage = this.generatedDetailedMessage(...arguments);
|
||||
const transformedPayload = this.transformValidationErrors(payload);
|
||||
const transformedPayload = this.transformValidationErrors(
|
||||
payload,
|
||||
status,
|
||||
);
|
||||
return new InvalidError(transformedPayload.errors, detailedMessage);
|
||||
}
|
||||
return super.handleResponse(status, headers, payload, requestData);
|
||||
@@ -269,17 +273,18 @@ export default class ApplicationAdapter extends RESTAdapter.extend(
|
||||
* error format.
|
||||
*
|
||||
* @param {object} payload
|
||||
* @param status
|
||||
* @return {object}
|
||||
*/
|
||||
transformValidationErrors(payload) {
|
||||
transformValidationErrors(payload, status) {
|
||||
const fieldErrors = get(payload, 'details.request_fields') || [];
|
||||
// Normalize the primary error message into "base", which is an error
|
||||
// that applies to the whole model instance
|
||||
const baseError = {
|
||||
isInvalid: true,
|
||||
status: payload.source,
|
||||
code: payload.code,
|
||||
detail: payload.message,
|
||||
status,
|
||||
code: payload?.kind,
|
||||
detail: payload?.message,
|
||||
source: { pointer: '/data' },
|
||||
};
|
||||
// Normalize field-specific errors, if any.
|
||||
@@ -314,6 +319,6 @@ export default class ApplicationAdapter extends RESTAdapter.extend(
|
||||
* @return {String} detailed error message
|
||||
*/
|
||||
generatedDetailedMessage(status, headers, payload /*, requestData*/) {
|
||||
return payload.message;
|
||||
return payload?.message;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import ApplicationAdapter from './application';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import ApplicationAdapter from './application';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import ApplicationAdapter from './application';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import BaseModel from '../../models/base';
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import BaseModel from '../../models/base';
|
||||
import { attr } from '@ember-data/model';
|
||||
|
||||
/**
|
||||
* Alias contains all fields related to an Alias resource
|
||||
*/
|
||||
export default class GeneratedAliasModel extends BaseModel {
|
||||
// =attributes
|
||||
|
||||
@attr('string', {
|
||||
description: 'The type of the resource, to help differentiate schemas',
|
||||
})
|
||||
type;
|
||||
|
||||
@attr('string', {
|
||||
description: 'Optional name for identification purposes.',
|
||||
})
|
||||
name;
|
||||
|
||||
@attr('string', {
|
||||
description: 'Optional user-set description for identification purposes.',
|
||||
})
|
||||
description;
|
||||
|
||||
@attr('date', {
|
||||
description: 'The time this resource was created\nOutput only.',
|
||||
readOnly: true,
|
||||
})
|
||||
created_time;
|
||||
|
||||
@attr('date', {
|
||||
description: 'The time this resource was last updated\nOutput only.',
|
||||
readOnly: true,
|
||||
})
|
||||
updated_time;
|
||||
|
||||
@attr('number', {
|
||||
description: 'Current version number of this resource.',
|
||||
})
|
||||
version;
|
||||
|
||||
@attr('string', {
|
||||
description:
|
||||
'This is the value referenced by the user that is resolved to the destination id.',
|
||||
})
|
||||
value;
|
||||
|
||||
@attr('string', {
|
||||
description: 'This is the id of the resource that this Alias points to.',
|
||||
})
|
||||
destination_id;
|
||||
|
||||
@attr('object', {
|
||||
isNestedAttribute: true,
|
||||
description:
|
||||
'This contains a host_id which is the id of the host that the session will be authorized for.',
|
||||
})
|
||||
authorize_session_arguments;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import BaseModel from '../../models/base';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import BaseModel from '../../models/base';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import BaseModel from '../../models/base';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import BaseModel from '../../models/base';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import BaseModel from '../../models/base';
|
||||
@@ -75,6 +75,18 @@ export default class GeneratedCredentialLibraryModel extends BaseModel {
|
||||
})
|
||||
path;
|
||||
|
||||
@attr('string', {
|
||||
for: 'vault-generic',
|
||||
description: 'It indicates the type of credential the library returns.',
|
||||
})
|
||||
credential_type;
|
||||
|
||||
@attr('object-as-array', {
|
||||
for: 'vault-generic',
|
||||
description: 'It indicates the credential mapping overrides.',
|
||||
})
|
||||
credential_mapping_overrides;
|
||||
|
||||
@attr('string', {
|
||||
for: 'vault-ssh-certificate',
|
||||
isNestedAttribute: true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import BaseModel from '../../models/base';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import BaseModel from '../../models/base';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import BaseModel from '../../models/base';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import BaseModel from '../../models/base';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import BaseModel from '../../models/base';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import BaseModel from '../../models/base';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import BaseModel from '../../models/base';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import BaseModel from '../../models/base';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import BaseModel from '../../models/base';
|
||||
@@ -22,11 +22,12 @@ export default class GeneratedRoleModel extends BaseModel {
|
||||
})
|
||||
description;
|
||||
|
||||
@attr('string', {
|
||||
@attr('array', {
|
||||
emptyArrayIfMissing: true,
|
||||
description:
|
||||
"The scope to which this role applies. Defaults to the role's scope.",
|
||||
"The scopes to which this role applies. Defaults to the role's scope.",
|
||||
})
|
||||
grant_scope_id;
|
||||
grant_scope_ids;
|
||||
|
||||
@attr('date', {
|
||||
description: 'The time this resource was created\nOutput only.',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import BaseModel from '../../models/base';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import BaseModel from '../../models/base';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import BaseModel from '../../models/base';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import BaseModel from '../../models/base';
|
||||
@@ -73,6 +73,12 @@ export default class GeneratedStorageBucketModel extends BaseModel {
|
||||
})
|
||||
region;
|
||||
|
||||
@attr('string', {
|
||||
isNestedAttribute: true,
|
||||
description: 'The MinIO location server.',
|
||||
})
|
||||
endpoint_url;
|
||||
|
||||
//this field is not used in the UI, but this is kept here to replicate the API
|
||||
@attr('string', {
|
||||
readOnly: true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import BaseModel from '../../models/base';
|
||||
@@ -38,12 +38,6 @@ export default class GeneratedTargetModel extends BaseModel {
|
||||
})
|
||||
session_connection_limit;
|
||||
|
||||
@attr('string', {
|
||||
description:
|
||||
'Optional boolean expression to filter the workers that are allowed to satisfy this request.',
|
||||
})
|
||||
worker_filter;
|
||||
|
||||
@attr('string', {
|
||||
description:
|
||||
'Optional boolean expressions to filter the egress workers that are allowed to satisfy this request.',
|
||||
@@ -108,4 +102,17 @@ export default class GeneratedTargetModel extends BaseModel {
|
||||
isNestedAttribute: true,
|
||||
})
|
||||
enable_session_recording;
|
||||
|
||||
@attr('array', {
|
||||
description:
|
||||
'with_aliases specify the aliases that should be created when the target is created. ',
|
||||
})
|
||||
with_aliases;
|
||||
|
||||
@attr('array', {
|
||||
readOnly: true,
|
||||
description:
|
||||
'with_aliases specify the aliases that should be created when the target is created. ',
|
||||
})
|
||||
aliases;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import BaseModel from '../../models/base';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import BaseModel from '../../models/base';
|
||||
@@ -72,4 +72,27 @@ export default class GeneratedWorkerModel extends BaseModel {
|
||||
readOnly: true,
|
||||
})
|
||||
type;
|
||||
|
||||
@attr({
|
||||
description:
|
||||
'The deduplicated union of the tags reported by the worker ' +
|
||||
'from its configuration and any tags added through other means.\nOutput only.',
|
||||
readOnly: true,
|
||||
emptyObjectIfMissing: true,
|
||||
})
|
||||
canonical_tags;
|
||||
|
||||
@attr({
|
||||
description:
|
||||
"The tags set in the worker's configuration file.\nOutput only.",
|
||||
readOnly: true,
|
||||
emptyObjectIfMissing: true,
|
||||
})
|
||||
config_tags;
|
||||
|
||||
@attr({
|
||||
description: 'The api tags set for the worker.\nOutput only.',
|
||||
emptyObjectIfMissing: true,
|
||||
})
|
||||
api_tags;
|
||||
}
|
||||
+39
-43
@@ -1,57 +1,44 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
/* global __electronLog */
|
||||
import { inject as service } from '@ember/service';
|
||||
import { getOwner, setOwner } from '@ember/application';
|
||||
import { pluralize } from 'ember-inflector';
|
||||
import { generateMQLExpression } from '../utils/mql-query';
|
||||
import { paginateResults } from '../utils/paginate-results';
|
||||
|
||||
/**
|
||||
* Not all types are yet supported by the client daemon so we'll
|
||||
* Not all types are yet supported by the cache daemon so we'll
|
||||
* just whitelist the ones we need to start with. Keys are the resource
|
||||
* types and the values are the fields that are searchable by the client.
|
||||
* @type {{session: string[], target: string[]}}
|
||||
* @type {{session: string[], alias: string[], target: string[]}}
|
||||
*/
|
||||
const supportedTypes = {
|
||||
target: ['id', 'name', 'description', 'address', 'scope_id'],
|
||||
session: ['id', 'type', 'status', 'endpoint', 'scope_id', 'target_id'],
|
||||
alias: ['id', 'type', 'value', 'destination_id'],
|
||||
};
|
||||
|
||||
/**
|
||||
* Takes an array and the current page and pagesize to calculate the correct
|
||||
* number of results to return to the caller.
|
||||
*
|
||||
* @param array
|
||||
* @param page
|
||||
* @param pageSize
|
||||
* @returns {[*]}
|
||||
* Map the model resource name to the cache daemon resource name
|
||||
* @type {{session: string, alias: string, target: string}}
|
||||
*/
|
||||
const paginateResults = (array, page, pageSize) => {
|
||||
const length = array?.length;
|
||||
if (!array || length === 0) {
|
||||
return [];
|
||||
}
|
||||
if (!page || !pageSize) {
|
||||
return array;
|
||||
}
|
||||
|
||||
const offset = (page - 1) * pageSize;
|
||||
const start = Math.min(length - 1, offset);
|
||||
const end = Math.min(length, offset + pageSize);
|
||||
|
||||
return array.slice(start, end);
|
||||
export const resourceNames = {
|
||||
target: 'targets',
|
||||
session: 'sessions',
|
||||
alias: 'resolvable-aliases',
|
||||
};
|
||||
|
||||
const fetchControllerData = async (context, next) => {
|
||||
const { data } = context.request;
|
||||
const { query: originalQuery } = data;
|
||||
// remove client daemon specific query params
|
||||
// remove cache daemon specific query params
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const { query, page, pageSize, ...remainingQuery } = originalQuery;
|
||||
|
||||
// If we get an error or client daemon is unavailable, fall back to calling the API
|
||||
// If we get an error or cache daemon is unavailable, fall back to calling the API
|
||||
context.request.data.query = remainingQuery;
|
||||
const results = await next(context.request);
|
||||
const models = results.content.toArray();
|
||||
@@ -65,7 +52,7 @@ const fetchControllerData = async (context, next) => {
|
||||
* Handler to sit in front of the API request layer
|
||||
* so we can request from the daemon first
|
||||
*/
|
||||
export default class ClientDaemonHandler {
|
||||
export default class CacheDaemonHandler {
|
||||
@service session;
|
||||
@service ipc;
|
||||
|
||||
@@ -78,8 +65,8 @@ export default class ClientDaemonHandler {
|
||||
case 'query': {
|
||||
const { store, data } = context.request;
|
||||
const { type, query, options: { pushToStore = true } = {} } = data;
|
||||
const isClientDaemonRunning = await this.ipc.invoke(
|
||||
'isClientDaemonRunning',
|
||||
const isCacheDaemonRunning = await this.ipc.invoke(
|
||||
'isCacheDaemonRunning',
|
||||
);
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
@@ -88,7 +75,7 @@ export default class ClientDaemonHandler {
|
||||
|
||||
if (
|
||||
!Object.keys(supportedTypes).includes(type) ||
|
||||
!isClientDaemonRunning
|
||||
!isCacheDaemonRunning
|
||||
) {
|
||||
return fetchControllerData(context, next);
|
||||
}
|
||||
@@ -112,40 +99,49 @@ export default class ClientDaemonHandler {
|
||||
query: searchQuery,
|
||||
auth_token_id,
|
||||
token,
|
||||
resource: pluralize(type),
|
||||
resource: resourceNames[type],
|
||||
};
|
||||
|
||||
let clientDaemonResults = {};
|
||||
let cacheDaemonResults = {};
|
||||
try {
|
||||
clientDaemonResults = await this.ipc.invoke(
|
||||
'searchClientDaemon',
|
||||
cacheDaemonResults = await this.ipc.invoke(
|
||||
'searchCacheDaemon',
|
||||
remainingQuery,
|
||||
);
|
||||
} catch (e) {
|
||||
// If we got a 403, most likely the client daemon was restarted and our token is no longer valid
|
||||
// If we got a 403, most likely the cache daemon was restarted and our token is no longer valid
|
||||
// I'm not sure if we can get a 401 since we always send a token but we'll handle it in the same way
|
||||
if (e.statusCode === 403 || e.statusCode === 401) {
|
||||
try {
|
||||
await this.ipc.invoke('addTokenToClientDaemon', {
|
||||
await this.ipc.invoke('addTokenToDaemons', {
|
||||
tokenId: auth_token_id,
|
||||
token,
|
||||
});
|
||||
clientDaemonResults = await this.ipc.invoke(
|
||||
'searchClientDaemon',
|
||||
cacheDaemonResults = await this.ipc.invoke(
|
||||
'searchCacheDaemon',
|
||||
remainingQuery,
|
||||
);
|
||||
} catch {
|
||||
} catch (err) {
|
||||
// If it fails again just fall back to fetching controller data
|
||||
__electronLog?.error(
|
||||
'Failed to add token to daemons',
|
||||
err.message,
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
__electronLog?.error(
|
||||
'Failed to search cache daemon; falling back to search controller',
|
||||
e.message,
|
||||
);
|
||||
|
||||
return fetchControllerData(context, next);
|
||||
return fetchControllerData(context, next);
|
||||
}
|
||||
}
|
||||
|
||||
// Currently returns with a singular top level field with resource name
|
||||
// e.g. { targets: [...] } or { sessions: [..] }
|
||||
// So this just unwraps to the array, or undefined
|
||||
const [results] = Object.values(clientDaemonResults);
|
||||
const [results] = Object.values(cacheDaemonResults);
|
||||
const payload = { items: paginateResults(results, page, pageSize) };
|
||||
|
||||
const schema = store.modelFor(type);
|
||||
@@ -0,0 +1,172 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import { modelIndexes } from 'api/services/indexed-db';
|
||||
import { inject as service } from '@ember/service';
|
||||
import { getOwner, setOwner } from '@ember/application';
|
||||
import { queryIndexedDb } from '../utils/indexed-db-query';
|
||||
import { paginateResults } from '../utils/paginate-results';
|
||||
import { hashCode } from '../utils/hash-code';
|
||||
|
||||
/**
|
||||
* Handler to sit in front of the API request layer
|
||||
* so we can handle any caching with indexedDb first
|
||||
*/
|
||||
export default class IndexedDbHandler {
|
||||
@service indexedDb;
|
||||
|
||||
constructor(context) {
|
||||
setOwner(this, getOwner(context));
|
||||
}
|
||||
|
||||
async request(context, next) {
|
||||
switch (context.request.op) {
|
||||
case 'query': {
|
||||
const { store, data } = context.request;
|
||||
// TODO: Remove storeToken option as this is a temporary fix for auth-methods.
|
||||
const {
|
||||
type,
|
||||
query,
|
||||
options: {
|
||||
pushToStore = true,
|
||||
peekIndexedDB = false,
|
||||
storeToken = true,
|
||||
} = {},
|
||||
} = data;
|
||||
const supportedModels = Object.keys(modelIndexes);
|
||||
const { db: indexedDb } = this.indexedDb ?? {};
|
||||
|
||||
// Go through normal flow if we don't yet support the model
|
||||
// or if we don't have an indexedDb instance
|
||||
if (!supportedModels.includes(type) || !indexedDb) {
|
||||
return next(context.request);
|
||||
}
|
||||
|
||||
let { page, pageSize, query: queryObj, ...remainingQuery } = query;
|
||||
|
||||
const adapter = store.adapterFor(type);
|
||||
const schema = store.modelFor(type);
|
||||
const serializer = store.serializerFor(type);
|
||||
|
||||
if (!peekIndexedDB) {
|
||||
const tokenKey = `${type}-${hashCode(remainingQuery)}`;
|
||||
|
||||
let listToken;
|
||||
if (storeToken) {
|
||||
listToken = await indexedDb.token.get(tokenKey);
|
||||
}
|
||||
|
||||
let payload;
|
||||
try {
|
||||
payload = await adapter.query(store, schema, {
|
||||
...remainingQuery,
|
||||
list_token: listToken?.token,
|
||||
});
|
||||
} catch (e) {
|
||||
// If we get an invalid list token, we'll delete the token and
|
||||
// clear the DB and try again without a token.
|
||||
if (
|
||||
e?.errors[0].status === 400 &&
|
||||
e?.errors[0].code === 'invalid list token'
|
||||
) {
|
||||
await indexedDb[type].clear();
|
||||
// Delete all tokens of the same resource type so we don't keep clearing the DB.
|
||||
// Even if other tokens may still be valid, we might have cleared data that they
|
||||
// depended on so we should clear all tokens of the same type when clearing the DB.
|
||||
const tokenKeys = await indexedDb.token
|
||||
.where(':id')
|
||||
.startsWith(type)
|
||||
.primaryKeys();
|
||||
|
||||
await indexedDb.token.bulkDelete(tokenKeys);
|
||||
|
||||
payload = await adapter.query(store, schema, {
|
||||
...remainingQuery,
|
||||
});
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
// Store the token we just got back from the payload if it exists
|
||||
if (payload.list_token && storeToken) {
|
||||
await indexedDb.token.put({
|
||||
id: tokenKey,
|
||||
token: payload.list_token,
|
||||
});
|
||||
}
|
||||
|
||||
// Remove any records from the DB if the API indicates they've been deleted
|
||||
if (payload.removed_ids?.length > 0) {
|
||||
await indexedDb[type].bulkDelete(payload.removed_ids);
|
||||
}
|
||||
// This is a temporary fix of clearing the DB (specifically for auth-methods)
|
||||
// since we are not storing the token we do not get back a list of removed_ids
|
||||
// from the API call and we do not want deleted items from showing in list view.
|
||||
if (!storeToken) {
|
||||
await indexedDb[type].clear();
|
||||
}
|
||||
|
||||
const normalizedPayload = serializer.normalizeResponse(
|
||||
store,
|
||||
schema,
|
||||
payload,
|
||||
null,
|
||||
'query',
|
||||
);
|
||||
|
||||
const { data: payloadData } = normalizedPayload;
|
||||
|
||||
// Store the new data we just got back from the API refresh
|
||||
const items = payloadData.map((datum) =>
|
||||
this.indexedDb.normalizeData({
|
||||
data: datum,
|
||||
cleanData: true,
|
||||
schema,
|
||||
serializer,
|
||||
}),
|
||||
);
|
||||
|
||||
await indexedDb[type].bulkPut(items);
|
||||
}
|
||||
|
||||
const indexedDbResults = await queryIndexedDb(
|
||||
indexedDb,
|
||||
type,
|
||||
queryObj,
|
||||
);
|
||||
|
||||
const dbRecords = paginateResults(indexedDbResults, page, pageSize).map(
|
||||
(item) =>
|
||||
this.indexedDb.normalizeData({
|
||||
data: item,
|
||||
cleanData: false,
|
||||
schema,
|
||||
serializer,
|
||||
}),
|
||||
);
|
||||
|
||||
// Return the raw data if we don't push to the store.
|
||||
let records = dbRecords.map((record) => ({
|
||||
...record.attributes,
|
||||
id: record.id,
|
||||
}));
|
||||
|
||||
if (pushToStore) {
|
||||
records = store.push({ data: dbRecords });
|
||||
}
|
||||
|
||||
// Set a meta property on the array to store the total items of the results.
|
||||
// This isn't conventional but is better than returning an ArrayProxy
|
||||
// or EmberArray since the ember store query method asserts it has to be an array
|
||||
// so we can't just return an object.
|
||||
records.meta = { totalItems: indexedDbResults.length };
|
||||
return records;
|
||||
}
|
||||
default:
|
||||
return next(context.request);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import { registerDeprecationHandler } from '@ember/debug';
|
||||
|
||||
const deprecationList = ['ember-data:deprecate-early-static'];
|
||||
|
||||
export function initialize() {
|
||||
registerDeprecationHandler((message, options, next) => {
|
||||
// TODO: Remove deprecation handling for `deprecate-early-static` warning
|
||||
// once we upgrade to ember-cli-mirage v3.0.0 which fixes this issue.
|
||||
// More info about this issue here: https://github.com/miragejs/ember-cli-mirage/issues/2441
|
||||
if (options?.id && deprecationList.includes(options.id)) {
|
||||
return;
|
||||
}
|
||||
if (options?.url) {
|
||||
message += options.url;
|
||||
}
|
||||
next(message, options);
|
||||
});
|
||||
}
|
||||
|
||||
export default {
|
||||
initialize,
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import Mixin from '@ember/object/mixin';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import GeneratedAccountModel from '../generated/models/account';
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import GeneratedAliasModel from '../generated/models/alias';
|
||||
|
||||
export const TYPE_ALIAS_TARGET = 'target';
|
||||
export const TYPES_ALIAS = Object.freeze([TYPE_ALIAS_TARGET]);
|
||||
export default class AliasModel extends GeneratedAliasModel {}
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import GeneratedAuthMethodModel from '../generated/models/auth-method';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import GeneratedAuthTokenModel from '../generated/models/auth-token';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import Model from '@ember-data/model';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import GeneratedChannelRecordingModel from '../generated/models/channel-recording';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import GeneratedConnectionRecordingModel from '../generated/models/connection-recording';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import GeneratedCredentialLibraryModel from '../generated/models/credential-library';
|
||||
@@ -11,6 +11,15 @@ import GeneratedCredentialLibraryModel from '../generated/models/credential-libr
|
||||
export const options = {
|
||||
http_method: ['GET', 'POST'],
|
||||
key_type: ['ed25519', 'ecdsa', 'rsa'],
|
||||
credential_types: ['ssh_private_key', 'username_password'],
|
||||
mapping_overrides: {
|
||||
username_password: ['username_attribute', 'password_attribute'],
|
||||
ssh_private_key: [
|
||||
'private_key_attribute',
|
||||
'private_key_passphrase_attribute',
|
||||
'username_attribute',
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
export const TYPE_CREDENTIAL_LIBRARY_VAULT_GENERIC = 'vault-generic';
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import GeneratedCredentialStoreModel from '../generated/models/credential-store';
|
||||
import { equal } from '@ember/object/computed';
|
||||
|
||||
export const types = ['static', 'vault'];
|
||||
export const TYPE_CREDENTIAL_STORE_STATIC = 'static';
|
||||
export const TYPE_CREDENTIAL_STORE_VAULT = 'vault';
|
||||
|
||||
export const TYPES_CREDENTIAL_STORE = Object.freeze([
|
||||
TYPE_CREDENTIAL_STORE_STATIC,
|
||||
TYPE_CREDENTIAL_STORE_VAULT,
|
||||
]);
|
||||
|
||||
export default class CredentialStoreModel extends GeneratedCredentialStoreModel {
|
||||
// =attributes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import GeneratedCredentialModel from '../generated/models/credential';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import GeneratedGroupModel from '../generated/models/group';
|
||||
|
||||
@@ -1,12 +1,23 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import GeneratedHostCatalogModel from '../generated/models/host-catalog';
|
||||
|
||||
export const types = ['static', 'plugin'];
|
||||
export const pluginTypes = ['aws', 'azure'];
|
||||
export const TYPE_HOST_CATALOG_STATIC = 'static';
|
||||
export const TYPE_HOST_CATALOG_DYNAMIC = 'plugin';
|
||||
export const TYPES_HOST_CATALOG = Object.freeze([
|
||||
TYPE_HOST_CATALOG_STATIC,
|
||||
TYPE_HOST_CATALOG_DYNAMIC,
|
||||
]);
|
||||
|
||||
export const TYPE_HOST_CATALOG_PLUGIN_AWS = 'aws';
|
||||
export const TYPE_HOST_CATALOG_PLUGIN_AZURE = 'azure';
|
||||
export const TYPES_HOST_CATALOG_PLUGIN = [
|
||||
TYPE_HOST_CATALOG_PLUGIN_AWS,
|
||||
TYPE_HOST_CATALOG_PLUGIN_AZURE,
|
||||
];
|
||||
|
||||
export default class HostCatalogModel extends GeneratedHostCatalogModel {
|
||||
// =attributes
|
||||
@@ -32,7 +43,9 @@ export default class HostCatalogModel extends GeneratedHostCatalogModel {
|
||||
* @type {boolean}
|
||||
*/
|
||||
get isUnknown() {
|
||||
return this.isPlugin && !pluginTypes.includes(this.plugin?.name);
|
||||
return (
|
||||
this.isPlugin && !TYPES_HOST_CATALOG_PLUGIN.includes(this.plugin?.name)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import GeneratedHostSetModel from '../generated/models/host-set';
|
||||
import { pluginTypes } from './host-catalog';
|
||||
import { TYPES_HOST_CATALOG_PLUGIN } from './host-catalog';
|
||||
|
||||
export default class HostSetModel extends GeneratedHostSetModel {
|
||||
// =attributes
|
||||
@@ -30,7 +30,9 @@ export default class HostSetModel extends GeneratedHostSetModel {
|
||||
* @type {boolean}
|
||||
*/
|
||||
get isUnknown() {
|
||||
return this.isPlugin && !pluginTypes.includes(this.plugin?.name);
|
||||
return (
|
||||
this.isPlugin && !TYPES_HOST_CATALOG_PLUGIN.includes(this.plugin?.name)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import GeneratedHostModel from '../generated/models/host';
|
||||
import { attr } from '@ember-data/model';
|
||||
import { pluginTypes } from './host-catalog';
|
||||
import { TYPES_HOST_CATALOG_PLUGIN } from './host-catalog';
|
||||
|
||||
export default class HostModel extends GeneratedHostModel {
|
||||
// =attributes
|
||||
@@ -64,7 +64,9 @@ export default class HostModel extends GeneratedHostModel {
|
||||
* @type {boolean}
|
||||
*/
|
||||
get isUnknown() {
|
||||
return this.isPlugin && !pluginTypes.includes(this.plugin?.name);
|
||||
return (
|
||||
this.isPlugin && !TYPES_HOST_CATALOG_PLUGIN.includes(this.plugin?.name)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import GeneratedManagedGroupModel from '../generated/models/managed-group';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import GeneratedPolicyModel from '../generated/models/policy';
|
||||
|
||||
+89
-101
@@ -1,22 +1,36 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import GeneratedRoleModel from '../generated/models/role';
|
||||
import { attr } from '@ember-data/model';
|
||||
import { inject as service } from '@ember/service';
|
||||
import { all, resolve } from 'rsvp';
|
||||
import {
|
||||
TYPE_AUTH_METHOD_OIDC,
|
||||
TYPE_AUTH_METHOD_LDAP,
|
||||
} from 'api/models/auth-method';
|
||||
|
||||
export const GRANT_SCOPE_THIS = 'this';
|
||||
export const GRANT_SCOPE_CHILDREN = 'children';
|
||||
export const GRANT_SCOPE_DESCENDANTS = 'descendants';
|
||||
export const GRANT_SCOPE_KEYWORDS = Object.freeze([
|
||||
GRANT_SCOPE_THIS,
|
||||
GRANT_SCOPE_CHILDREN,
|
||||
GRANT_SCOPE_DESCENDANTS,
|
||||
]);
|
||||
|
||||
// Sort the grant scope IDs by the order in which they should be displayed
|
||||
// in the UI as the API will return them in an arbitrary order.
|
||||
const sortOrder = {
|
||||
[GRANT_SCOPE_THIS]: 0,
|
||||
[GRANT_SCOPE_CHILDREN]: 1,
|
||||
[GRANT_SCOPE_DESCENDANTS]: 2,
|
||||
global: 3,
|
||||
o: 4,
|
||||
p: 5,
|
||||
};
|
||||
|
||||
export default class RoleModel extends GeneratedRoleModel {
|
||||
// =services
|
||||
|
||||
@service store;
|
||||
@service resourceFilterStore;
|
||||
|
||||
// =attributes
|
||||
|
||||
@@ -27,7 +41,7 @@ export default class RoleModel extends GeneratedRoleModel {
|
||||
* see obvious. Instead, the application layer is expected to load referenced
|
||||
* users and groups as needed.
|
||||
*/
|
||||
@attr('principal-array', {
|
||||
@attr('array', {
|
||||
readOnly: true,
|
||||
emptyArrayIfMissing: true,
|
||||
})
|
||||
@@ -40,12 +54,57 @@ export default class RoleModel extends GeneratedRoleModel {
|
||||
@attr({ readOnly: true, emptyArrayIfMissing: true }) grant_strings;
|
||||
|
||||
/**
|
||||
* Convenience for looking up the grant scope, if loaded.
|
||||
* Convenience for looking up the grant scopes, if loaded.
|
||||
*/
|
||||
get grantScope() {
|
||||
return this.grant_scope_id
|
||||
? this.store.peekRecord('scope', this.grant_scope_id)
|
||||
: null;
|
||||
get grantScopes() {
|
||||
const grantScopes = [];
|
||||
if (this.grant_scope_ids) {
|
||||
const sortedScopeIDs = [...this.grant_scope_ids].sort((a, b) => {
|
||||
const aSplit = a.split('_')[0];
|
||||
const bSplit = b.split('_')[0];
|
||||
|
||||
return sortOrder[aSplit] - sortOrder[bSplit];
|
||||
});
|
||||
|
||||
sortedScopeIDs.forEach((id) => {
|
||||
if (GRANT_SCOPE_KEYWORDS.includes(id)) {
|
||||
grantScopes.push({ id });
|
||||
} else {
|
||||
const scope = this.store.peekRecord('scope', id);
|
||||
if (scope) {
|
||||
grantScopes.push(scope);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return grantScopes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for retrieving grant scope ids that are keywords.
|
||||
* @type {string[]}
|
||||
*/
|
||||
get grantScopeKeywords() {
|
||||
return this.grant_scope_ids.filter((id) =>
|
||||
GRANT_SCOPE_KEYWORDS.includes(id),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for retrieving grant_scope_ids that are orgs.
|
||||
* @type {string[]}
|
||||
*/
|
||||
get grantScopeOrgIDs() {
|
||||
return this.grant_scope_ids.filter((id) => id.startsWith('o_'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for retrieving grant_scope_ids that are projects.
|
||||
* @type {string[]}
|
||||
*/
|
||||
get grantScopeProjectIDs() {
|
||||
return this.grant_scope_ids.filter((id) => id.startsWith('p_'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,7 +114,7 @@ export default class RoleModel extends GeneratedRoleModel {
|
||||
get userIDs() {
|
||||
return this.principals
|
||||
.filter(({ type }) => type === 'user')
|
||||
.map(({ principal_id }) => principal_id);
|
||||
.map(({ id }) => id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,7 +124,7 @@ export default class RoleModel extends GeneratedRoleModel {
|
||||
get groupIDs() {
|
||||
return this.principals
|
||||
.filter(({ type }) => type === 'group')
|
||||
.map(({ principal_id }) => principal_id);
|
||||
.map(({ id }) => id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,96 +134,25 @@ export default class RoleModel extends GeneratedRoleModel {
|
||||
get managedGroupIDs() {
|
||||
return this.principals
|
||||
.filter(({ type }) => type === 'managed group')
|
||||
.map(({ principal_id }) => principal_id);
|
||||
.map(({ id }) => id);
|
||||
}
|
||||
|
||||
/**
|
||||
* A promise that resolves to an array of User instances.
|
||||
* When calling this getter, be sure to await resolution
|
||||
* before interacting with the results.
|
||||
* @type {Promise[UserModel]}
|
||||
*/
|
||||
get users() {
|
||||
const ids = this.userIDs;
|
||||
|
||||
// Role has prinicipal IDs,
|
||||
// return a promise which resolves model instances for those IDs
|
||||
if (ids?.length) {
|
||||
return this.resourceFilterStore
|
||||
.queryBy('user', { id: ids }, { scope_id: 'global', recursive: true })
|
||||
.then((models) => models.map((model) => model));
|
||||
}
|
||||
|
||||
// No principal IDs,
|
||||
// return a promise resolving to an empty array
|
||||
return resolve([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* A promise that resolves to an array of Group instances.
|
||||
* When calling this getter, be sure to await resolution
|
||||
* before interacting with the results.
|
||||
* @type {Promise[GroupModel]}
|
||||
*/
|
||||
get groups() {
|
||||
const ids = this.groupIDs;
|
||||
|
||||
// Role has prinicipal IDs,
|
||||
// return a promise which resolves model instances for those IDs
|
||||
if (ids?.length) {
|
||||
return this.resourceFilterStore
|
||||
.queryBy('group', { id: ids }, { scope_id: 'global', recursive: true })
|
||||
.then((models) => models.map((model) => model));
|
||||
}
|
||||
|
||||
// No principal IDs,
|
||||
// return a promise resolving to an empty array
|
||||
return resolve([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* A promise that resolves to an array of ManagedGroup instances.
|
||||
* When calling this getter, be sure to await resolution
|
||||
* before interacting with the results.
|
||||
* @type {Promise[ManagedGroupModel]}
|
||||
*/
|
||||
get managedGroups() {
|
||||
const ids = this.managedGroupIDs;
|
||||
|
||||
// Role has prinicipal IDs
|
||||
// return a promise which resolves model instances for those IDs
|
||||
if (ids?.length) {
|
||||
// Collect all auth methods.
|
||||
const authMethods = this.resourceFilterStore.queryBy(
|
||||
'auth-method',
|
||||
{ type: [TYPE_AUTH_METHOD_OIDC, TYPE_AUTH_METHOD_LDAP] },
|
||||
{ scope_id: 'global', recursive: true },
|
||||
);
|
||||
|
||||
// For each auth method, query all managed groups with IDs
|
||||
// that match the role's manage group principal IDs.
|
||||
const managedGroups = authMethods
|
||||
.then((methods) =>
|
||||
all(
|
||||
methods.map(({ id: auth_method_id }) =>
|
||||
this.resourceFilterStore
|
||||
.queryBy('managed-group', { id: ids }, { auth_method_id })
|
||||
.then((models) => models.map((model) => model)),
|
||||
),
|
||||
),
|
||||
)
|
||||
// The result is an array of arrays of model instances (grouped by
|
||||
// auth methods), so these must be flattened.
|
||||
.then((grouped) => grouped.flat());
|
||||
return managedGroups;
|
||||
}
|
||||
|
||||
// No principal IDs,
|
||||
// return a promise resolving to an empty array
|
||||
return resolve([]);
|
||||
}
|
||||
// =methods
|
||||
|
||||
/**
|
||||
* Saves grant scope ids on the role via the `set-grant-scopes` method.
|
||||
* @param {[string]} grantScopeIDs
|
||||
* @return {Promise}
|
||||
*/
|
||||
setGrantScopes(grantScopeIDs) {
|
||||
return this.save({
|
||||
adapterOptions: {
|
||||
method: 'set-grant-scopes',
|
||||
grantScopeIDs,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves grant strings on the role via the `set-grants` method.
|
||||
* See serializer and adapter for more information.
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import GeneratedScopeModel from '../generated/models/scope';
|
||||
import { computed } from '@ember/object';
|
||||
|
||||
export const scopeTypes = {
|
||||
global: 'global',
|
||||
org: 'org',
|
||||
project: 'project',
|
||||
};
|
||||
export const TYPE_SCOPE_GLOBAL = 'global';
|
||||
export const TYPE_SCOPE_ORG = 'org';
|
||||
export const TYPE_SCOPE_PROJECT = 'project';
|
||||
export const TYPES_SCOPE = Object.freeze([
|
||||
TYPE_SCOPE_GLOBAL,
|
||||
TYPE_SCOPE_ORG,
|
||||
TYPE_SCOPE_PROJECT,
|
||||
]);
|
||||
|
||||
export default class ScopeModel extends GeneratedScopeModel {
|
||||
// =attributes
|
||||
@@ -18,9 +20,8 @@ export default class ScopeModel extends GeneratedScopeModel {
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
@computed('type')
|
||||
get isGlobal() {
|
||||
return this.type === scopeTypes.global;
|
||||
return this.type === TYPE_SCOPE_GLOBAL;
|
||||
}
|
||||
// There is only one global scope and it cannot be created by clients,
|
||||
// thus no set.
|
||||
@@ -28,23 +29,21 @@ export default class ScopeModel extends GeneratedScopeModel {
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
@computed('type')
|
||||
get isOrg() {
|
||||
return this.type === scopeTypes.org;
|
||||
return this.type === TYPE_SCOPE_ORG;
|
||||
}
|
||||
set isOrg(value) {
|
||||
if (value) this.type = scopeTypes.org;
|
||||
if (value) this.type = TYPE_SCOPE_ORG;
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
@computed('type')
|
||||
get isProject() {
|
||||
return this.type === scopeTypes.project;
|
||||
return this.type === TYPE_SCOPE_PROJECT;
|
||||
}
|
||||
set isProject(value) {
|
||||
if (value) this.type = scopeTypes.project;
|
||||
if (value) this.type = TYPE_SCOPE_PROJECT;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import GeneratedSessionRecordingModel from '../generated/models/session-recording';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import GeneratedSessionModel from '../generated/models/session';
|
||||
@@ -151,6 +151,17 @@ export default class SessionModel extends GeneratedSessionModel {
|
||||
return this.store.peekRecord('target', this.target_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* The user associated with this session (if loaded).
|
||||
* @type {UserModel}
|
||||
*/
|
||||
get user() {
|
||||
if (!this.user_id) {
|
||||
return null;
|
||||
}
|
||||
return this.store.peekRecord('user', this.user_id);
|
||||
}
|
||||
|
||||
// =methods
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import GeneratedStorageBucketModel from '../generated/models/storage-bucket';
|
||||
@@ -9,8 +9,10 @@ export const TYPE_STORAGE_BUCKET_PLUGIN = 'plugin';
|
||||
export const TYPES_STORAGE_BUCKET = Object.freeze([TYPE_STORAGE_BUCKET_PLUGIN]);
|
||||
|
||||
export const TYPE_STORAGE_BUCKET_PLUGIN_AWS_S3 = 'aws';
|
||||
export const TYPE_STORAGE_BUCKET_PLUGIN_MINIO = 'minio';
|
||||
export const TYPES_STORAGE_BUCKET_PLUGIN = Object.freeze([
|
||||
TYPE_STORAGE_BUCKET_PLUGIN_AWS_S3,
|
||||
TYPE_STORAGE_BUCKET_PLUGIN_MINIO,
|
||||
]);
|
||||
|
||||
export const TYPE_CREDENTIAL_STATIC = 'static';
|
||||
@@ -75,6 +77,14 @@ export default class StorageBucketModel extends GeneratedStorageBucketModel {
|
||||
return this.compositeType === TYPE_STORAGE_BUCKET_PLUGIN_AWS_S3;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if the storage bucket plugin type is MinIO
|
||||
* @type {boolean}
|
||||
*/
|
||||
get isMinIO() {
|
||||
return this.compositeType === TYPE_STORAGE_BUCKET_PLUGIN_MINIO;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the storage bucket is a plugin return `plugin.name`,
|
||||
* otherwise return the storage bucket type.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import GeneratedTargetModel from '../generated/models/target';
|
||||
@@ -135,6 +135,12 @@ export default class TargetModel extends GeneratedTargetModel {
|
||||
return Boolean(pendingOrActiveSessions.length);
|
||||
}
|
||||
|
||||
get associatedAliases() {
|
||||
return this.store
|
||||
.peekAll('alias')
|
||||
.filter((alias) => alias?.destination_id === this.id);
|
||||
}
|
||||
|
||||
// =methods
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import GeneratedUserModel from '../generated/models/user';
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import GeneratedWorkerModel from '../generated/models/worker';
|
||||
import { attr } from '@ember-data/model';
|
||||
|
||||
export const TYPE_WORKER_PKI = 'pki';
|
||||
|
||||
export const TAG_TYPE_CONFIG = 'config';
|
||||
export const TAG_TYPE_API = 'api';
|
||||
|
||||
export const HCP_MANAGED_KEY = 'boundary.cloud.hashicorp.com:managed';
|
||||
|
||||
export default class WorkerModel extends GeneratedWorkerModel {
|
||||
// =attributes
|
||||
@@ -23,19 +29,19 @@ export default class WorkerModel extends GeneratedWorkerModel {
|
||||
* @type {boolean}
|
||||
*/
|
||||
get isPki() {
|
||||
return this.type === 'pki';
|
||||
return this.type === TYPE_WORKER_PKI;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of config tags present on the worker.
|
||||
* Returns the number of tags present on the worker.
|
||||
* @type {number}
|
||||
*/
|
||||
get tagCount() {
|
||||
if (!this.config_tags) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Object.values(this.config_tags).reduce(
|
||||
const allTags = [
|
||||
...Object.values(this.config_tags ?? {}),
|
||||
...Object.values(this.api_tags ?? {}),
|
||||
];
|
||||
return allTags.reduce(
|
||||
(previousCount, currentTags) => previousCount + currentTags.length,
|
||||
0,
|
||||
);
|
||||
@@ -45,30 +51,37 @@ export default class WorkerModel extends GeneratedWorkerModel {
|
||||
* Returns the config tags as an array of key/value pair objects.
|
||||
* @type {[object]}
|
||||
*/
|
||||
getConfigTagList() {
|
||||
get configTagList() {
|
||||
if (!this.config_tags) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Object.entries(this.config_tags).flatMap(([key, value]) =>
|
||||
value.map((tag) => ({ key, value: tag })),
|
||||
value.map((tag) => ({ key, value: tag, type: TAG_TYPE_CONFIG })),
|
||||
);
|
||||
}
|
||||
|
||||
@attr({
|
||||
description:
|
||||
'The deduplicated union of the tags reported by the worker ' +
|
||||
'from its configuration and any tags added through other means.\nOutput only.',
|
||||
readOnly: true,
|
||||
})
|
||||
canonical_tags;
|
||||
/**
|
||||
* Returns the api tags as an array of key/value pair objects.
|
||||
* @type {[object]}
|
||||
*/
|
||||
get apiTagList() {
|
||||
if (!this.api_tags) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@attr({
|
||||
description:
|
||||
"The tags set in the worker's configuration file.\nOutput only.",
|
||||
readOnly: true,
|
||||
})
|
||||
config_tags;
|
||||
return Object.entries(this.api_tags).flatMap(([key, value]) =>
|
||||
value.map((tag) => ({ key, value: tag, type: TAG_TYPE_API })),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all tags as an array of key/value pair objects with tag type.
|
||||
* @type {[object]}
|
||||
*/
|
||||
get allTags() {
|
||||
return [...(this.configTagList ?? []), ...(this.apiTagList ?? [])];
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to modify the adapter to handle custom POST route for creating worker.
|
||||
@@ -90,4 +103,26 @@ export default class WorkerModel extends GeneratedWorkerModel {
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to set api tags on the worker.
|
||||
* @param {object} apiTags
|
||||
* @return {Promise}
|
||||
*/
|
||||
setApiTags(apiTags) {
|
||||
return this.save({
|
||||
adapterOptions: { method: 'set-worker-tags', apiTags },
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to remove api tags on the worker.
|
||||
* @param {object} apiTags
|
||||
* @return {Promise}
|
||||
*/
|
||||
removeApiTags(apiTags) {
|
||||
return this.save({
|
||||
adapterOptions: { method: 'remove-worker-tags', apiTags },
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import ApplicationSerializer from './application';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import RESTSerializer from '@ember-data/serializer/rest';
|
||||
@@ -179,6 +179,8 @@ export default class ApplicationSerializer extends RESTSerializer {
|
||||
payload = structuredClone(payload);
|
||||
// Check for and normalize missing arrays
|
||||
payload = this.normalizeMissingArrays(store, primaryModelClass, payload);
|
||||
// Check for and normalize missing objects
|
||||
payload = this.normalizeMissingObjects(store, primaryModelClass, payload);
|
||||
// Setup a new payload data structure.
|
||||
const transformedPayload = {};
|
||||
// Find the Ember-data-expected root key name.
|
||||
@@ -199,7 +201,7 @@ export default class ApplicationSerializer extends RESTSerializer {
|
||||
|
||||
/**
|
||||
* Resets missing array fields to an empty array if they are annotated by
|
||||
* `normalizeToEmptyArray: true` in the associated model attribute
|
||||
* `emptyArrayIfMissing: true` in the associated model attribute
|
||||
* declaration. Our API excludes arrays when they are empty from
|
||||
* singular responses.
|
||||
*
|
||||
@@ -222,6 +224,30 @@ export default class ApplicationSerializer extends RESTSerializer {
|
||||
return payload;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets missing object fields to an empty object if they are annotated by
|
||||
* `emptyObjectIfMissing: true` in the associated model attribute
|
||||
* declaration.
|
||||
*
|
||||
* @param {Store} store
|
||||
* @param {Model} primaryModelClass
|
||||
* @param {object} payload
|
||||
* @return {object}
|
||||
*/
|
||||
normalizeMissingObjects(store, primaryModelClass, payload) {
|
||||
const attrDefs = store
|
||||
.getSchemaDefinitionService()
|
||||
.attributesDefinitionFor({ type: primaryModelClass.modelName });
|
||||
if (attrDefs) {
|
||||
Object.keys(attrDefs).forEach((key) => {
|
||||
if (!payload[key] && attrDefs[key]?.options?.emptyObjectIfMissing) {
|
||||
payload[key] = {};
|
||||
}
|
||||
});
|
||||
}
|
||||
return payload;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hydrates the incoming scope JSON with additional boolean fields and
|
||||
* delegates nested attributes and secrets normalization.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import ApplicationSerializer from './application';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import ApplicationSerializer from './application';
|
||||
|
||||
Loaded 100 of 2186 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user