Compare commits
74 Commits
Author | SHA1 | Date | |
---|---|---|---|
bc7a2ca5f1 | |||
77d911e47a | |||
b9c9c2d0a9 | |||
d5b91789d1 | |||
eb8350f453 | |||
b987ce27b8 | |||
630e363e53 | |||
a602021952 | |||
80585437a0 | |||
4674a20a2c | |||
820cdfcd48 | |||
6e5dd9b05a | |||
f3d5c21fab | |||
04b278ee28 | |||
7084d76c43 | |||
41d7550e89 | |||
4bf361d3a6 | |||
d70617a90c | |||
62ad1655d5 | |||
caf3a095f2 | |||
89e44b2e5f | |||
a617f51b19 | |||
355e04fd1d | |||
89bd767bea | |||
e567ebbf21 | |||
33311348e2 | |||
d6e914edab | |||
da7b866f23 | |||
7654d780b1 | |||
dbd9b661c6 | |||
e19d0b4deb | |||
f0ebb719f7 | |||
c8e0666bc6 | |||
0d0b106f90 | |||
c9073df7cd | |||
f65200703d | |||
57970b3d10 | |||
b4d9f40c41 | |||
a219725ff6 | |||
4b993fc6b3 | |||
d453da709f | |||
50fac41c95 | |||
affce1fcd1 | |||
df67ebd27a | |||
ef5bfd435a | |||
db07db930c | |||
f6309f600c | |||
7477704905 | |||
db89d86242 | |||
b74ce05845 | |||
79db68a4a2 | |||
5a3ddcf39b | |||
fe6bfc0a83 | |||
36a481ecd1 | |||
f7b2e203ed | |||
27c98c4e32 | |||
79257908d0 | |||
b5ca898eac | |||
53ade28931 | |||
fff4c7642d | |||
dafe6574cc | |||
b70dad4996 | |||
17b0b50fbd | |||
91a0272ab3 | |||
efd22d4087 | |||
c9e32540bf | |||
8344f96983 | |||
3b77089d79 | |||
b6bce76043 | |||
cab57ab303 | |||
804f1f3b12 | |||
f0144fdd5b | |||
81f286cb2f | |||
1f12cb9f94 |
@ -10,8 +10,8 @@ env:
|
||||
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@/${{gitea.repository}}.git
|
||||
NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}}
|
||||
NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}}
|
||||
NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}}
|
||||
NPMCI_LOGIN_DOCKER_GITEA: ${{ github.server_url }}|${{ gitea.repository_owner }}|${{ secrets.GITEA_TOKEN }}
|
||||
# NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}}
|
||||
# NPMCI_LOGIN_DOCKER_GITEA: ${{ github.server_url }}|${{ gitea.repository_owner }}|${{ secrets.GITEA_TOKEN }}
|
||||
NPMCI_LOGIN_DOCKER_DOCKERREGISTRY: ${{ secrets.NPMCI_LOGIN_DOCKER_DOCKERREGISTRY }}
|
||||
NPMCI_SECRET01: ${{ secrets.NPMCI_SECRET01 }}
|
||||
|
||||
@ -75,7 +75,7 @@ jobs:
|
||||
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: code.foss.global/hosttoday/ht-docker-dbase:npmci
|
||||
image: code.foss.global/host.today/ht-docker-dbase:npmci
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
@ -90,8 +90,7 @@ jobs:
|
||||
npmci docker login
|
||||
npmci docker build
|
||||
npmci docker test
|
||||
# npmci docker push
|
||||
npmci docker push
|
||||
npmci docker push code.foss.global
|
||||
|
||||
metadata:
|
||||
needs: test
|
||||
|
@ -1,6 +1,6 @@
|
||||
# gitzone dockerfile_service
|
||||
## STAGE 1 // BUILD
|
||||
FROM code.foss.global/hosttoday/ht-docker-node:npmci as node1
|
||||
FROM code.foss.global/host.today/ht-docker-node:npmci as node1
|
||||
COPY ./ /app
|
||||
WORKDIR /app
|
||||
ARG NPMCI_TOKEN_NPM2
|
||||
@ -12,7 +12,7 @@ RUN pnpm run build
|
||||
|
||||
# gitzone dockerfile_service
|
||||
## STAGE 2 // install production
|
||||
FROM code.foss.global/hosttoday/ht-docker-node:npmci as node2
|
||||
FROM code.foss.global/host.today/ht-docker-node:npmci as node2
|
||||
WORKDIR /app
|
||||
COPY --from=node1 /app /app
|
||||
RUN rm -rf .pnpm-store
|
||||
@ -24,7 +24,7 @@ RUN rm -rf node_modules/ && pnpm install --prod
|
||||
|
||||
|
||||
## STAGE 3 // rebuild dependencies for alpine
|
||||
FROM code.foss.global/hosttoday/ht-docker-node:alpinenpmci as node3
|
||||
FROM code.foss.global/host.today/ht-docker-node:alpine_npmci as node3
|
||||
WORKDIR /app
|
||||
COPY --from=node2 /app /app
|
||||
ARG NPMCI_TOKEN_NPM2
|
||||
@ -34,7 +34,7 @@ RUN pnpm config set store-dir .pnpm-store
|
||||
RUN pnpm rebuild -r
|
||||
|
||||
## STAGE 4 // the final production image with all dependencies in place
|
||||
FROM code.foss.global/hosttoday/ht-docker-node:alpine as node4
|
||||
FROM code.foss.global/host.today/ht-docker-node:alpine as node4
|
||||
WORKDIR /app
|
||||
COPY --from=node3 /app /app
|
||||
|
||||
|
232
changelog.md
232
changelog.md
@ -1,5 +1,237 @@
|
||||
# Changelog
|
||||
|
||||
## 2025-04-25 - 5.0.4 - fix(platformservice/mta)
|
||||
Update getEmailStatus response schema: make details property optional
|
||||
|
||||
- Changed details property from required with fixed message to optional with a flexible message structure in IReq_GetEMailStats response
|
||||
|
||||
## 2025-04-25 - 5.0.3 - fix(mta)
|
||||
update email status response type in MTA platform service
|
||||
|
||||
- Changed the response 'status' field in IRequest_CheckEmailStatus from a literal 'unknown' to a generic string for improved flexibility
|
||||
|
||||
## 2025-04-25 - 5.0.2 - fix(platformservice/mta)
|
||||
Refactor email status response in MTA service
|
||||
|
||||
- Updated IReq_CheckEmailStatus response: replaced union type ('ok' | 'not ok') with fixed status 'unknown' and added a details object with message 'Email not found'.
|
||||
|
||||
## 2025-04-25 - 5.0.1 - fix(mta)
|
||||
Update email stats response interface in mta platform service to include totalEmailsSent, totalEmailsDelivered, totalEmailsBounced, averageDeliveryTimeMs, and lastUpdated timestamp.
|
||||
|
||||
- Modified IReq_GetEMailStats response in ts_interfaces/platformservice/mta.ts from an empty status object to a detailed email statistics structure.
|
||||
|
||||
## 2025-04-25 - 5.0.0 - BREAKING CHANGE(ts_interfaces/platformservice/mta)
|
||||
Rename mta interfaces and upgrade dependency versions
|
||||
|
||||
- Upgraded devDependencies: @git.zone/tsbuild, tsbundle, tsdoc, tstest, tswatch, and @push.rocks/tapbundle to newer versions.
|
||||
- Upgraded dependencies: @design.estate/dees-catalog, dees-domtools, dees-element, @push.rocks/smartdata, smartexpect, smartfile, smartpromise, smartrequest, smartrx, and tsclass (v4.2.0 to v9.0.0).
|
||||
- Added new packageManager field in package.json and introduced pnpm-workspace.yaml for additional workspace configuration.
|
||||
- Refactored mta API interfaces: renamed IRequest_SendEmail to IReq_SendEmail and IRequestRegisterRecipient to IReq_RegisterRecipient; added IReq_CheckEmailStatus and IReq_GetEMailStats.
|
||||
|
||||
## 2025-01-20 - 4.13.0 - feat(service)
|
||||
Add support for service creation, update, and deletion.
|
||||
|
||||
- Implemented TypedHandlers for creating a new service.
|
||||
- Added features to update existing service details.
|
||||
- Enabled deletion of services by their unique ID.
|
||||
|
||||
## 2025-01-20 - 4.12.2 - fix(service)
|
||||
Fix secret bundle and service management bugs
|
||||
|
||||
- Corrected the field name from 'includedImages' to 'imageClaims' in secret bundles.
|
||||
- Implemented 'getFlatKeyValueObject' for secret bundles and modified related API interactions.
|
||||
- Enhanced the Service class with methods for handling secret bundle data by resolving related groups and environments.
|
||||
|
||||
## 2025-01-02 - 4.12.1 - fix(deps)
|
||||
Updated @git.zone/tspublish to version ^1.9.1
|
||||
|
||||
|
||||
## 2025-01-02 - 4.12.0 - feat(cli)
|
||||
Add CLI support and external registries view
|
||||
|
||||
- Adds CLI client functionality
|
||||
- Introduces a new view for External Registries in the dashboard
|
||||
|
||||
## 2024-12-30 - 4.11.0 - feat(external-registry)
|
||||
Introduce external registry management
|
||||
|
||||
- Added ExternalRegistryManager to handle external registry operations.
|
||||
- Implemented ability to create, retrieve, and delete external registries.
|
||||
- Enhanced Cloudly class to include ExternalRegistryManager.
|
||||
|
||||
## 2024-12-29 - 4.10.0 - feat(apiclient)
|
||||
Added support for managing external registries in the API client.
|
||||
|
||||
- Introduced methods to get a registry by ID, get all registries, and create a new registry in the externalRegistry object.
|
||||
- Updated external registry request interfaces to match new API client capabilities.
|
||||
|
||||
## 2024-12-29 - 4.9.0 - feat(apiclient)
|
||||
Add external registry management capabilities to Cloudly API client.
|
||||
|
||||
- Introduce ExternalRegistry class with methods for getting, creating, and updating external registries.
|
||||
- Expand requests module to handle external registry management, including creation and deletion.
|
||||
|
||||
## 2024-12-28 - 4.8.1 - fix(interfaces)
|
||||
Fix image location schema in IImage interface
|
||||
|
||||
- Refactored the 'external' object within IImage data to a 'location' object.
|
||||
- Added 'internal' boolean to 'location' to specify internal/external status.
|
||||
|
||||
## 2024-12-28 - 4.8.0 - feat(manager.registry)
|
||||
Add external registry management
|
||||
|
||||
- Introduced ExternalRegistry class for handling external registry configurations.
|
||||
- Updated IExternalRegistry interface to include registry details.
|
||||
- Enhanced IImage interface to support linking with external registries.
|
||||
|
||||
## 2024-12-28 - 4.7.1 - fix(secretmanagement)
|
||||
Refactor secret bundle actions and improve authorization handling
|
||||
|
||||
- Refactored secret bundle handling by renaming methods and reorganizing static and instance methods in SecretBundle class.
|
||||
- Added getSecretBundleByAuthorization method to SecretBundle.
|
||||
- Improved getFlatKeyValueObjectForEnvironment to accurately retrieve key-value pairs for specified environments.
|
||||
- Removed deprecated IEnvBundle interface and related request handler for better clarity and code usage.
|
||||
- Updated request interfaces related to secret bundles for consistent method naming and arguments.
|
||||
|
||||
## 2024-12-22 - 4.7.0 - feat(apiclient)
|
||||
Add method to flatten secret bundles into key-value objects.
|
||||
|
||||
- SecretBundle: Implemented toFlatKeyValueObject method to flatten secret groups into key-value pairs.
|
||||
- Removed stale SecretManager class from apiclient.
|
||||
|
||||
## 2024-12-22 - 4.6.0 - feat(cloudlyapiclient)
|
||||
Extend CloudlyApiClient with cluster, secretbundle, and secretgroup methods
|
||||
|
||||
- Added methods to CloudlyApiClient for managing clusters: getClusterById, getClusters, createCluster.
|
||||
- Added methods to CloudlyApiClient for managing secret bundles: getSecretBundleById, getSecretBundles, createSecretBundle.
|
||||
- Added methods to CloudlyApiClient for managing secret groups: getSecretGroupById, getSecretGroups, createSecretGroup.
|
||||
|
||||
## 2024-12-22 - 4.5.5 - fix(apiclient)
|
||||
Fixed image creation method in cloudlyApiClient
|
||||
|
||||
- Corrected method call from 'images.createImage' to 'image.createImage' to ensure proper image creation.
|
||||
- Updated cluster retrieval methods and ensured proper API routes are being called.
|
||||
|
||||
## 2024-12-21 - 4.5.4 - fix(ts_web)
|
||||
Fix action type and data fields in appstate for CRUD operations
|
||||
|
||||
- Correct request method in createSecretGroupAction to accurately reflect the purpose.
|
||||
- Align the deleteSecretGroupAction and deleteSecretBundleAction request types with proper interfaces.
|
||||
- Ensure data payload matches backend requirements for secret group and secret bundle operations.
|
||||
|
||||
## 2024-12-21 - 4.5.3 - fix(secret-management)
|
||||
Refactor secret management to use distinct secret bundle and group APIs. Introduce API client classes for secret bundles and groups.
|
||||
|
||||
- Updated secret management logic to separate secret bundle and group APIs.
|
||||
- Implemented new API client classes for managing secret bundles and groups.
|
||||
- Fixed incorrect method usages for secret-related actions.
|
||||
|
||||
## 2024-12-20 - 4.5.2 - fix(apiclient)
|
||||
Implemented IService interface in Service class and improved secret bundle documentation.
|
||||
|
||||
- Implemented plugins.servezoneInterfaces.data.IService interface in the Service class within ts_apiclient.
|
||||
- Updated documentation comments for the type property in the ISecretBundle interface.
|
||||
|
||||
## 2024-12-17 - 4.5.1 - fix(core)
|
||||
Updated dependencies in package.json to latest versions.
|
||||
|
||||
- Bumped @git.zone/tswatch to version ^2.0.37
|
||||
- Bumped @types/node to version ^22.10.2
|
||||
- Bumped @design.estate/dees-catalog to version ^1.3.2
|
||||
- Bumped @push.rocks/smartfile to version ^11.0.23
|
||||
- Bumped @tsclass/tsclass to version ^4.2.0
|
||||
|
||||
## 2024-12-14 - 4.5.0 - feat(services)
|
||||
Add service management functionalities
|
||||
|
||||
- Integrated service-related API client methods including getServices, getServiceById, and createService.
|
||||
- Updated the deployment data structure in the service manager.
|
||||
- Enhanced service interface to incorporate additional fields for comprehensive data handling.
|
||||
- Ensured secure token generation for Cloudly authentication processes.
|
||||
|
||||
## 2024-11-18 - 4.4.0 - feat(api-client)
|
||||
Add static method getImageById for Image class in api-client
|
||||
|
||||
- Introduced a static method getImageById in the Image class.
|
||||
- Updated CloudlyApiClient to include the getImageById method in the images interface.
|
||||
|
||||
## 2024-11-18 - 4.3.21 - fix(interfaces)
|
||||
Remove deprecated deployment directive and update related interfaces
|
||||
|
||||
- Removed IDeploymentDirective from data and requests.
|
||||
- Updated IDeployment to remove references to directives.
|
||||
- Changed IRequest_Any_Cloudly_GetClusterConfig to return services instead of deployment directives.
|
||||
- Removed deploymentDirectiveIds from IService data structure.
|
||||
|
||||
## 2024-11-18 - 4.3.20 - fix(apiclient)
|
||||
Ensure mandatory parameter in CloudlyApiClient constructor
|
||||
|
||||
- Made the 'optionsArg' parameter mandatory in the constructor of CloudlyApiClient class.
|
||||
|
||||
## 2024-11-18 - 4.3.19 - fix(docker)
|
||||
Fix improper Docker push command preventing push to the correct registry.
|
||||
|
||||
- Corrected the docker push command in the '.gitea/workflows/docker_tags.yaml' file to push images to the 'code.foss.global' registry.
|
||||
|
||||
## 2024-11-17 - 4.3.18 - fix(docker_tags)
|
||||
Updated Docker configuration to include NPM tokens.
|
||||
|
||||
- Restored NPMCI_TOKEN_NPM and NPMCI_TOKEN_NPM2 environment variables in docker_tags.yaml for authentication purposes.
|
||||
|
||||
## 2024-11-17 - 4.3.17 - fix(Dockerfile)
|
||||
Corrected docker base image tag in Dockerfile for alpine compatibility.
|
||||
|
||||
- Updated Dockerfile to use the correct base image tag for Alpine.
|
||||
- Resolved any potential build issues related to incorrect image tag usage.
|
||||
|
||||
## 2024-11-17 - 4.3.16 - fix(infrastructure)
|
||||
Correct Docker image path in Dockerfile for improved build consistency.
|
||||
|
||||
- Dockerfile: Updated base image paths from 'code.foss.global/hosttoday/ht-docker-node' to 'code.foss.global/host.today/ht-docker-node'.
|
||||
|
||||
## 2024-11-17 - 4.3.15 - fix(project setup)
|
||||
fixed incorrect configuration in npmextra.json
|
||||
|
||||
- Removed unnecessary 'dockerBuildargEnvMap' entry for NPMCI_TOKEN_NPM2.
|
||||
- Corrected the githost and gitscope in gitzone module configuration.
|
||||
- Updated the license field to reflect the correct license.
|
||||
|
||||
## 2024-11-16 - 4.3.14 - fix(docker tags)
|
||||
Comment out unused secret variables in docker_tags.yaml
|
||||
|
||||
- Modified docker_tags.yaml to comment out unused secret variables related to NPM and GitHub tokens.
|
||||
|
||||
## 2024-11-16 - 4.3.13 - fix(package)
|
||||
Updated package dependencies
|
||||
|
||||
- Updated @design.estate/dees-catalog version to 1.3.1
|
||||
|
||||
## 2024-11-06 - 4.3.12 - fix(workflow)
|
||||
Fix Docker image path in GitHub action workflow
|
||||
|
||||
- Corrected the path of the Docker image used in the GitHub action workflow from 'code.foss.global/hosttoday/ht-docker-dbase:npmci' to 'code.foss.global/host.today/ht-docker-dbase:npmci'.
|
||||
|
||||
## 2024-11-06 - 4.3.11 - fix(overall)
|
||||
Refactor and improve code consistency across all modules
|
||||
|
||||
- Updated cloud configuration management for better reliability.
|
||||
- Enhanced security measures in the authentication and authorization processes.
|
||||
- Streamlined deployment logic in cluster management.
|
||||
- Refactored code to improve maintainability and readability.
|
||||
|
||||
## 2024-11-06 - 4.3.10 - fix(dependencies)
|
||||
Updated dependencies and fixed Docker Alpine image retrieval issue in tests
|
||||
|
||||
- Updated @push.rocks/tapbundle to version ^5.5.0 in devDependencies.
|
||||
- Updated @push.rocks/smartrequest to version ^2.0.23 in dependencies.
|
||||
- Ensured the Docker Alpine image is retrieved as a local tarball in cloudlyfactory.ts test helper.
|
||||
|
||||
## 2024-11-06 - 4.3.9 - fix(test and dependencies)
|
||||
Corrected cloudlyUrl in test.apiclient and updated tapbundle dependency.
|
||||
|
||||
- Fixed cloudlyUrl assignment in the test.apiclient to use the correct helper method.
|
||||
- Updated tapbundle dependency version from ^5.4.3 to ^5.4.4.
|
||||
|
||||
## 2024-11-06 - 4.3.8 - fix(api client)
|
||||
Fixed localhost URL issue in test.client.ts
|
||||
|
||||
|
@ -6,19 +6,17 @@
|
||||
"dockerRegistryRepoMap": {
|
||||
"code.foss.global": "serve.zone/cloudly"
|
||||
},
|
||||
"dockerBuildargEnvMap": {
|
||||
"NPMCI_TOKEN_NPM2": "NPMCI_TOKEN_NPM2"
|
||||
}
|
||||
"dockerBuildargEnvMap": {}
|
||||
},
|
||||
"gitzone": {
|
||||
"projectType": "service",
|
||||
"module": {
|
||||
"githost": "gitlab.com",
|
||||
"gitscope": "servezone/private",
|
||||
"githost": "code.foss.global",
|
||||
"gitscope": "serve.zone",
|
||||
"gitrepo": "cloudly",
|
||||
"description": "A comprehensive tool for managing containerized applications across multiple cloud providers using Docker Swarmkit, featuring web, CLI, and API interfaces.",
|
||||
"npmPackagename": "@serve.zone/cloudly",
|
||||
"license": "UNLICENSED",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"multi-cloud management",
|
||||
"Docker Swarmkit",
|
||||
|
51
package.json
51
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@serve.zone/cloudly",
|
||||
"version": "4.3.8",
|
||||
"version": "5.0.4",
|
||||
"private": false,
|
||||
"description": "A comprehensive tool for managing containerized applications across multiple cloud providers using Docker Swarmkit, featuring web, CLI, and API interfaces.",
|
||||
"type": "module",
|
||||
@ -22,41 +22,41 @@
|
||||
"docs": "tsdoc aidoc"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@git.zone/tsbuild": "^2.2.0",
|
||||
"@git.zone/tsbundle": "^2.1.0",
|
||||
"@git.zone/tsdoc": "^1.4.2",
|
||||
"@git.zone/tspublish": "^1.7.7",
|
||||
"@git.zone/tstest": "^1.0.90",
|
||||
"@git.zone/tswatch": "^2.0.25",
|
||||
"@push.rocks/tapbundle": "^5.4.3",
|
||||
"@types/node": "^22.9.0"
|
||||
"@git.zone/tsbuild": "^2.3.2",
|
||||
"@git.zone/tsbundle": "^2.2.5",
|
||||
"@git.zone/tsdoc": "^1.4.4",
|
||||
"@git.zone/tspublish": "^1.9.1",
|
||||
"@git.zone/tstest": "^1.0.96",
|
||||
"@git.zone/tswatch": "^2.1.0",
|
||||
"@push.rocks/tapbundle": "^5.6.3",
|
||||
"@types/node": "^22.15.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@api.global/typedrequest": "3.1.10",
|
||||
"@api.global/typedrequest-interfaces": "^3.0.19",
|
||||
"@api.global/typedserver": "^3.0.51",
|
||||
"@api.global/typedserver": "^3.0.74",
|
||||
"@api.global/typedsocket": "^3.0.1",
|
||||
"@apiclient.xyz/cloudflare": "^6.0.1",
|
||||
"@apiclient.xyz/docker": "^1.2.7",
|
||||
"@apiclient.xyz/docker": "^1.3.0",
|
||||
"@apiclient.xyz/hetznercloud": "^1.2.0",
|
||||
"@apiclient.xyz/slack": "^3.0.9",
|
||||
"@design.estate/dees-catalog": "^1.2.0",
|
||||
"@design.estate/dees-domtools": "^2.0.64",
|
||||
"@design.estate/dees-element": "^2.0.39",
|
||||
"@design.estate/dees-catalog": "^1.8.0",
|
||||
"@design.estate/dees-domtools": "^2.3.2",
|
||||
"@design.estate/dees-element": "^2.0.42",
|
||||
"@git.zone/tsrun": "^1.3.3",
|
||||
"@push.rocks/early": "^4.0.3",
|
||||
"@push.rocks/npmextra": "^5.1.2",
|
||||
"@push.rocks/projectinfo": "^5.0.1",
|
||||
"@push.rocks/qenv": "^6.0.5",
|
||||
"@push.rocks/qenv": "^6.1.0",
|
||||
"@push.rocks/smartacme": "^5.0.0",
|
||||
"@push.rocks/smartbucket": "^3.0.23",
|
||||
"@push.rocks/smartbucket": "^3.3.7",
|
||||
"@push.rocks/smartcli": "^4.0.11",
|
||||
"@push.rocks/smartclickhouse": "^2.0.17",
|
||||
"@push.rocks/smartdata": "^5.2.10",
|
||||
"@push.rocks/smartdata": "^5.15.1",
|
||||
"@push.rocks/smartdelay": "^3.0.5",
|
||||
"@push.rocks/smartexit": "^1.0.23",
|
||||
"@push.rocks/smartexpect": "^1.2.1",
|
||||
"@push.rocks/smartfile": "^11.0.21",
|
||||
"@push.rocks/smartexpect": "^1.6.1",
|
||||
"@push.rocks/smartfile": "^11.2.0",
|
||||
"@push.rocks/smartguard": "^3.1.0",
|
||||
"@push.rocks/smartjson": "^5.0.19",
|
||||
"@push.rocks/smartjwt": "^2.2.1",
|
||||
@ -64,17 +64,17 @@
|
||||
"@push.rocks/smartlog-destination-clickhouse": "^1.0.13",
|
||||
"@push.rocks/smartlog-interfaces": "^3.0.2",
|
||||
"@push.rocks/smartpath": "^5.0.18",
|
||||
"@push.rocks/smartpromise": "^4.0.4",
|
||||
"@push.rocks/smartrequest": "^2.0.22",
|
||||
"@push.rocks/smartrx": "^3.0.7",
|
||||
"@push.rocks/smartpromise": "^4.2.3",
|
||||
"@push.rocks/smartrequest": "^2.1.0",
|
||||
"@push.rocks/smartrx": "^3.0.10",
|
||||
"@push.rocks/smartssh": "^2.0.1",
|
||||
"@push.rocks/smartstate": "^2.0.19",
|
||||
"@push.rocks/smartstream": "^3.2.4",
|
||||
"@push.rocks/smartstream": "^3.2.5",
|
||||
"@push.rocks/smartstring": "^4.0.15",
|
||||
"@push.rocks/smartunique": "^3.0.9",
|
||||
"@push.rocks/taskbuffer": "^3.0.2",
|
||||
"@push.rocks/webjwt": "^1.0.9",
|
||||
"@tsclass/tsclass": "^4.1.2"
|
||||
"@tsclass/tsclass": "^9.0.0"
|
||||
},
|
||||
"files": [
|
||||
"ts/**/*",
|
||||
@ -126,5 +126,6 @@
|
||||
"frontend",
|
||||
"backend",
|
||||
"security"
|
||||
]
|
||||
],
|
||||
"packageManager": "pnpm@10.7.0+sha512.6b865ad4b62a1d9842b61d674a393903b871d9244954f652b8842c2b553c72176b278f64c463e52d40fff8aba385c235c8c9ecf5cc7de4fd78b8bb6d49633ab6"
|
||||
}
|
||||
|
14696
pnpm-lock.yaml
generated
14696
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
4
pnpm-workspace.yaml
Normal file
4
pnpm-workspace.yaml
Normal file
@ -0,0 +1,4 @@
|
||||
onlyBuiltDependencies:
|
||||
- esbuild
|
||||
- mongodb-memory-server
|
||||
- puppeteer
|
@ -34,6 +34,8 @@ export const testCloudlyConfig: cloudly.ICloudlyConfig = {
|
||||
})(),
|
||||
};
|
||||
|
||||
await tapToolsNodeMod.tapNodeTools.testFileProvider.getDockerAlpineImageAsLocalTarball();
|
||||
|
||||
export const createCloudly = async () => {
|
||||
const cloudlyInstance = new cloudly.Cloudly(testCloudlyConfig);
|
||||
return cloudlyInstance;
|
||||
|
@ -33,7 +33,7 @@ tap.preTask('should create a new machine user for testing', async () => {
|
||||
tap.test('should create a new cloudlyApiClient', async () => {
|
||||
testClient = new cloudlyApiClient.CloudlyApiClient({
|
||||
registerAs: 'api',
|
||||
cloudlyUrl: `http://127.0.0.1:${helpers.testCloudlyConfig.publicPort}`,
|
||||
cloudlyUrl: `http://${helpers.testCloudlyConfig.publicUrl}:${helpers.testCloudlyConfig.publicPort}`,
|
||||
});
|
||||
await testClient.start();
|
||||
expect(testClient).toBeTruthy();
|
||||
@ -57,7 +57,7 @@ tap.test('should get an identity', async () => {
|
||||
|
||||
let image: Image;
|
||||
tap.test('should create and upload an image', async () => {
|
||||
image = await testClient.images.createImage({
|
||||
image = await testClient.image.createImage({
|
||||
name: 'test',
|
||||
description: 'test'
|
||||
});
|
||||
|
@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@serve.zone/cloudly',
|
||||
version: '4.3.8',
|
||||
version: '5.0.4',
|
||||
description: 'A comprehensive tool for managing containerized applications across multiple cloud providers using Docker Swarmkit, featuring web, CLI, and API interfaces.'
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ for (let i = 0; i < demoSecretGroups.length; i++) {
|
||||
id: `configBundleId${i + 1}`,
|
||||
data: {
|
||||
name: `Demo Config Bundle ${i + 1}`,
|
||||
includedImages: [],
|
||||
imageClaims: [],
|
||||
type: 'external',
|
||||
description: 'Demo Purpose',
|
||||
includedSecretGroupIds: [secretGroup.id],
|
||||
|
@ -20,6 +20,7 @@ import { CloudlyTaskmanager } from './manager.task/taskmanager.js';
|
||||
import { CloudlySecretManager } from './manager.secret/classes.secretmanager.js';
|
||||
import { CloudlyServerManager } from './manager.server/classes.servermanager.js';
|
||||
import { ExternalApiManager } from './manager.status/statusmanager.js';
|
||||
import { ExternalRegistryManager } from './manager.externalregistry/index.js';
|
||||
import { ImageManager } from './manager.image/classes.imagemanager.js';
|
||||
import { logger } from './logger.js';
|
||||
import { CloudlyAuthManager } from './manager.auth/classes.authmanager.js';
|
||||
@ -54,6 +55,7 @@ export class Cloudly {
|
||||
public clusterManager: ClusterManager;
|
||||
public coreflowManager: CloudlyCoreflowManager;
|
||||
public externalApiManager: ExternalApiManager;
|
||||
public externalRegistryManager: ExternalRegistryManager;
|
||||
public imageManager: ImageManager;
|
||||
public taskManager: CloudlyTaskmanager;
|
||||
public serverManager: CloudlyServerManager;
|
||||
@ -80,6 +82,7 @@ export class Cloudly {
|
||||
this.clusterManager = new ClusterManager(this);
|
||||
this.coreflowManager = new CloudlyCoreflowManager(this);
|
||||
this.externalApiManager = new ExternalApiManager(this);
|
||||
this.externalRegistryManager = new ExternalRegistryManager(this);
|
||||
this.imageManager = new ImageManager(this);
|
||||
this.taskManager = new CloudlyTaskmanager(this);
|
||||
this.secretManager = new CloudlySecretManager(this);
|
||||
|
@ -38,13 +38,13 @@ export class ClusterManager {
|
||||
console.log(await cluster.createSavableObject());
|
||||
this.cloudlyRef.serverManager.ensureServerInfrastructure();
|
||||
return {
|
||||
clusterConfig: await cluster.createSavableObject(),
|
||||
cluster: await cluster.createSavableObject(),
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
||||
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.cluster.IRequest_GetAllClusters>(
|
||||
new plugins.typedrequest.TypedHandler('getAllClusters', async (dataArg) => {
|
||||
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.cluster.IReq_Any_Cloudly_GetClusters>(
|
||||
new plugins.typedrequest.TypedHandler('getClusters', async (dataArg) => {
|
||||
// TODO: do authentication here
|
||||
const clusters = await this.getAllClusters();
|
||||
return {
|
||||
@ -56,12 +56,12 @@ export class ClusterManager {
|
||||
);
|
||||
|
||||
// delete cluster
|
||||
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.cluster.IRequest_DeleteCluster>(
|
||||
new plugins.typedrequest.TypedHandler('deleteCluster', async (reqDataArg, toolsArg) => {
|
||||
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.cluster.IReq_Any_Cloudly_DeleteClusterById>(
|
||||
new plugins.typedrequest.TypedHandler('deleteClusterById', async (reqDataArg, toolsArg) => {
|
||||
await toolsArg.passGuards([this.cloudlyRef.authManager.adminIdentityGuard], reqDataArg);
|
||||
await this.deleteCluster(reqDataArg.clusterId);
|
||||
return {
|
||||
success: true,
|
||||
ok: true,
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
40
ts/manager.externalregistry/classes.externalregistry.ts
Normal file
40
ts/manager.externalregistry/classes.externalregistry.ts
Normal file
@ -0,0 +1,40 @@
|
||||
import * as plugins from '../plugins.js';
|
||||
import * as paths from '../paths.js';
|
||||
import type { Cloudly } from 'ts/classes.cloudly.js';
|
||||
import type { ExternalRegistryManager } from './classes.externalregistrymanager.js';
|
||||
|
||||
export class ExternalRegistry extends plugins.smartdata.SmartDataDbDoc<ExternalRegistry, plugins.servezoneInterfaces.data.IExternalRegistry, ExternalRegistryManager> {
|
||||
// STATIC
|
||||
public static async getRegistryById(registryIdArg: string) {
|
||||
const externalRegistry = await this.getInstance({
|
||||
id: registryIdArg,
|
||||
});
|
||||
return externalRegistry;
|
||||
}
|
||||
|
||||
public static async getRegistries() {
|
||||
const externalRegistries = await this.getInstances({});
|
||||
return externalRegistries;
|
||||
}
|
||||
|
||||
public static async createExternalRegistry(registryDataArg: Partial<plugins.servezoneInterfaces.data.IExternalRegistry['data']>) {
|
||||
const externalRegistry = new ExternalRegistry();
|
||||
externalRegistry.id = await ExternalRegistry.getNewId();
|
||||
Object.assign(externalRegistry, registryDataArg);
|
||||
await externalRegistry.save();
|
||||
return externalRegistry;
|
||||
}
|
||||
|
||||
// INSTANCE
|
||||
|
||||
@plugins.smartdata.svDb()
|
||||
public id: string;
|
||||
|
||||
@plugins.smartdata.svDb()
|
||||
public data: plugins.servezoneInterfaces.data.IExternalRegistry['data'];
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
import * as plugins from '../plugins.js';
|
||||
import { Cloudly } from '../classes.cloudly.js';
|
||||
import { ExternalRegistry } from './classes.externalregistry.js';
|
||||
|
||||
export class ExternalRegistryManager {
|
||||
public cloudlyRef: Cloudly;
|
||||
public typedrouter = new plugins.typedrequest.TypedRouter();
|
||||
public CExternalRegistry = plugins.smartdata.setDefaultManagerForDoc(this, ExternalRegistry);
|
||||
|
||||
get db() {
|
||||
return this.cloudlyRef.mongodbConnector.smartdataDb;
|
||||
}
|
||||
|
||||
constructor(cloudlyRef: Cloudly) {
|
||||
this.cloudlyRef = cloudlyRef;
|
||||
}
|
||||
|
||||
public async start() {
|
||||
// lets set up a typedrouter
|
||||
this.typedrouter.addTypedRouter(this.typedrouter);
|
||||
|
||||
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.externalRegistry.IReq_GetRegistryById>(
|
||||
new plugins.typedrequest.TypedHandler('getExternalRegistryById', async (dataArg) => {
|
||||
const registry = await ExternalRegistry.getRegistryById(dataArg.id);
|
||||
return {
|
||||
registry: await registry.createSavableObject(),
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.externalRegistry.IReq_GetRegistries>(
|
||||
new plugins.typedrequest.TypedHandler('getExternalRegistries', async (dataArg) => {
|
||||
const registries = await ExternalRegistry.getRegistries();
|
||||
return {
|
||||
registries: await Promise.all(
|
||||
registries.map((registry) => registry.createSavableObject())
|
||||
),
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.externalRegistry.IReq_CreateRegistry>(
|
||||
new plugins.typedrequest.TypedHandler('createExternalRegistry', async (dataArg) => {
|
||||
const registry = await ExternalRegistry.createExternalRegistry(dataArg.registryData);
|
||||
return {
|
||||
registry: await registry.createSavableObject(),
|
||||
};
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
2
ts/manager.externalregistry/index.ts
Normal file
2
ts/manager.externalregistry/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './classes.externalregistrymanager.js';
|
||||
export * from './classes.externalregistry.js';
|
@ -59,4 +59,16 @@ export class SecretBundle extends plugins.smartdata.SmartDataDbDoc<
|
||||
}
|
||||
return returnObject;
|
||||
}
|
||||
|
||||
public async getFlatKeyValueObject(environmentArg: string) {
|
||||
if (!environmentArg) {
|
||||
throw new Error('environment is required');
|
||||
}
|
||||
const secretGroups = await this.getSecretGroups();
|
||||
const returnObject = {};
|
||||
for (const secretGroup of secretGroups) {
|
||||
returnObject[secretGroup.data.key] = secretGroup.data.environments[environmentArg].value;
|
||||
}
|
||||
return returnObject;
|
||||
}
|
||||
}
|
||||
|
@ -35,20 +35,71 @@ export class CloudlySecretManager {
|
||||
this.typedrouter = new plugins.typedrequest.TypedRouter();
|
||||
this.cloudlyRef.typedrouter.addTypedRouter(this.typedrouter);
|
||||
|
||||
this.typedrouter.addTypedHandler(
|
||||
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.secret.IReq_Admin_GetConfigBundlesAndSecretGroups>(
|
||||
'adminGetConfigBundlesAndSecretGroups',
|
||||
// secretbundle routes
|
||||
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.secretbundle.IReq_GetSecretBundles>(
|
||||
new plugins.typedrequest.TypedHandler(
|
||||
'getSecretBundles',
|
||||
async (dataArg, toolsArg) => {
|
||||
await toolsArg.passGuards([this.cloudlyRef.authManager.adminIdentityGuard], dataArg);
|
||||
dataArg.identity.jwt;
|
||||
const secretBundles = await SecretBundle.getInstances({});
|
||||
const secretGroups = await SecretGroup.getInstances({});
|
||||
return {
|
||||
secretBundles: [
|
||||
...(await Promise.all(
|
||||
secretBundles.map((configBundle) => configBundle.createSavableObject()),
|
||||
)),
|
||||
],
|
||||
};
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.secretbundle.IReq_CreateSecretBundle>(
|
||||
new plugins.typedrequest.TypedHandler('createSecretBundle', async (dataArg) => {
|
||||
const secretBundle = new SecretBundle();
|
||||
secretBundle.id = plugins.smartunique.shortId(8);
|
||||
secretBundle.data = dataArg.secretBundle.data;
|
||||
await secretBundle.save();
|
||||
return {
|
||||
resultSecretBundle: await secretBundle.createSavableObject(),
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
||||
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.secretbundle.IReq_UpdateSecretBundle>(
|
||||
new plugins.typedrequest.TypedHandler('updateSecretBundle', async (dataArg) => {
|
||||
const secretBundle = await SecretBundle.getInstance({
|
||||
id: dataArg.secretBundle.id,
|
||||
});
|
||||
secretBundle.data = dataArg.secretBundle.data;
|
||||
await secretBundle.save();
|
||||
return {
|
||||
resultSecretBundle: await secretBundle.createSavableObject(),
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
||||
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.secretbundle.IReq_DeleteSecretBundleById>(
|
||||
new plugins.typedrequest.TypedHandler('deleteSecretBundleById', async (dataArg) => {
|
||||
const secretBundle = await SecretBundle.getInstance({
|
||||
id: dataArg.secretBundleId,
|
||||
});
|
||||
await secretBundle.delete();
|
||||
return {
|
||||
ok: true,
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
||||
// secretgroup routes
|
||||
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.secretgroup.IReq_GetSecretGroups>(
|
||||
new plugins.typedrequest.TypedHandler(
|
||||
'getSecretGroups',
|
||||
async (dataArg, toolsArg) => {
|
||||
await toolsArg.passGuards([this.cloudlyRef.authManager.adminIdentityGuard], dataArg);
|
||||
dataArg.identity.jwt;
|
||||
const secretGroups = await SecretGroup.getInstances({});
|
||||
return {
|
||||
secretGroups: [
|
||||
...(await Promise.all(
|
||||
secretGroups.map((secretGroup) => secretGroup.createSavableObject()),
|
||||
@ -59,73 +110,64 @@ export class CloudlySecretManager {
|
||||
),
|
||||
);
|
||||
|
||||
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.secret.IReq_Admin_CreateConfigBundlesAndSecretGroups>(
|
||||
new plugins.typedrequest.TypedHandler(
|
||||
'adminCreateConfigBundlesAndSecretGroups',
|
||||
async (dataArg) => {
|
||||
for (const secretGroupObject of dataArg.secretGroups) {
|
||||
const secretGroup = new SecretGroup();
|
||||
secretGroup.id = plugins.smartunique.shortId(8);
|
||||
secretGroup.data = secretGroupObject.data;
|
||||
await secretGroup.save();
|
||||
}
|
||||
return {
|
||||
ok: true,
|
||||
};
|
||||
},
|
||||
),
|
||||
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.secretgroup.IReq_CreateSecretGroup>(
|
||||
new plugins.typedrequest.TypedHandler('createSecretGroup', async (dataArg) => {
|
||||
const secretGroup = new SecretGroup();
|
||||
secretGroup.id = plugins.smartunique.shortId(8);
|
||||
secretGroup.data = dataArg.secretGroup.data;
|
||||
await secretGroup.save();
|
||||
return {
|
||||
resultSecretGroup: await secretGroup.createSavableObject(),
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
||||
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.secretgroup.IReq_UpdateSecretGroup>(
|
||||
new plugins.typedrequest.TypedHandler('updateSecretGroup', async (dataArg) => {
|
||||
const secretGroup = await SecretGroup.getInstance({
|
||||
id: dataArg.secretGroup.id,
|
||||
});
|
||||
secretGroup.data = dataArg.secretGroup.data;
|
||||
await secretGroup.save();
|
||||
return {
|
||||
resultSecretGroup: await secretGroup.createSavableObject(),
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
||||
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.secretgroup.IReq_DeleteSecretGroupById>(
|
||||
new plugins.typedrequest.TypedHandler('deleteSecretGroupById', async (dataArg) => {
|
||||
const secretGroup = await SecretGroup.getInstance({
|
||||
id: dataArg.secretGroupId,
|
||||
});
|
||||
await secretGroup.delete();
|
||||
return {
|
||||
ok: true,
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
||||
this.typedrouter.addTypedHandler(
|
||||
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.secret.IReq_Admin_DeleteConfigBundlesAndSecretGroups>(
|
||||
'adminDeleteConfigBundlesAndSecretGroups',
|
||||
async (dataArg) => {
|
||||
for (const secretGroupId of dataArg.secretGroupIds) {
|
||||
const secretGroup = await SecretGroup.getInstance({
|
||||
id: secretGroupId,
|
||||
});
|
||||
await secretGroup.delete();
|
||||
}
|
||||
for (const secretBundleId of dataArg.secretBundleIds) {
|
||||
const configBundle = await SecretBundle.getInstance({
|
||||
id: secretBundleId,
|
||||
});
|
||||
await configBundle.delete();
|
||||
console.log(`deleted configbundle ${secretBundleId}`);
|
||||
}
|
||||
return {
|
||||
ok: true,
|
||||
};
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
// lets add typedrouter routes for accessing the configvailt from apps
|
||||
this.typedrouter.addTypedHandler(
|
||||
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.secret.IReq_GetEnvBundle>(
|
||||
'getEnvBundle',
|
||||
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.secretbundle.IReq_GetFlatKeyValueObject>(
|
||||
'getFlatKeyValueObject',
|
||||
async (dataArg) => {
|
||||
const wantedBundle = await SecretBundle.getInstance({
|
||||
data: {
|
||||
authorizations: {
|
||||
// @ts-ignore
|
||||
$elemMatch: {
|
||||
secretAccessKey: dataArg.authorization,
|
||||
secretAccessKey: dataArg.secretBundleAuthorization.secretAccessKey,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
const authorization = await wantedBundle.getAuthorizationFromAuthKey(
|
||||
dataArg.authorization,
|
||||
dataArg.secretBundleAuthorization.secretAccessKey,
|
||||
);
|
||||
return {
|
||||
envBundle: {
|
||||
configKeyValueObject: await wantedBundle.getKeyValueObjectForEnvironment(
|
||||
authorization.environment,
|
||||
),
|
||||
environment: authorization.environment,
|
||||
timeSensitive: false,
|
||||
},
|
||||
flatKeyValueObject: await wantedBundle.getKeyValueObjectForEnvironment(
|
||||
authorization.environment,
|
||||
),
|
||||
};
|
||||
},
|
||||
),
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { SecretBundle } from 'ts/manager.secret/classes.secretbundle.js';
|
||||
import * as plugins from '../plugins.js';
|
||||
import { ServiceManager } from './classes.servicemanager.js';
|
||||
|
||||
@ -6,9 +7,51 @@ export class Service extends plugins.smartdata.SmartDataDbDoc<
|
||||
plugins.servezoneInterfaces.data.IService,
|
||||
ServiceManager
|
||||
> {
|
||||
// STATIC
|
||||
public static async getServiceById(serviceIdArg: string) {
|
||||
const service = await this.getInstance({
|
||||
id: serviceIdArg,
|
||||
});
|
||||
return service;
|
||||
}
|
||||
|
||||
public static async getServices() {
|
||||
const services = await this.getInstances({});
|
||||
return services;
|
||||
}
|
||||
|
||||
public static async createService(serviceDataArg: Partial<plugins.servezoneInterfaces.data.IService['data']>) {
|
||||
const service = new Service();
|
||||
service.id = await Service.getNewId();
|
||||
Object.assign(service, serviceDataArg);
|
||||
await service.save();
|
||||
return service;
|
||||
}
|
||||
|
||||
// INSTANCE
|
||||
@plugins.smartdata.svDb()
|
||||
public id: string;
|
||||
|
||||
@plugins.smartdata.svDb()
|
||||
public data: plugins.servezoneInterfaces.data.IService['data'];
|
||||
|
||||
/**
|
||||
* a service runs in a specific environment
|
||||
* so -> this method returns the secret bundles as a flat object accordingly.
|
||||
* in other words, it resolves secret groups for the relevant environment
|
||||
* @param environmentArg
|
||||
*/
|
||||
public async getSecretBundlesAsFlatObject(environmentArg: string = 'production') {
|
||||
const secreBundleIds = this.data.additionalSecretBundleIds || [];
|
||||
secreBundleIds.push(this.data.secretBundleId); // put this last, so it overwrites any other secret bundles.
|
||||
let finalFlatObject = {};
|
||||
for (const secretBundleId of secreBundleIds) {
|
||||
const secretBundle = await SecretBundle.getInstance({
|
||||
id: secretBundleId,
|
||||
});
|
||||
const flatObject = await secretBundle.getFlatKeyValueObject(environmentArg);
|
||||
Object.assign(finalFlatObject, flatObject);
|
||||
}
|
||||
return finalFlatObject;
|
||||
}
|
||||
}
|
||||
|
@ -14,5 +14,87 @@ export class ServiceManager {
|
||||
|
||||
constructor(cloudlyRef: Cloudly) {
|
||||
this.cloudlyRef = cloudlyRef;
|
||||
|
||||
this.typedrouter.addTypedHandler(
|
||||
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.service.IRequest_Any_Cloudly_GetServices>(
|
||||
'getServices',
|
||||
async (reqArg) => {
|
||||
await plugins.smartguard.passGuardsOrReject(reqArg, [
|
||||
this.cloudlyRef.authManager.validIdentityGuard,
|
||||
]);
|
||||
|
||||
const services = await this.CService.getInstances({});
|
||||
|
||||
return {
|
||||
services: await Promise.all(
|
||||
services.map((service) => {
|
||||
return service.createSavableObject();
|
||||
})
|
||||
),
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
this.typedrouter.addTypedHandler(
|
||||
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.service.IRequest_Any_Cloudly_GetServiceSecretBundlesAsFlatObject>(
|
||||
'getServiceSecretBundlesAsFlatObject',
|
||||
async (dataArg) => {
|
||||
const service = await Service.getInstance({
|
||||
id: dataArg.serviceId,
|
||||
});
|
||||
const flatKeyValueObject = await service.getSecretBundlesAsFlatObject(dataArg.environment);
|
||||
return {
|
||||
flatKeyValueObject: flatKeyValueObject,
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
this.typedrouter.addTypedHandler(
|
||||
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.service.IRequest_Any_Cloudly_CreateService>(
|
||||
'createService',
|
||||
async (dataArg) => {
|
||||
const service = await Service.createService(dataArg.serviceData);
|
||||
return {
|
||||
service: await service.createSavableObject(),
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
this.typedrouter.addTypedHandler(
|
||||
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.service.IRequest_Any_Cloudly_UpdateService>(
|
||||
'updateService',
|
||||
async (dataArg) => {
|
||||
const service = await Service.getInstance({
|
||||
id: dataArg.serviceId,
|
||||
});
|
||||
service.data = {
|
||||
...service.data,
|
||||
...dataArg.serviceData,
|
||||
};
|
||||
await service.save();
|
||||
return {
|
||||
service: await service.createSavableObject(),
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
this.typedrouter.addTypedHandler(
|
||||
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.service.IRequest_Any_Cloudly_DeleteServiceById>(
|
||||
'deleteServiceById',
|
||||
async (dataArg) => {
|
||||
const service = await Service.getInstance({
|
||||
id: dataArg.serviceId,
|
||||
});
|
||||
await service.delete();
|
||||
return {
|
||||
success: true,
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,11 @@ import * as plugins from './plugins.js';
|
||||
export type TClientType = 'api' | 'ci' | 'coreflow' | 'cli' | 'serverconfig';
|
||||
|
||||
import { Image } from './classes.image.js';
|
||||
import { Service } from './classes.service.js';
|
||||
import { Cluster } from './classes.cluster.js';
|
||||
import { SecretBundle } from './classes.secretbundle.js';
|
||||
import { SecretGroup } from './classes.secretgroup.js';
|
||||
import { ExternalRegistry } from './classes.externalregistry.js';
|
||||
|
||||
export class CloudlyApiClient {
|
||||
private cloudlyUrl: string;
|
||||
@ -20,7 +25,7 @@ export class CloudlyApiClient {
|
||||
plugins.servezoneInterfaces.requests.server.IRequest_TriggerServerAction['request']
|
||||
>();
|
||||
|
||||
constructor(optionsArg?: {
|
||||
constructor(optionsArg: {
|
||||
registerAs: TClientType;
|
||||
cloudlyUrl?: string;
|
||||
}) {
|
||||
@ -155,8 +160,24 @@ export class CloudlyApiClient {
|
||||
return typedResponse.certificate;
|
||||
}
|
||||
|
||||
public images = {
|
||||
public externalRegistry = {
|
||||
// ExternalRegistry
|
||||
getRegistryById: async (registryNameArg: string) => {
|
||||
return ExternalRegistry.getExternalRegistryById(this, registryNameArg);
|
||||
},
|
||||
getRegistries: async () => {
|
||||
return ExternalRegistry.getExternalRegistries(this);
|
||||
},
|
||||
createRegistry: async (optionsArg: Parameters<typeof ExternalRegistry.createExternalRegistry>[1]) => {
|
||||
return ExternalRegistry.createExternalRegistry(this, optionsArg);
|
||||
}
|
||||
}
|
||||
|
||||
public image = {
|
||||
// Images
|
||||
getImageById: async (imageIdArg: string) => {
|
||||
return Image.getImageById(this, imageIdArg);
|
||||
},
|
||||
getImages: async () => {
|
||||
return Image.getImages(this);
|
||||
},
|
||||
@ -164,4 +185,56 @@ export class CloudlyApiClient {
|
||||
return Image.createImage(this, optionsArg);
|
||||
}
|
||||
}
|
||||
|
||||
public services = {
|
||||
// Services
|
||||
getServiceById: async (serviceIdArg: string) => {
|
||||
return Service.getServiceById(this, serviceIdArg);
|
||||
},
|
||||
getServices: async () => {
|
||||
return Service.getServices(this);
|
||||
},
|
||||
createService: async (optionsArg: Parameters<typeof Service.createService>[1]) => {
|
||||
return Service.createService(this, optionsArg);
|
||||
}
|
||||
}
|
||||
|
||||
public cluster = {
|
||||
// Clusters
|
||||
getClusterById: async (clusterIdArg: string) => {
|
||||
return Cluster.getClusterById(this, clusterIdArg);
|
||||
},
|
||||
getClusters: async () => {
|
||||
return Cluster.getClusters(this);
|
||||
},
|
||||
createCluster: async (optionsArg: Parameters<typeof Cluster.createCluster>[1]) => {
|
||||
return Cluster.createCluster(this, optionsArg);
|
||||
}
|
||||
}
|
||||
|
||||
public secretbundle = {
|
||||
// SecretBundles
|
||||
getSecretBundleById: async (secretBundleIdArg: string) => {
|
||||
return SecretBundle.getSecretBundleById(this, secretBundleIdArg);
|
||||
},
|
||||
getSecretBundles: async () => {
|
||||
return SecretBundle.getSecretBundles(this);
|
||||
},
|
||||
createSecretBundle: async (optionsArg: Parameters<typeof SecretBundle.createSecretBundle>[1]) => {
|
||||
return SecretBundle.createSecretBundle(this, optionsArg);
|
||||
}
|
||||
}
|
||||
|
||||
public secretgroup = {
|
||||
// SecretGroups
|
||||
getSecretGroupById: async (secretGroupIdArg: string) => {
|
||||
return SecretGroup.getSecretGroupById(this, secretGroupIdArg);
|
||||
},
|
||||
getSecretGroups: async () => {
|
||||
return SecretGroup.getSecretGroups(this);
|
||||
},
|
||||
createSecretGroup: async (optionsArg: Parameters<typeof SecretGroup.createSecretGroup>[1]) => {
|
||||
return SecretGroup.createSecretGroup(this, optionsArg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,84 @@
|
||||
import { CloudlyApiClient } from './classes.cloudlyapiclient.js';
|
||||
import * as plugins from './plugins.js';
|
||||
|
||||
export class Cluster {
|
||||
public getServers() {}
|
||||
|
||||
export class Cluster implements plugins.servezoneInterfaces.data.ICluster {
|
||||
// STATIC
|
||||
public static async getClusterById(cloudlyClientRef: CloudlyApiClient, clusterIdArg: string) {
|
||||
const getClusterByIdTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.cluster.IReq_Any_Cloudly_GetClusterById>(
|
||||
'getClusterById'
|
||||
);
|
||||
const response = await getClusterByIdTR.fire({
|
||||
identity: cloudlyClientRef.identity,
|
||||
clusterId: clusterIdArg,
|
||||
});
|
||||
const newCluster = new Cluster(cloudlyClientRef);
|
||||
Object.assign(newCluster, response.cluster);
|
||||
return newCluster;
|
||||
}
|
||||
|
||||
public static async getClusters(cloudlyClientRef: CloudlyApiClient) {
|
||||
const getClustersTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.cluster.IReq_Any_Cloudly_GetClusters>(
|
||||
'getClusters'
|
||||
);
|
||||
const response = await getClustersTR.fire({
|
||||
identity: cloudlyClientRef.identity,
|
||||
});
|
||||
const clusterConfigs: Cluster[] = [];
|
||||
for (const clusterConfig of response.clusters) {
|
||||
const newCluster = new Cluster(cloudlyClientRef);
|
||||
Object.assign(newCluster, clusterConfig);
|
||||
clusterConfigs.push(newCluster);
|
||||
}
|
||||
return clusterConfigs;
|
||||
}
|
||||
|
||||
public static async createCluster(cloudlyClientRef: CloudlyApiClient, clusterNameArg: string) {
|
||||
const createClusterTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.cluster.IRequest_CreateCluster>(
|
||||
'createCluster'
|
||||
);
|
||||
const response = await createClusterTR.fire({
|
||||
identity: cloudlyClientRef.identity,
|
||||
clusterName: clusterNameArg,
|
||||
});
|
||||
const newCluster = new Cluster(cloudlyClientRef);
|
||||
Object.assign(newCluster, response.cluster);
|
||||
return newCluster;
|
||||
}
|
||||
|
||||
// INSTANCE
|
||||
public id: string;
|
||||
public data: plugins.servezoneInterfaces.data.ICluster['data'];
|
||||
public cloudlyClientRef: CloudlyApiClient;
|
||||
|
||||
constructor(cloudlyClientRef: CloudlyApiClient) {
|
||||
this.cloudlyClientRef = cloudlyClientRef;
|
||||
}
|
||||
|
||||
|
||||
public async update() {
|
||||
const updateClusterTR = this.cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.cluster.IReq_Any_Cloudly_UpdateCluster>(
|
||||
'updateCluster'
|
||||
);
|
||||
const response = await updateClusterTR.fire({
|
||||
identity: this.cloudlyClientRef.identity,
|
||||
clusterData: this.data,
|
||||
});
|
||||
|
||||
const resultClusterData = response.resultCluster.data;
|
||||
plugins.smartexpect.expect(resultClusterData).toEqual(this.data);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public async delete(cloudlyClientRef: CloudlyApiClient, clusterIdArg: string) {
|
||||
const deleteClusterTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.cluster.IReq_Any_Cloudly_DeleteClusterById>(
|
||||
'deleteClusterById'
|
||||
);
|
||||
const response = await deleteClusterTR.fire({
|
||||
identity: cloudlyClientRef.identity,
|
||||
clusterId: this.id,
|
||||
});
|
||||
plugins.smartexpect.expect(response.ok).toBeTrue();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
83
ts_apiclient/classes.externalregistry.ts
Normal file
83
ts_apiclient/classes.externalregistry.ts
Normal file
@ -0,0 +1,83 @@
|
||||
import * as plugins from './plugins.js';
|
||||
import type { CloudlyApiClient } from './classes.cloudlyapiclient.js';
|
||||
|
||||
export class ExternalRegistry implements plugins.servezoneInterfaces.data.IExternalRegistry {
|
||||
// STATIC
|
||||
public static async getExternalRegistryById(cloudlyClientRef: CloudlyApiClient, registryNameArg: string) {
|
||||
const getRegistryByIdTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.externalRegistry.IReq_GetRegistryById>(
|
||||
'getExternalRegistryById'
|
||||
);
|
||||
const response = await getRegistryByIdTR.fire({
|
||||
identity: cloudlyClientRef.identity,
|
||||
id: registryNameArg,
|
||||
});
|
||||
const newRegistry = new ExternalRegistry(cloudlyClientRef);
|
||||
Object.assign(newRegistry, response.registry);
|
||||
return newRegistry;
|
||||
}
|
||||
|
||||
public static async getExternalRegistries(cloudlyClientRef: CloudlyApiClient) {
|
||||
const getRegistriesTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.externalRegistry.IReq_GetRegistries>(
|
||||
'getExternalRegistries'
|
||||
);
|
||||
const response = await getRegistriesTR.fire({
|
||||
identity: cloudlyClientRef.identity,
|
||||
});
|
||||
const registryConfigs: ExternalRegistry[] = [];
|
||||
for (const registryConfig of response.registries) {
|
||||
const newRegistry = new ExternalRegistry(cloudlyClientRef);
|
||||
Object.assign(newRegistry, registryConfig);
|
||||
registryConfigs.push(newRegistry);
|
||||
}
|
||||
return registryConfigs;
|
||||
}
|
||||
|
||||
public static async createExternalRegistry(cloudlyClientRef: CloudlyApiClient, registryDataArg: Partial<plugins.servezoneInterfaces.data.IExternalRegistry['data']>) {
|
||||
const createRegistryTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.externalRegistry.IReq_CreateRegistry>(
|
||||
'createExternalRegistry'
|
||||
);
|
||||
const response = await createRegistryTR.fire({
|
||||
identity: cloudlyClientRef.identity,
|
||||
registryData: registryDataArg as plugins.servezoneInterfaces.data.IExternalRegistry['data'],
|
||||
});
|
||||
const newRegistry = new ExternalRegistry(cloudlyClientRef);
|
||||
Object.assign(newRegistry, response.registry);
|
||||
return newRegistry;
|
||||
}
|
||||
|
||||
// INSTANCE
|
||||
public id: string;
|
||||
public data: plugins.servezoneInterfaces.data.IExternalRegistry['data'];
|
||||
public cloudlyClientRef: CloudlyApiClient;
|
||||
|
||||
constructor(cloudlyClientRef: CloudlyApiClient) {
|
||||
this.cloudlyClientRef = cloudlyClientRef;
|
||||
}
|
||||
|
||||
public async update() {
|
||||
const updateRegistryTR = this.cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.externalRegistry.IReq_UpdateRegistry>(
|
||||
'updateExternalRegistry'
|
||||
);
|
||||
const response = await updateRegistryTR.fire({
|
||||
identity: this.cloudlyClientRef.identity,
|
||||
registryData: this.data,
|
||||
});
|
||||
|
||||
const resultRegistryData = response.resultRegistry.data;
|
||||
plugins.smartexpect.expect(resultRegistryData).toEqual(this.data);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public async delete(cloudlyClientRef: CloudlyApiClient, registryIdArg: string) {
|
||||
const deleteRegistryTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.externalRegistry.IReq_DeleteRegistryById>(
|
||||
'deleteExternalRegistryById'
|
||||
);
|
||||
const response = await deleteRegistryTR.fire({
|
||||
identity: cloudlyClientRef.identity,
|
||||
registryId: this.id,
|
||||
});
|
||||
plugins.smartexpect.expect(response.ok).toBeTrue();
|
||||
return null;
|
||||
}
|
||||
}
|
@ -18,6 +18,19 @@ export class Image implements plugins.servezoneInterfaces.data.IImage {
|
||||
return resultImages;
|
||||
}
|
||||
|
||||
public static async getImageById(cloudlyClientRef: CloudlyApiClient, imageIdArg: string) {
|
||||
const getImageByIdTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.image.IRequest_GetImage>(
|
||||
'getImage'
|
||||
);
|
||||
const response = await getImageByIdTR.fire({
|
||||
identity: cloudlyClientRef.identity,
|
||||
imageId: imageIdArg,
|
||||
});
|
||||
const newImage = new Image(cloudlyClientRef);
|
||||
Object.assign(newImage, response.image);
|
||||
return newImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* creates a new image
|
||||
*/
|
||||
|
135
ts_apiclient/classes.secretbundle.ts
Normal file
135
ts_apiclient/classes.secretbundle.ts
Normal file
@ -0,0 +1,135 @@
|
||||
import * as plugins from './plugins.js';
|
||||
import type { CloudlyApiClient } from './classes.cloudlyapiclient.js';
|
||||
import { SecretGroup } from './classes.secretgroup.js';
|
||||
|
||||
export class SecretBundle implements plugins.servezoneInterfaces.data.ISecretBundle {
|
||||
// STATIC
|
||||
public static async getSecretBundleById(cloudlyClientRef: CloudlyApiClient, secretBundleIdArg: string) {
|
||||
const getSecretBundleByIdTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretbundle.IReq_GetSecretBundleById>(
|
||||
'getSecretBundleById'
|
||||
);
|
||||
const response = await getSecretBundleByIdTR.fire({
|
||||
identity: cloudlyClientRef.identity,
|
||||
secretBundleId: secretBundleIdArg,
|
||||
});
|
||||
const newSecretBundle = new SecretBundle(cloudlyClientRef);
|
||||
Object.assign(newSecretBundle, response.secretBundle);
|
||||
return newSecretBundle;
|
||||
}
|
||||
|
||||
public static async getSecretBundleByAuthorization(cloudlyClientRef: CloudlyApiClient, secretBundleAuthorizationArg: plugins.servezoneInterfaces.data.ISecretBundleAuthorization) {
|
||||
const getSecretBundleByAuthorizationTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretbundle.IReq_GetSecretBundleByAuthorization>(
|
||||
'getSecretBundleByAuthorization'
|
||||
);
|
||||
const response = await getSecretBundleByAuthorizationTR.fire({
|
||||
identity: cloudlyClientRef.identity,
|
||||
secretBundleAuthorization: secretBundleAuthorizationArg,
|
||||
});
|
||||
const newSecretBundle = new SecretBundle(cloudlyClientRef);
|
||||
Object.assign(newSecretBundle, response.secretBundle);
|
||||
return newSecretBundle;
|
||||
}
|
||||
|
||||
public static async getSecretBundles(cloudlyClientRef: CloudlyApiClient) {
|
||||
const getSecretBundlesTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretbundle.IReq_GetSecretBundles>(
|
||||
'getSecretBundles'
|
||||
);
|
||||
const response = await getSecretBundlesTR.fire({
|
||||
identity: cloudlyClientRef.identity,
|
||||
});
|
||||
const secretBundles: SecretBundle[] = [];
|
||||
for (const secretBundle of response.secretBundles) {
|
||||
const newSecretBundle = new SecretBundle(cloudlyClientRef);
|
||||
Object.assign(newSecretBundle, secretBundle);
|
||||
secretBundles.push(newSecretBundle);
|
||||
}
|
||||
return secretBundles;
|
||||
}
|
||||
|
||||
public static async createSecretBundle(cloudlyClientRef: CloudlyApiClient, secretBundleDataArg: Partial<plugins.servezoneInterfaces.data.ISecretBundle['data']>) {
|
||||
const createSecretBundleTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretbundle.IReq_CreateSecretBundle>(
|
||||
'createSecretBundle'
|
||||
);
|
||||
const response = await createSecretBundleTR.fire({
|
||||
identity: cloudlyClientRef.identity,
|
||||
secretBundle: {
|
||||
id: null,
|
||||
data: {
|
||||
name: secretBundleDataArg.name,
|
||||
description: secretBundleDataArg.description,
|
||||
type: secretBundleDataArg.type,
|
||||
authorizations: secretBundleDataArg.authorizations,
|
||||
imageClaims: secretBundleDataArg.imageClaims,
|
||||
includedSecretGroupIds: secretBundleDataArg.includedSecretGroupIds,
|
||||
includedTags: secretBundleDataArg.includedTags,
|
||||
},
|
||||
},
|
||||
});
|
||||
const newSecretBundle = new SecretBundle(cloudlyClientRef);
|
||||
Object.assign(newSecretBundle, response.resultSecretBundle);
|
||||
return newSecretBundle;
|
||||
}
|
||||
|
||||
// INSTANCE
|
||||
|
||||
public cloudlyClientRef: CloudlyApiClient;
|
||||
|
||||
public id: string;
|
||||
public data: plugins.servezoneInterfaces.data.ISecretBundle['data'];
|
||||
|
||||
constructor(cloudlyClientRef: CloudlyApiClient) {
|
||||
this.cloudlyClientRef = cloudlyClientRef;
|
||||
}
|
||||
|
||||
public async update() {
|
||||
const updateSecretBundleTR = this.cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretbundle.IReq_UpdateSecretBundle>(
|
||||
'updateSecretBundle'
|
||||
);
|
||||
const response = await updateSecretBundleTR.fire({
|
||||
identity: this.cloudlyClientRef.identity,
|
||||
secretBundle: {
|
||||
id: this.id,
|
||||
data: this.data,
|
||||
},
|
||||
});
|
||||
|
||||
const resultSecretBundleData = response.resultSecretBundle.data;
|
||||
plugins.smartexpect.expect(resultSecretBundleData).toEqual(this.data);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public async delete(cloudlyClientRef: CloudlyApiClient, secretBundleIdArg: string) {
|
||||
const deleteSecretBundleTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretbundle.IReq_DeleteSecretBundleById>(
|
||||
'deleteSecretBundleById'
|
||||
);
|
||||
const response = await deleteSecretBundleTR.fire({
|
||||
identity: cloudlyClientRef.identity,
|
||||
secretBundleId: this.id,
|
||||
});
|
||||
plugins.smartexpect.expect(response.ok).toBeTrue();
|
||||
return null;
|
||||
}
|
||||
|
||||
public async getFlatKeyValueObjectForEnvironment(environmentArg: string = 'production') {
|
||||
const bundleAuthorization = this.data.authorizations.find(authorization => {
|
||||
return authorization.environment === environmentArg;
|
||||
});
|
||||
if (bundleAuthorization) {
|
||||
throw new Error(`no matching environment >>${environmentArg} found in secret bundle`);
|
||||
}
|
||||
|
||||
const getFlatKeyValueObjectTR = this.cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretbundle.IReq_GetFlatKeyValueObject>(
|
||||
'getFlatKeyValueObject'
|
||||
);
|
||||
const response = await getFlatKeyValueObjectTR.fire({
|
||||
identity: this.cloudlyClientRef.identity,
|
||||
seccretBundleId: this.id,
|
||||
secretBundleAuthorization: bundleAuthorization,
|
||||
});
|
||||
|
||||
const flatKeyValueObject: {[key: string]: string} = response.flatKeyValueObject;
|
||||
|
||||
return flatKeyValueObject;
|
||||
}
|
||||
}
|
96
ts_apiclient/classes.secretgroup.ts
Normal file
96
ts_apiclient/classes.secretgroup.ts
Normal file
@ -0,0 +1,96 @@
|
||||
import * as plugins from './plugins.js';
|
||||
import type { CloudlyApiClient } from './classes.cloudlyapiclient.js';
|
||||
|
||||
export class SecretGroup implements plugins.servezoneInterfaces.data.ISecretGroup {
|
||||
public cloudlyClientRef: CloudlyApiClient;
|
||||
|
||||
public id: string;
|
||||
public data: plugins.servezoneInterfaces.data.ISecretGroup['data'];
|
||||
|
||||
constructor(cloudlyClientRef: CloudlyApiClient) {
|
||||
this.cloudlyClientRef = cloudlyClientRef;
|
||||
}
|
||||
|
||||
public static async getSecretGroupById(cloudlyClientRef: CloudlyApiClient, secretGroupIdArg: string) {
|
||||
const getSecretGroupByIdTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretgroup.IReq_GetSecretGroupById>(
|
||||
'getSecretGroupById'
|
||||
);
|
||||
const response = await getSecretGroupByIdTR.fire({
|
||||
identity: cloudlyClientRef.identity,
|
||||
secretGroupId: secretGroupIdArg,
|
||||
});
|
||||
const newSecretGroup = new SecretGroup(cloudlyClientRef);
|
||||
Object.assign(newSecretGroup, response.secretGroup);
|
||||
return newSecretGroup;
|
||||
}
|
||||
|
||||
public static async getSecretGroups(cloudlyClientRef: CloudlyApiClient) {
|
||||
const getSecretGroupsTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretgroup.IReq_GetSecretGroups>(
|
||||
'getSecretGroups'
|
||||
);
|
||||
const response = await getSecretGroupsTR.fire({
|
||||
identity: cloudlyClientRef.identity,
|
||||
});
|
||||
const secretGroups: SecretGroup[] = [];
|
||||
for (const secretGroup of response.secretGroups) {
|
||||
const newSecretGroup = new SecretGroup(cloudlyClientRef);
|
||||
Object.assign(newSecretGroup, secretGroup);
|
||||
secretGroups.push(newSecretGroup);
|
||||
}
|
||||
return secretGroups;
|
||||
}
|
||||
|
||||
public static async createSecretGroup(cloudlyClientRef: CloudlyApiClient, secretGroupDataArg: Partial<plugins.servezoneInterfaces.data.ISecretGroup['data']>) {
|
||||
const createSecretGroupTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretgroup.IReq_CreateSecretGroup>(
|
||||
'createSecretGroup'
|
||||
);
|
||||
const response = await createSecretGroupTR.fire({
|
||||
identity: cloudlyClientRef.identity,
|
||||
secretGroup: {
|
||||
id: null,
|
||||
data: {
|
||||
name: secretGroupDataArg.name,
|
||||
description: secretGroupDataArg.description,
|
||||
environments: secretGroupDataArg.environments,
|
||||
key: secretGroupDataArg.key,
|
||||
tags: secretGroupDataArg.tags,
|
||||
priority: secretGroupDataArg.priority,
|
||||
},
|
||||
},
|
||||
});
|
||||
const newSecretGroup = new SecretGroup(cloudlyClientRef);
|
||||
Object.assign(newSecretGroup, response.resultSecretGroup);
|
||||
return newSecretGroup;
|
||||
}
|
||||
|
||||
// INSTANCE
|
||||
public async update() {
|
||||
const updateSecretGroupTR = this.cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretgroup.IReq_UpdateSecretGroup>(
|
||||
'updateSecretGroup'
|
||||
);
|
||||
const response = await updateSecretGroupTR.fire({
|
||||
identity: this.cloudlyClientRef.identity,
|
||||
secretGroup: {
|
||||
id: this.id,
|
||||
data: this.data,
|
||||
},
|
||||
});
|
||||
|
||||
const resultSecretGroupData = response.resultSecretGroup.data;
|
||||
plugins.smartexpect.expect(resultSecretGroupData).toEqual(this.data);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public async delete(cloudlyClientRef: CloudlyApiClient, secretGroupIdArg: string) {
|
||||
const deleteSecretGroupTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretgroup.IReq_DeleteSecretGroupById>(
|
||||
'deleteSecretGroupById'
|
||||
);
|
||||
const response = await deleteSecretGroupTR.fire({
|
||||
identity: cloudlyClientRef.identity,
|
||||
secretGroupId: this.id,
|
||||
});
|
||||
plugins.smartexpect.expect(response.ok).toBeTrue();
|
||||
return null;
|
||||
}
|
||||
}
|
@ -1,5 +1,78 @@
|
||||
import * as plugins from './plugins.js';
|
||||
import type { CloudlyApiClient } from './classes.cloudlyapiclient.js';
|
||||
|
||||
export class Service {
|
||||
export class Service implements plugins.servezoneInterfaces.data.IService {
|
||||
public static async getServices(cloudlyClientRef: CloudlyApiClient) {
|
||||
const getAllServicesTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.service.IRequest_Any_Cloudly_GetServices>(
|
||||
'getServices'
|
||||
);
|
||||
const response = await getAllServicesTR.fire({
|
||||
identity: cloudlyClientRef.identity,
|
||||
});
|
||||
const resultServices: Service[] = [];
|
||||
for (const service of response.services) {
|
||||
const newService = new Service(cloudlyClientRef);
|
||||
Object.assign(newService, service);
|
||||
resultServices.push(newService);
|
||||
}
|
||||
return resultServices;
|
||||
}
|
||||
|
||||
public static async getServiceById(cloudlyClientRef: CloudlyApiClient, serviceIdArg: string) {
|
||||
const getServiceByIdTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.service.IRequest_Any_Cloudly_GetServiceById>(
|
||||
'getServiceById'
|
||||
);
|
||||
const response = await getServiceByIdTR.fire({
|
||||
identity: cloudlyClientRef.identity,
|
||||
serviceId: serviceIdArg,
|
||||
});
|
||||
const newService = new Service(cloudlyClientRef);
|
||||
Object.assign(newService, response.service);
|
||||
return newService;
|
||||
}
|
||||
|
||||
/**
|
||||
* creates a new service
|
||||
*/
|
||||
public static async createService(cloudlyClientRef: CloudlyApiClient, serviceDataArg: Partial<plugins.servezoneInterfaces.data.IService['data']>) {
|
||||
const createServiceTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.service.IRequest_Any_Cloudly_CreateService>(
|
||||
'createService'
|
||||
);
|
||||
const response = await createServiceTR.fire({
|
||||
identity: cloudlyClientRef.identity,
|
||||
serviceData: serviceDataArg as plugins.servezoneInterfaces.data.IService['data'],
|
||||
});
|
||||
const newService = new Service(cloudlyClientRef);
|
||||
Object.assign(newService, response.service);
|
||||
return newService;
|
||||
}
|
||||
|
||||
// INSTANCE
|
||||
cloudlyClientRef: CloudlyApiClient;
|
||||
|
||||
public id: string;
|
||||
public data: plugins.servezoneInterfaces.data.IService['data'];
|
||||
|
||||
constructor(cloudlyClientRef: CloudlyApiClient) {
|
||||
this.cloudlyClientRef = cloudlyClientRef;
|
||||
}
|
||||
|
||||
/**
|
||||
* The service has a secret bundle.
|
||||
* This function essentially returns the secret bundle as a flat object.
|
||||
* In other words, it resolves secret groups and
|
||||
*/
|
||||
public async getSecretBundleAsFlatObject(environmentArg: string = 'production') {
|
||||
const getServiceSecretBundlesAsFlatObjectTR = this.cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.service.IRequest_Any_Cloudly_GetServiceSecretBundlesAsFlatObject>(
|
||||
'getServiceSecretBundlesAsFlatObject'
|
||||
);
|
||||
const response = await getServiceSecretBundlesAsFlatObjectTR.fire({
|
||||
identity: this.cloudlyClientRef.identity,
|
||||
serviceId: this.id,
|
||||
environment: environmentArg,
|
||||
});
|
||||
const flatKeyValueObject: {[key: string]: string} = response.flatKeyValueObject;
|
||||
|
||||
return flatKeyValueObject;
|
||||
}
|
||||
}
|
||||
|
@ -6,11 +6,13 @@ export {
|
||||
}
|
||||
|
||||
// @push.rocks scope
|
||||
import * as smartexpect from '@push.rocks/smartexpect';
|
||||
import * as smartpromise from '@push.rocks/smartpromise';
|
||||
import * as smartrx from '@push.rocks/smartrx';
|
||||
import * as webstream from '@push.rocks/smartstream/web';
|
||||
|
||||
export {
|
||||
smartexpect,
|
||||
smartpromise,
|
||||
smartrx,
|
||||
webstream,
|
||||
|
15
ts_cliclient/classes.cliclient.ts
Normal file
15
ts_cliclient/classes.cliclient.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import * as plugins from './plugins.js';
|
||||
import { CloudlyApiClient } from '@serve.zone/api';
|
||||
|
||||
export class CliClient {
|
||||
public cloudlyApiClient: CloudlyApiClient;
|
||||
|
||||
constructor(cloudlyApiClientArg: CloudlyApiClient) {
|
||||
this.cloudlyApiClient = cloudlyApiClientArg;
|
||||
}
|
||||
|
||||
public async getClusters() {
|
||||
const clusters = await this.cloudlyApiClient.cluster.getClusters();
|
||||
console.log(clusters);
|
||||
}
|
||||
}
|
@ -1 +1,11 @@
|
||||
console.log('this is the cli client.');
|
||||
import * as plugins from './plugins.js';
|
||||
import { CliClient } from "./classes.cliclient.js";
|
||||
|
||||
export const runCli = async () => {
|
||||
const cliQenv = new plugins.qenv.Qenv();
|
||||
const apiClient = new plugins.servezoneApi.CloudlyApiClient({
|
||||
registerAs: 'cli',
|
||||
cloudlyUrl: await cliQenv.getEnvVarOnDemand('CLOUDLY_URL'),
|
||||
});
|
||||
const cliClient = new CliClient(apiClient);
|
||||
};
|
17
ts_cliclient/plugins.ts
Normal file
17
ts_cliclient/plugins.ts
Normal file
@ -0,0 +1,17 @@
|
||||
// @serve.zone scope
|
||||
import * as servezoneApi from '@serve.zone/api';
|
||||
import * as servezoneInterfaces from '@serve.zone/interfaces';
|
||||
|
||||
export {
|
||||
servezoneApi,
|
||||
servezoneInterfaces
|
||||
}
|
||||
|
||||
// @push.rocks scope
|
||||
import * as projectinfo from '@push.rocks/projectinfo';
|
||||
import * as qenv from '@push.rocks/qenv';
|
||||
|
||||
export {
|
||||
projectinfo,
|
||||
qenv,
|
||||
}
|
@ -1,8 +1,15 @@
|
||||
{
|
||||
"name": "@serve.zone/cli",
|
||||
"dependencies": [],
|
||||
"dependencies": [
|
||||
"@serve.zone/api",
|
||||
"@serve.zone/interfaces",
|
||||
"@push.rocks/projectinfo",
|
||||
"@push.rocks/qenv",
|
||||
"@push.rocks/smartcli"
|
||||
],
|
||||
"registries": [
|
||||
"registry.npmjs.org:public",
|
||||
"verdaccio.lossless.digital:public"
|
||||
]
|
||||
],
|
||||
"bin": ["servezone"]
|
||||
}
|
@ -1,12 +1,11 @@
|
||||
import * as plugins from '../plugins.js';
|
||||
|
||||
/**
|
||||
* results from a DeploymentDirective
|
||||
* a deployment happens when a service is deployed
|
||||
* tracks the status of a deployment
|
||||
*/
|
||||
export interface IDeployment {
|
||||
id: string;
|
||||
deploymentDirectiveId: string;
|
||||
affectedServiceIds: string[];
|
||||
usedImageId: string;
|
||||
deploymentLog: string[];
|
||||
|
@ -1,14 +0,0 @@
|
||||
import type { IServiceRessources } from "./docker.js";
|
||||
|
||||
/**
|
||||
* used for tellilng a cluster about a disired deployment
|
||||
* and specifies its configuration
|
||||
*/
|
||||
export interface IDeploymentDirective {
|
||||
id: string;
|
||||
name: string;
|
||||
imageClaim: string;
|
||||
ports: { hostPort: number; containerPort: number }[];
|
||||
environment: { [key: string]: string };
|
||||
resources?: IServiceRessources;
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
|
||||
export interface IEnvBundle {
|
||||
environment: string;
|
||||
timeSensitive: boolean;
|
||||
configKeyValueObject: {[key: string]: string};
|
||||
}
|
12
ts_interfaces/data/externalregistry.ts
Normal file
12
ts_interfaces/data/externalregistry.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import * as plugins from '../plugins.js';
|
||||
|
||||
export interface IExternalRegistry {
|
||||
id: string;
|
||||
data: {
|
||||
type: 'docker' | 'npm';
|
||||
name: string;
|
||||
url: string;
|
||||
username: string;
|
||||
password: string;
|
||||
};
|
||||
}
|
@ -4,6 +4,11 @@ export interface IImage {
|
||||
id: string;
|
||||
data: {
|
||||
name: string;
|
||||
location: {
|
||||
internal: boolean;
|
||||
externalRegistryId: string;
|
||||
externalImageTag: string;
|
||||
}
|
||||
description: string;
|
||||
versions: Array<{
|
||||
versionString: string;
|
||||
|
@ -2,10 +2,9 @@ export * from './cloudlyconfig.js';
|
||||
export * from './cluster.js';
|
||||
export * from './config.js';
|
||||
export * from './deployment.js';
|
||||
export * from './deploymentdirective.js';
|
||||
export * from './docker.js';
|
||||
export * from './env.js';
|
||||
export * from './event.js';
|
||||
export * from './externalregistry.js';
|
||||
export * from './image.js';
|
||||
export * from './secretbundle.js';
|
||||
export * from './secretgroup.js'
|
||||
|
@ -7,16 +7,33 @@ export interface ISecretBundle {
|
||||
/**
|
||||
* determines if the secret is a service or an external secret
|
||||
* if external secret additional checks are put in place to protect the secret
|
||||
*
|
||||
* * service:
|
||||
* the bundle belongs to a service and can only be used by that service
|
||||
* * npmci:
|
||||
* the bundle is a secret bundle that is used by an npmci pipeline
|
||||
* production secrets will be omitted in any case
|
||||
* * gitzone:
|
||||
* the bundle is a secret bundle that is used by a gitzone.
|
||||
* Only local environment variables are allowed
|
||||
* * external:
|
||||
* the bundle is a secret bundle that is used by an external service
|
||||
*/
|
||||
type: 'service' | 'npmci' | 'gitzone' | 'external';
|
||||
|
||||
|
||||
/**
|
||||
* set this if the secretBundle belongs to a service
|
||||
*/
|
||||
serviceId?: string;
|
||||
|
||||
/**
|
||||
* You can add specific secret groups using this
|
||||
*/
|
||||
includedSecretGroupIds: string[];
|
||||
|
||||
/**
|
||||
* You can add specific tags using this
|
||||
* access to this secretBundle also grants access to resources with matching tags
|
||||
*/
|
||||
includedTags: {
|
||||
key: string;
|
||||
@ -24,19 +41,21 @@ export interface ISecretBundle {
|
||||
}[];
|
||||
|
||||
/**
|
||||
* add images
|
||||
* access to this secretBundle also grants access to the images
|
||||
*/
|
||||
includedImages: {
|
||||
imageClaims: {
|
||||
imageId: string;
|
||||
permissions: ('read' | 'write')[];
|
||||
}[];
|
||||
}[];
|
||||
|
||||
/**
|
||||
* authrozations select a specific environment of a config bundle
|
||||
*/
|
||||
authorizations: Array<{
|
||||
secretAccessKey: string;
|
||||
environment: string;
|
||||
}>;
|
||||
authorizations: Array<ISecretBundleAuthorization>;
|
||||
};
|
||||
}
|
||||
|
||||
export interface ISecretBundleAuthorization {
|
||||
secretAccessKey: string;
|
||||
environment: string;
|
||||
}
|
||||
|
@ -4,10 +4,19 @@ export interface IService {
|
||||
id: string;
|
||||
data: {
|
||||
name: string;
|
||||
description: string;
|
||||
imageId: string;
|
||||
imageVersion: string;
|
||||
environment: { [key: string]: string };
|
||||
/**
|
||||
* the main secret bundle id, exclusive to the service
|
||||
*/
|
||||
secretBundleId: string;
|
||||
/**
|
||||
* those secret bundle ids do not belong to the service itself
|
||||
* and thus live past the service lifecycle
|
||||
*/
|
||||
additionalSecretBundleIds?: string[];
|
||||
scaleFactor: number;
|
||||
balancingStrategy: 'round-robin' | 'least-connections';
|
||||
ports: {
|
||||
@ -21,6 +30,5 @@ export interface IService {
|
||||
protocol?: 'http' | 'https' | 'ssh';
|
||||
}[];
|
||||
deploymentIds: string[];
|
||||
deploymentDirectiveIds: string[];
|
||||
};
|
||||
}
|
||||
|
@ -2,9 +2,9 @@ import * as plugins from '../plugins.js';
|
||||
|
||||
export type TTemplates = 'default' | 'linkaction' | 'notification';
|
||||
|
||||
export interface IRequest_SendEmail extends plugins.typedrequestInterfaces.implementsTR<
|
||||
export interface IReq_SendEmail extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IRequest_SendEmail
|
||||
IReq_SendEmail
|
||||
> {
|
||||
method: 'sendEmail';
|
||||
request: {
|
||||
@ -25,9 +25,9 @@ export interface IRequest_SendEmail extends plugins.typedrequestInterfaces.imple
|
||||
};
|
||||
}
|
||||
|
||||
export interface IRequestRegisterRecipient extends plugins.typedrequestInterfaces.implementsTR<
|
||||
export interface IReq_RegisterRecipient extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IRequestRegisterRecipient
|
||||
IReq_RegisterRecipient
|
||||
> {
|
||||
method: 'registerRecepient';
|
||||
request: {
|
||||
@ -37,3 +37,34 @@ export interface IRequestRegisterRecipient extends plugins.typedrequestInterface
|
||||
status: 'ok' | 'not ok';
|
||||
};
|
||||
}
|
||||
|
||||
export interface IReq_CheckEmailStatus extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IReq_CheckEmailStatus
|
||||
> {
|
||||
method: 'checkEmailStatus';
|
||||
request: {
|
||||
emailId: string;
|
||||
};
|
||||
response: {
|
||||
status: string,
|
||||
details?: { message: string; }
|
||||
};
|
||||
}
|
||||
|
||||
export interface IReq_GetEMailStats extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IReq_GetEMailStats
|
||||
> {
|
||||
method: 'getEmailStats';
|
||||
request: {
|
||||
jwt: string;
|
||||
};
|
||||
response: {
|
||||
totalEmailsSent: number;
|
||||
totalEmailsDelivered: number;
|
||||
totalEmailsBounced: number;
|
||||
averageDeliveryTimeMs: number;
|
||||
lastUpdated: string;
|
||||
};
|
||||
}
|
||||
|
16
ts_interfaces/requests/admin.ts
Normal file
16
ts_interfaces/requests/admin.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import * as plugins from '../plugins.js';
|
||||
import * as userInterfaces from '../data/user.js';
|
||||
|
||||
export interface IReq_Admin_LoginWithUsernameAndPassword extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IReq_Admin_LoginWithUsernameAndPassword
|
||||
> {
|
||||
method: 'adminLoginWithUsernameAndPassword';
|
||||
request: {
|
||||
username: string;
|
||||
password: string;
|
||||
};
|
||||
response: {
|
||||
identity: userInterfaces.IIdentity;
|
||||
}
|
||||
}
|
@ -5,11 +5,11 @@ import * as plugins from '../plugins.js';
|
||||
/**
|
||||
* get all clusters
|
||||
*/
|
||||
export interface IRequest_GetAllClusters extends plugins.typedrequestInterfaces.implementsTR<
|
||||
export interface IReq_Any_Cloudly_GetClusters extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IRequest_GetAllClusters
|
||||
IReq_Any_Cloudly_GetClusters
|
||||
> {
|
||||
method: 'getAllClusters';
|
||||
method: 'getClusters';
|
||||
request: {
|
||||
identity: userInterfaces.IIdentity;
|
||||
};
|
||||
@ -18,6 +18,21 @@ export interface IRequest_GetAllClusters extends plugins.typedrequestInterfaces.
|
||||
};
|
||||
}
|
||||
|
||||
export interface IReq_Any_Cloudly_GetClusterById
|
||||
extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IReq_Any_Cloudly_GetClusterById
|
||||
> {
|
||||
method: 'getClusterById';
|
||||
request: {
|
||||
identity: userInterfaces.IIdentity;
|
||||
clusterId: string;
|
||||
};
|
||||
response: {
|
||||
cluster: clusterInterfaces.ICluster;
|
||||
};
|
||||
}
|
||||
|
||||
export interface IRequest_CreateCluster extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IRequest_CreateCluster
|
||||
@ -28,40 +43,40 @@ export interface IRequest_CreateCluster extends plugins.typedrequestInterfaces.i
|
||||
clusterName: string;
|
||||
};
|
||||
response: {
|
||||
clusterConfig: clusterInterfaces.ICluster;
|
||||
cluster: clusterInterfaces.ICluster;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* updates a cluster
|
||||
*/
|
||||
export interface IRequest_UpdateCluster extends plugins.typedrequestInterfaces.implementsTR<
|
||||
export interface IReq_Any_Cloudly_UpdateCluster extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IRequest_UpdateCluster
|
||||
IReq_Any_Cloudly_UpdateCluster
|
||||
> {
|
||||
method: 'updateCluster';
|
||||
request: {
|
||||
identity: userInterfaces.IIdentity;
|
||||
clusterConfig: clusterInterfaces.ICluster;
|
||||
clusterData: clusterInterfaces.ICluster['data'];
|
||||
};
|
||||
response: {
|
||||
clusterConfig: clusterInterfaces.ICluster;
|
||||
resultCluster: clusterInterfaces.ICluster;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* deletes a cluster
|
||||
*/
|
||||
export interface IRequest_DeleteCluster extends plugins.typedrequestInterfaces.implementsTR<
|
||||
export interface IReq_Any_Cloudly_DeleteClusterById extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IRequest_DeleteCluster
|
||||
IReq_Any_Cloudly_DeleteClusterById
|
||||
> {
|
||||
method: 'deleteCluster';
|
||||
method: 'deleteClusterById';
|
||||
request: {
|
||||
identity: userInterfaces.IIdentity;
|
||||
clusterId: string;
|
||||
};
|
||||
response: {
|
||||
success: boolean;
|
||||
ok: boolean;
|
||||
};
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ import * as clusterInterfaces from '../data/cluster.js';
|
||||
import * as serverInterfaces from '../data/server.js';
|
||||
import * as userInterfaces from '../data/user.js';
|
||||
import type { IService } from '../data/service.js';
|
||||
import type { IDeploymentDirective } from '../data/deploymentdirective.js';
|
||||
|
||||
export interface IRequest_Any_Cloudly_GetServerConfig
|
||||
extends plugins.typedrequestInterfaces.implementsTR<
|
||||
@ -31,7 +30,7 @@ extends plugins.typedrequestInterfaces.implementsTR<
|
||||
};
|
||||
response: {
|
||||
configData: clusterInterfaces.ICluster;
|
||||
deploymentDirectives: IDeploymentDirective[];
|
||||
services: IService[];
|
||||
};
|
||||
}
|
||||
|
||||
@ -43,7 +42,7 @@ extends plugins.typedrequestInterfaces.implementsTR<
|
||||
method: 'pushClusterConfig';
|
||||
request: {
|
||||
configData: clusterInterfaces.ICluster;
|
||||
deploymentDirectives: IDeploymentDirective[];
|
||||
services: IService[];
|
||||
};
|
||||
response: {};
|
||||
}
|
||||
|
72
ts_interfaces/requests/externalregistry.ts
Normal file
72
ts_interfaces/requests/externalregistry.ts
Normal file
@ -0,0 +1,72 @@
|
||||
import * as plugins from '../plugins.js';
|
||||
import * as data from '../data/index.js';
|
||||
import * as userInterfaces from '../data/user.js';
|
||||
|
||||
export interface IReq_GetRegistryById extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IReq_GetRegistryById
|
||||
> {
|
||||
method: 'getExternalRegistryById';
|
||||
request: {
|
||||
identity: userInterfaces.IIdentity;
|
||||
id: string;
|
||||
};
|
||||
response: {
|
||||
registry: data.IExternalRegistry;
|
||||
};
|
||||
}
|
||||
|
||||
export interface IReq_GetRegistries extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IReq_GetRegistries
|
||||
> {
|
||||
method: 'getExternalRegistries';
|
||||
request: {
|
||||
identity: userInterfaces.IIdentity;
|
||||
};
|
||||
response: {
|
||||
registries: data.IExternalRegistry[];
|
||||
};
|
||||
}
|
||||
|
||||
export interface IReq_CreateRegistry extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IReq_CreateRegistry
|
||||
> {
|
||||
method: 'createExternalRegistry';
|
||||
request: {
|
||||
identity: userInterfaces.IIdentity;
|
||||
registryData: data.IExternalRegistry['data'];
|
||||
};
|
||||
response: {
|
||||
registry: data.IExternalRegistry;
|
||||
};
|
||||
}
|
||||
|
||||
export interface IReq_UpdateRegistry extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IReq_UpdateRegistry
|
||||
> {
|
||||
method: 'updateExternalRegistry';
|
||||
request: {
|
||||
identity: userInterfaces.IIdentity;
|
||||
registryData: data.IExternalRegistry['data'];
|
||||
};
|
||||
response: {
|
||||
resultRegistry: data.IExternalRegistry;
|
||||
};
|
||||
}
|
||||
|
||||
export interface IReq_DeleteRegistryById extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IReq_DeleteRegistryById
|
||||
> {
|
||||
method: 'deleteExternalRegistryById';
|
||||
request: {
|
||||
identity: userInterfaces.IIdentity;
|
||||
registryId: string;
|
||||
};
|
||||
response: {
|
||||
ok: boolean;
|
||||
};
|
||||
}
|
@ -18,6 +18,7 @@ export interface IRequest_GetAllImages extends plugins.typedrequestInterfaces.im
|
||||
|
||||
/**
|
||||
* gets a single image
|
||||
* authentication can happen via imageClaim or identity
|
||||
*/
|
||||
export interface IRequest_GetImage extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
|
@ -1,31 +1,39 @@
|
||||
import * as plugins from '../plugins.js';
|
||||
|
||||
import * as adminRequests from './admin.js';
|
||||
import * as certificateRequests from './certificate.js';
|
||||
import * as clusterRequests from './cluster.js';
|
||||
import * as configRequests from './config.js';
|
||||
import * as externalRegistryRequests from './externalregistry.js';
|
||||
import * as identityRequests from './identity.js';
|
||||
import * as imageRequests from './image.js';
|
||||
import * as informRequests from './inform.js';
|
||||
import * as logRequests from './log.js';
|
||||
import * as networkRequests from './network.js';
|
||||
import * as routingRequests from './routing.js';
|
||||
import * as secretRequests from './secret.js';
|
||||
import * as secretBundleRequests from './secretbundle.js';
|
||||
import * as secretGroupRequests from './secretgroup.js';
|
||||
import * as serverRequests from './server.js';
|
||||
import * as serviceRequests from './service.js';
|
||||
import * as statusRequests from './status.js';
|
||||
import * as versionRequests from './version.js';
|
||||
|
||||
export {
|
||||
adminRequests as admin,
|
||||
certificateRequests as certificate,
|
||||
clusterRequests as cluster,
|
||||
configRequests as config,
|
||||
externalRegistryRequests as externalRegistry,
|
||||
identityRequests as identity,
|
||||
imageRequests as image,
|
||||
informRequests as inform,
|
||||
logRequests as log,
|
||||
networkRequests as network,
|
||||
routingRequests as routing,
|
||||
secretRequests as secret,
|
||||
secretBundleRequests as secretbundle,
|
||||
secretGroupRequests as secretgroup,
|
||||
serverRequests as server,
|
||||
serviceRequests as service,
|
||||
statusRequests as status,
|
||||
versionRequests as version,
|
||||
};
|
||||
|
@ -1,94 +0,0 @@
|
||||
import * as plugins from '../plugins.js';
|
||||
import * as data from '../data/index.js';
|
||||
import * as userInterfaces from '../data/user.js';
|
||||
|
||||
export interface IReq_GetEnvBundle extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IReq_GetEnvBundle
|
||||
> {
|
||||
method: 'getEnvBundle';
|
||||
request: {
|
||||
authorization: string;
|
||||
/**
|
||||
* specify this if you want to get a warning, if the envBundle is for an unexpected environment
|
||||
*/
|
||||
environment?: string;
|
||||
};
|
||||
response: {
|
||||
envBundle: data.IEnvBundle;
|
||||
};
|
||||
}
|
||||
|
||||
export interface IReq_Admin_LoginWithUsernameAndPassword extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IReq_Admin_LoginWithUsernameAndPassword
|
||||
> {
|
||||
method: 'adminLoginWithUsernameAndPassword';
|
||||
request: {
|
||||
username: string;
|
||||
password: string;
|
||||
};
|
||||
response: {
|
||||
identity: userInterfaces.IIdentity;
|
||||
}
|
||||
}
|
||||
|
||||
export interface IReq_Admin_GetConfigBundlesAndSecretGroups extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IReq_Admin_GetConfigBundlesAndSecretGroups
|
||||
> {
|
||||
method: 'adminGetConfigBundlesAndSecretGroups';
|
||||
request: {
|
||||
identity: userInterfaces.IIdentity;
|
||||
};
|
||||
response: {
|
||||
secretBundles: data.ISecretBundle[];
|
||||
secretGroups: data.ISecretGroup[];
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
export interface IReq_Admin_CreateConfigBundlesAndSecretGroups extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IReq_Admin_CreateConfigBundlesAndSecretGroups
|
||||
> {
|
||||
method: 'adminCreateConfigBundlesAndSecretGroups';
|
||||
request: {
|
||||
identity: userInterfaces.IIdentity;
|
||||
secretBundles: data.ISecretBundle[];
|
||||
secretGroups: data.ISecretGroup[];
|
||||
};
|
||||
response: {
|
||||
ok: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
export interface IReq_Admin_UpdateConfigBundlesAndSecretGroups extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IReq_Admin_UpdateConfigBundlesAndSecretGroups
|
||||
> {
|
||||
method: 'adminUpdateConfigBundlesAndSecretGroups';
|
||||
request: {
|
||||
identity: userInterfaces.IIdentity;
|
||||
configBundles: data.ISecretBundle[];
|
||||
secretGroups: data.ISecretGroup[];
|
||||
};
|
||||
response: {
|
||||
ok: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
export interface IReq_Admin_DeleteConfigBundlesAndSecretGroups extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IReq_Admin_DeleteConfigBundlesAndSecretGroups
|
||||
> {
|
||||
method: 'adminDeleteConfigBundlesAndSecretGroups';
|
||||
request: {
|
||||
identity: userInterfaces.IIdentity;
|
||||
secretBundleIds: string[];
|
||||
secretGroupIds: string[];
|
||||
};
|
||||
response: {
|
||||
ok: boolean;
|
||||
};
|
||||
}
|
103
ts_interfaces/requests/secretbundle.ts
Normal file
103
ts_interfaces/requests/secretbundle.ts
Normal file
@ -0,0 +1,103 @@
|
||||
import * as plugins from '../plugins.js';
|
||||
import * as data from '../data/index.js';
|
||||
import * as userInterfaces from '../data/user.js';
|
||||
|
||||
export interface IReq_GetSecretBundles extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IReq_GetSecretBundles
|
||||
> {
|
||||
method: 'getSecretBundles';
|
||||
request: {
|
||||
identity: userInterfaces.IIdentity;
|
||||
};
|
||||
response: {
|
||||
secretBundles: data.ISecretBundle[];
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
export interface IReq_GetSecretBundleById extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IReq_GetSecretBundleById
|
||||
> {
|
||||
method: 'getSecretBundleById';
|
||||
request: {
|
||||
identity: userInterfaces.IIdentity;
|
||||
secretBundleId: string;
|
||||
};
|
||||
response: {
|
||||
secretBundle: data.ISecretBundle;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
export interface IReq_CreateSecretBundle extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IReq_CreateSecretBundle
|
||||
> {
|
||||
method: 'createSecretBundle';
|
||||
request: {
|
||||
identity: userInterfaces.IIdentity;
|
||||
secretBundle: data.ISecretBundle;
|
||||
};
|
||||
response: {
|
||||
resultSecretBundle: data.ISecretBundle;
|
||||
};
|
||||
}
|
||||
|
||||
export interface IReq_UpdateSecretBundle extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IReq_UpdateSecretBundle
|
||||
> {
|
||||
method: 'updateSecretBundle';
|
||||
request: {
|
||||
identity: userInterfaces.IIdentity;
|
||||
secretBundle: data.ISecretBundle;
|
||||
};
|
||||
response: {
|
||||
resultSecretBundle: data.ISecretBundle;
|
||||
};
|
||||
}
|
||||
|
||||
export interface IReq_DeleteSecretBundleById extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IReq_DeleteSecretBundleById
|
||||
> {
|
||||
method: 'deleteSecretBundleById';
|
||||
request: {
|
||||
identity: userInterfaces.IIdentity;
|
||||
secretBundleId: string;
|
||||
};
|
||||
response: {
|
||||
ok: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
export interface IReq_GetSecretBundleByAuthorization extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IReq_GetSecretBundleByAuthorization
|
||||
> {
|
||||
method: 'getSecretBundleByAuthorization';
|
||||
request: {
|
||||
identity: userInterfaces.IIdentity;
|
||||
secretBundleAuthorization: data.ISecretBundleAuthorization;
|
||||
};
|
||||
response: {
|
||||
secretBundle: data.ISecretBundle;
|
||||
};
|
||||
}
|
||||
|
||||
export interface IReq_GetFlatKeyValueObject extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IReq_GetFlatKeyValueObject
|
||||
> {
|
||||
method: 'getFlatKeyValueObject';
|
||||
request: {
|
||||
identity: userInterfaces.IIdentity;
|
||||
seccretBundleId: string;
|
||||
secretBundleAuthorization: data.ISecretBundleAuthorization;
|
||||
};
|
||||
response: {
|
||||
flatKeyValueObject: {[key: string]: string};
|
||||
};
|
||||
}
|
74
ts_interfaces/requests/secretgroup.ts
Normal file
74
ts_interfaces/requests/secretgroup.ts
Normal file
@ -0,0 +1,74 @@
|
||||
import * as plugins from '../plugins.js';
|
||||
import * as data from '../data/index.js';
|
||||
import * as userInterfaces from '../data/user.js';
|
||||
|
||||
export interface IReq_GetSecretGroups extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IReq_GetSecretGroups
|
||||
> {
|
||||
method: 'getSecretGroups';
|
||||
request: {
|
||||
identity: userInterfaces.IIdentity;
|
||||
};
|
||||
response: {
|
||||
secretGroups: data.ISecretGroup[];
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
export interface IReq_GetSecretGroupById extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IReq_GetSecretGroupById
|
||||
> {
|
||||
method: 'getSecretGroupById';
|
||||
request: {
|
||||
identity: userInterfaces.IIdentity;
|
||||
secretGroupId: string;
|
||||
};
|
||||
response: {
|
||||
secretGroup: data.ISecretGroup;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
export interface IReq_CreateSecretGroup extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IReq_CreateSecretGroup
|
||||
> {
|
||||
method: 'createSecretGroup';
|
||||
request: {
|
||||
identity: userInterfaces.IIdentity;
|
||||
secretGroup: data.ISecretGroup;
|
||||
};
|
||||
response: {
|
||||
resultSecretGroup: data.ISecretGroup;
|
||||
};
|
||||
}
|
||||
|
||||
export interface IReq_UpdateSecretGroup extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IReq_UpdateSecretGroup
|
||||
> {
|
||||
method: 'updateSecretGroup';
|
||||
request: {
|
||||
identity: userInterfaces.IIdentity;
|
||||
secretGroup: data.ISecretGroup;
|
||||
};
|
||||
response: {
|
||||
resultSecretGroup: data.ISecretGroup;
|
||||
};
|
||||
}
|
||||
|
||||
export interface IReq_DeleteSecretGroupById extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IReq_DeleteSecretGroupById
|
||||
> {
|
||||
method: 'deleteSecretGroupById';
|
||||
request: {
|
||||
identity: userInterfaces.IIdentity;
|
||||
secretGroupId: string;
|
||||
};
|
||||
response: {
|
||||
ok: boolean;
|
||||
};
|
||||
}
|
95
ts_interfaces/requests/service.ts
Normal file
95
ts_interfaces/requests/service.ts
Normal file
@ -0,0 +1,95 @@
|
||||
import * as plugins from '../plugins.js';
|
||||
import type { IService } from '../data/service.js';
|
||||
import type { IIdentity } from '../data/user.js';
|
||||
import type { IServiceRessources } from '../data/docker.js';
|
||||
|
||||
export interface IRequest_Any_Cloudly_GetServiceById
|
||||
extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IRequest_Any_Cloudly_GetServiceById
|
||||
> {
|
||||
method: 'getServiceById';
|
||||
request: {
|
||||
identity: IIdentity;
|
||||
serviceId: string;
|
||||
};
|
||||
response: {
|
||||
service: IService;
|
||||
};
|
||||
}
|
||||
|
||||
export interface IRequest_Any_Cloudly_GetServices
|
||||
extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IRequest_Any_Cloudly_GetServices
|
||||
> {
|
||||
method: 'getServices';
|
||||
request: {
|
||||
identity: IIdentity;
|
||||
};
|
||||
response: {
|
||||
services: IService[];
|
||||
};
|
||||
}
|
||||
|
||||
export interface IRequest_Any_Cloudly_CreateService
|
||||
extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IRequest_Any_Cloudly_CreateService
|
||||
> {
|
||||
method: 'createService';
|
||||
request: {
|
||||
identity: IIdentity;
|
||||
serviceData: IService['data'];
|
||||
};
|
||||
response: {
|
||||
service: IService;
|
||||
};
|
||||
}
|
||||
|
||||
export interface IRequest_Any_Cloudly_UpdateService
|
||||
extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IRequest_Any_Cloudly_UpdateService
|
||||
> {
|
||||
method: 'updateService';
|
||||
request: {
|
||||
identity: IIdentity;
|
||||
serviceId: string;
|
||||
serviceData: IService['data'];
|
||||
};
|
||||
response: {
|
||||
service: IService;
|
||||
};
|
||||
}
|
||||
|
||||
export interface IRequest_Any_Cloudly_DeleteServiceById
|
||||
extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IRequest_Any_Cloudly_DeleteServiceById
|
||||
> {
|
||||
method: 'deleteServiceById';
|
||||
request: {
|
||||
identity: IIdentity;
|
||||
serviceId: string;
|
||||
};
|
||||
response: {
|
||||
success: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
export interface IRequest_Any_Cloudly_GetServiceSecretBundlesAsFlatObject
|
||||
extends plugins.typedrequestInterfaces.implementsTR<
|
||||
plugins.typedrequestInterfaces.ITypedRequest,
|
||||
IRequest_Any_Cloudly_GetServiceSecretBundlesAsFlatObject
|
||||
> {
|
||||
method: 'getServiceSecretBundlesAsFlatObject';
|
||||
request: {
|
||||
identity: IIdentity;
|
||||
serviceId: string;
|
||||
environment: string;
|
||||
};
|
||||
response: {
|
||||
flatKeyValueObject: {[key: string]: string};
|
||||
};
|
||||
}
|
@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@serve.zone/cloudly',
|
||||
version: '4.3.8',
|
||||
version: '5.0.4',
|
||||
description: 'A comprehensive tool for managing containerized applications across multiple cloud providers using Docker Swarmkit, featuring web, CLI, and API interfaces.'
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ export const loginAction = loginStatePart.createAction<{ username: string; passw
|
||||
async (statePartArg, payloadArg) => {
|
||||
const currentState = statePartArg.getState();
|
||||
const trLogin =
|
||||
new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.secret.IReq_Admin_LoginWithUsernameAndPassword>(
|
||||
new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.admin.IReq_Admin_LoginWithUsernameAndPassword>(
|
||||
'/typedrequest',
|
||||
'adminLoginWithUsernameAndPassword'
|
||||
);
|
||||
@ -77,20 +77,34 @@ export const dataState = await appstate.getStatePart<IDataState>(
|
||||
);
|
||||
|
||||
// Getting data
|
||||
export const getAllDataAction = dataState.createAction(async (statePartArg, partialArg?: 'secrets' | 'images') => {
|
||||
export const getAllDataAction = dataState.createAction(async (statePartArg) => {
|
||||
let currentState = statePartArg.getState();
|
||||
// Secrets
|
||||
const trGetSecrets =
|
||||
new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.secret.IReq_Admin_GetConfigBundlesAndSecretGroups>(
|
||||
// SecretsGroups
|
||||
const trGetSecretGroups =
|
||||
new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.secretgroup.IReq_GetSecretGroups>(
|
||||
'/typedrequest',
|
||||
'adminGetConfigBundlesAndSecretGroups'
|
||||
'getSecretGroups'
|
||||
);
|
||||
const response = await trGetSecrets.fire({
|
||||
const response = await trGetSecretGroups.fire({
|
||||
identity: loginStatePart.getState().identity,
|
||||
});
|
||||
currentState = {
|
||||
...currentState,
|
||||
...response,
|
||||
secretGroups: response.secretGroups,
|
||||
};
|
||||
|
||||
// SecretBundles
|
||||
const trGetSecretBundles =
|
||||
new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.secretbundle.IReq_GetSecretBundles>(
|
||||
'/typedrequest',
|
||||
'getSecretBundles'
|
||||
);
|
||||
const responseSecretBundles = await trGetSecretBundles.fire({
|
||||
identity: loginStatePart.getState().identity,
|
||||
});
|
||||
currentState = {
|
||||
...currentState,
|
||||
secretBundles: responseSecretBundles.secretBundles,
|
||||
};
|
||||
|
||||
// images
|
||||
@ -104,14 +118,14 @@ export const getAllDataAction = dataState.createAction(async (statePartArg, part
|
||||
});
|
||||
currentState = {
|
||||
...currentState,
|
||||
...responseImages,
|
||||
images: responseImages.images,
|
||||
};
|
||||
|
||||
// Clusters
|
||||
const trGetClusters =
|
||||
new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.cluster.IRequest_GetAllClusters>(
|
||||
new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.cluster.IReq_Any_Cloudly_GetClusters>(
|
||||
'/typedrequest',
|
||||
'getAllClusters'
|
||||
'getClusters'
|
||||
);
|
||||
const responseClusters = await trGetClusters.fire({
|
||||
identity: loginStatePart.getState().identity,
|
||||
@ -119,7 +133,7 @@ export const getAllDataAction = dataState.createAction(async (statePartArg, part
|
||||
|
||||
currentState = {
|
||||
...currentState,
|
||||
...responseClusters,
|
||||
clusters: responseClusters.clusters,
|
||||
}
|
||||
|
||||
return currentState;
|
||||
@ -130,14 +144,13 @@ export const createSecretGroupAction = dataState.createAction(
|
||||
async (statePartArg, payloadArg: plugins.interfaces.data.ISecretGroup) => {
|
||||
let currentState = statePartArg.getState();
|
||||
const trCreateSecretGroup =
|
||||
new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.secret.IReq_Admin_CreateConfigBundlesAndSecretGroups>(
|
||||
new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.secretgroup.IReq_CreateSecretGroup>(
|
||||
'/typedrequest',
|
||||
'adminCreateConfigBundlesAndSecretGroups'
|
||||
'createSecretGroup'
|
||||
);
|
||||
const response = await trCreateSecretGroup.fire({
|
||||
identity: loginStatePart.getState().identity,
|
||||
secretBundles: [],
|
||||
secretGroups: [payloadArg],
|
||||
secretGroup: payloadArg,
|
||||
});
|
||||
currentState = await dataState.dispatchAction(getAllDataAction, null);
|
||||
return currentState;
|
||||
@ -149,14 +162,13 @@ export const deleteSecretGroupAction = dataState.createAction(
|
||||
async (statePartArg, payloadArg: { secretGroupId: string }) => {
|
||||
let currentState = statePartArg.getState();
|
||||
const trDeleteSecretGroup =
|
||||
new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.secret.IReq_Admin_DeleteConfigBundlesAndSecretGroups>(
|
||||
new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.secretgroup.IReq_DeleteSecretGroupById>(
|
||||
'/typedrequest',
|
||||
'adminDeleteConfigBundlesAndSecretGroups'
|
||||
'deleteSecretGroupById'
|
||||
);
|
||||
const response = await trDeleteSecretGroup.fire({
|
||||
identity: loginStatePart.getState().identity,
|
||||
secretBundleIds: [],
|
||||
secretGroupIds: [payloadArg.secretGroupId],
|
||||
secretGroupId: payloadArg.secretGroupId,
|
||||
});
|
||||
currentState = await dataState.dispatchAction(getAllDataAction, null);
|
||||
return currentState;
|
||||
@ -168,14 +180,13 @@ export const deleteSecretBundleAction = dataState.createAction(
|
||||
async (statePartArg, payloadArg: { configBundleId: string }) => {
|
||||
let currentState = statePartArg.getState();
|
||||
const trDeleteConfigBundle =
|
||||
new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.secret.IReq_Admin_DeleteConfigBundlesAndSecretGroups>(
|
||||
new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.secretbundle.IReq_DeleteSecretBundleById>(
|
||||
'/typedrequest',
|
||||
'adminDeleteConfigBundlesAndSecretGroups'
|
||||
'deleteSecretBundleById'
|
||||
);
|
||||
const response = await trDeleteConfigBundle.fire({
|
||||
identity: loginStatePart.getState().identity,
|
||||
secretBundleIds: [payloadArg.configBundleId],
|
||||
secretGroupIds: [],
|
||||
secretBundleId: payloadArg.configBundleId,
|
||||
});
|
||||
currentState = await dataState.dispatchAction(getAllDataAction, null);
|
||||
return currentState;
|
||||
@ -249,7 +260,7 @@ export const addClusterAction = dataState.createAction(
|
||||
currentState = {
|
||||
...currentState,
|
||||
...{
|
||||
clusters: [...currentState.clusters, response.clusterConfig],
|
||||
clusters: [...currentState.clusters, response.cluster],
|
||||
},
|
||||
}
|
||||
return currentState;
|
||||
|
@ -24,6 +24,7 @@ import { CloudlyViewS3 } from './cloudly-view-s3.js';
|
||||
import { CloudlyViewSecretBundles } from './cloudly-view-secretbundles.js';
|
||||
import { CloudlyViewSecretGroups } from './cloudly-view-secretgroups.js';
|
||||
import { CloudlyViewServices } from './cloudly-view-services.js';
|
||||
import { CloudlyViewExternalRegistries } from './cloudly-view-externalregistries.js';
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
@ -89,6 +90,10 @@ export class CloudlyDashboard extends DeesElement {
|
||||
name: 'Clusters',
|
||||
element: CloudlyViewClusters,
|
||||
},
|
||||
{
|
||||
name: 'ExternalRegistries',
|
||||
element: CloudlyViewExternalRegistries,
|
||||
},
|
||||
{
|
||||
name: 'Images',
|
||||
element: CloudlyViewImages,
|
||||
|
129
ts_web/elements/cloudly-view-externalregistries.ts
Normal file
129
ts_web/elements/cloudly-view-externalregistries.ts
Normal file
@ -0,0 +1,129 @@
|
||||
import * as plugins from '../plugins.js';
|
||||
import * as shared from '../elements/shared/index.js';
|
||||
|
||||
import {
|
||||
DeesElement,
|
||||
customElement,
|
||||
html,
|
||||
state,
|
||||
css,
|
||||
cssManager,
|
||||
} from '@design.estate/dees-element';
|
||||
|
||||
import * as appstate from '../appstate.js';
|
||||
|
||||
@customElement('cloudly-view-externalregistries')
|
||||
export class CloudlyViewExternalRegistries extends DeesElement {
|
||||
@state()
|
||||
private data: appstate.IDataState = {
|
||||
secretGroups: [],
|
||||
secretBundles: [],
|
||||
};
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
const subecription = appstate.dataState
|
||||
.select((stateArg) => stateArg)
|
||||
.subscribe((dataArg) => {
|
||||
this.data = dataArg;
|
||||
});
|
||||
this.rxSubscriptions.push(subecription);
|
||||
}
|
||||
|
||||
public static styles = [
|
||||
cssManager.defaultStyles,
|
||||
shared.viewHostCss,
|
||||
css`
|
||||
`,
|
||||
];
|
||||
|
||||
public render() {
|
||||
return html`
|
||||
<cloudly-sectionheading>External Registries</cloudly-sectionheading>
|
||||
<dees-table
|
||||
.heading1=${'External Registries'}
|
||||
.heading2=${'decoded in client'}
|
||||
.data=${this.data.deployments}
|
||||
.displayFunction=${(itemArg: plugins.interfaces.data.ICluster) => {
|
||||
return {
|
||||
id: itemArg.id,
|
||||
serverAmount: itemArg.data.servers.length,
|
||||
};
|
||||
}}
|
||||
.dataActions=${[
|
||||
{
|
||||
name: 'add configBundle',
|
||||
iconName: 'plus',
|
||||
type: ['header', 'footer'],
|
||||
actionFunc: async (dataActionArg) => {
|
||||
const modal = await plugins.deesCatalog.DeesModal.createAndShow({
|
||||
heading: 'Add ConfigBundle',
|
||||
content: html`
|
||||
<dees-form>
|
||||
<dees-input-text .key=${'id'} .label=${'ID'} .value=${''}></dees-input-text>
|
||||
<dees-input-text
|
||||
.key=${'data.secretGroupIds'}
|
||||
.label=${'secretGroupIds'}
|
||||
.value=${''}
|
||||
></dees-input-text>
|
||||
<dees-input-text
|
||||
.key=${'data.includedTags'}
|
||||
.label=${'includedTags'}
|
||||
.value=${''}
|
||||
></dees-input-text>
|
||||
</dees-form>
|
||||
`,
|
||||
menuOptions: [
|
||||
{ name: 'create', action: async (modalArg) => {} },
|
||||
{
|
||||
name: 'cancel',
|
||||
action: async (modalArg) => {
|
||||
modalArg.destroy();
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'delete',
|
||||
iconName: 'trash',
|
||||
type: ['contextmenu', 'inRow'],
|
||||
actionFunc: async (actionDataArg) => {
|
||||
plugins.deesCatalog.DeesModal.createAndShow({
|
||||
heading: `Delete ConfigBundle ${actionDataArg.item.id}`,
|
||||
content: html`
|
||||
<div style="text-align:center">
|
||||
Do you really want to delete the ConfigBundle?
|
||||
</div>
|
||||
<div
|
||||
style="font-size: 0.8em; color: red; text-align:center; padding: 16px; margin-top: 24px; border: 1px solid #444; font-family: Intel One Mono; font-size: 16px;"
|
||||
>
|
||||
${actionDataArg.item.id}
|
||||
</div>
|
||||
`,
|
||||
menuOptions: [
|
||||
{
|
||||
name: 'cancel',
|
||||
action: async (modalArg) => {
|
||||
await modalArg.destroy();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'delete',
|
||||
action: async (modalArg) => {
|
||||
appstate.dataState.dispatchAction(appstate.deleteSecretBundleAction, {
|
||||
configBundleId: actionDataArg.item.id,
|
||||
});
|
||||
await modalArg.destroy();
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
},
|
||||
},
|
||||
] as plugins.deesCatalog.ITableAction[]}
|
||||
></dees-table>
|
||||
`;
|
||||
}
|
||||
}
|
@ -18,11 +18,28 @@ export class CloudlySectionheading extends DeesElement {
|
||||
public static styles = [
|
||||
cssManager.defaultStyles,
|
||||
css`
|
||||
:host {
|
||||
display: grid;
|
||||
grid-template-columns: min-content min-content;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-family: 'Cal Sans';
|
||||
letter-spacing: 0.025em;
|
||||
margin: 0px;
|
||||
margin-bottom: 16px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.flag {
|
||||
border-radius: 4px;
|
||||
background: #8a0183;
|
||||
height: 20px;
|
||||
padding: 2px 4px;
|
||||
margin-left: 16px;
|
||||
font-size: 12px;
|
||||
transform: translateY(12px);
|
||||
white-space: nowrap;
|
||||
}
|
||||
`,
|
||||
]
|
||||
@ -30,6 +47,7 @@ export class CloudlySectionheading extends DeesElement {
|
||||
public render() {
|
||||
return html`
|
||||
<h1><slot></slot></h1>
|
||||
<div class="flag">stability: alpha</div>
|
||||
`;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user