Compare commits

...

255 Commits

Author SHA1 Message Date
Aleksandr Melnikov
7ae4e1373a Merge pull request #797 from rushtehrani/fix/jupyterlab-data-dir
fix: Set jupyterlab workingDir to /data
2020-12-16 12:33:02 -08:00
rushtehrani
01040a72d1 set jupyterlab workingDir to data 2020-12-16 11:16:19 -08:00
Rush Tehrani
1cf037340c Merge pull request #793 from Vafilor/fix/onepanelio.core.791-gke.jupyterlab.gpu
fix: Issue where gpu didn't work for jupyterlab in gke
2020-12-14 14:32:48 -08:00
Rush Tehrani
81bd32f837 remove extra space 2020-12-14 14:30:00 -08:00
Andrey Melnikov
0b68e88c60 fix: wrong template name 2020-12-14 14:05:08 -08:00
Andrey Melnikov
01cd321a1a fix: added migration to update jupyterlab workspace template to be able to use GPUs in GKE 2020-12-14 14:03:05 -08:00
Rush Tehrani
f54021c820 Merge pull request #788 from Vafilor/fix/gke.gpu
fix: GPU not being present in GKE for workspaces
2020-12-11 19:27:32 -08:00
Andrey Melnikov
172c4e6dd2 chore: clean up code for node pool resource selection 2020-12-11 19:21:51 -08:00
Andrey Melnikov
9302853820 chore: migration method documentation 2020-12-11 16:57:03 -08:00
Andrey Melnikov
5ce0bb1532 fix: add resource limits to a main container
This fixes an issue with GPUs in GKE as the container that needs the GPU needs to have a resource requirement.
2020-12-11 16:52:50 -08:00
Rush Tehrani
b6abe862c9 Merge pull request #783 from Vafilor/fix/revert.argo
chore: revert argo updates for stability
2020-12-11 11:18:53 -08:00
Andrey Melnikov
8735444f54 Merge pull request #785 from Vafilor/fix/workspace.node.pool
chore: changed variable name to better reflect purpose
2020-12-10 22:06:50 -08:00
Andrey Melnikov
909a728a41 chore: changed newParam to be newValue to better describe the functionality 2020-12-10 22:04:00 -08:00
Rush Tehrani
0aee834a9c Merge pull request #782 from Vafilor/fix/workspace.node.pool
fix: issue where workspace params were not updated
2020-12-10 22:03:18 -08:00
Andrey Melnikov
6f9f8ed164 fix: bug where parameters query did not actually update with the set parameters call 2020-12-10 21:27:34 -08:00
Andrey Melnikov
50a57f049c chore: revert argo updates 2020-12-10 20:26:35 -08:00
Andrey Melnikov
5d0d84c5d7 fix: issue where workspace params (like new node pool) were not updated when a workspace was upgraded. 2020-12-10 17:16:38 -08:00
Rush Tehrani
1fa8242a3c Merge pull request #781 from rushtehrani/fix/script-resources
fix: Correctly add resources to script templates
2020-12-10 16:02:40 -08:00
rushtehrani
37f1c0b6eb correctly add resources to script templates 2020-12-10 14:15:55 -08:00
Aleksandr Melnikov
ee7c148a5e Merge pull request #779 from Vafilor/feat/upgrade.tensorflow.workflow
fix: tf training with epochs
2020-12-09 15:16:42 -08:00
Andrey Melnikov
92c387a622 update: tf training with epochs 2020-12-09 13:39:15 -08:00
Aleksandr Melnikov
cb617d0605 Merge pull request #778 from Vafilor/feat/upgrade.tensorflow.workflow
feat: update tensorflow migration
2020-12-09 13:19:53 -08:00
Andrey Melnikov
7f5d52cb13 chore: migration method comments 2020-12-09 13:03:05 -08:00
Andrey Melnikov
ae998d000a feat: update tensorflow migration 2020-12-09 12:58:45 -08:00
Aleksandr Melnikov
93a0770f31 Merge pull request #777 from Vafilor/fix/adjust.curl
fix: adjust curl to use specific version and fail on non 200 responses
2020-12-09 11:16:18 -08:00
Andrey Melnikov
95e2516f66 fix: adjust curl to use specific version and fail on non 200 responses 2020-12-09 11:08:24 -08:00
Andrey Melnikov
4d28ce42d8 Merge pull request #776 from onepanelio/fix/wrong.migration.names
fix: wrong migration folder
2020-12-09 11:05:14 -08:00
Andrey Melnikov
f58263ddb2 fix: wrong migration folder 2020-12-09 11:03:20 -08:00
Andrey Melnikov
16977e3bd0 Merge pull request #775 from onepanelio/fix/wrong.migration.names
fix: wrong migration file names
2020-12-09 11:00:10 -08:00
Andrey Melnikov
24409404f8 fix: wrong migration file names 2020-12-09 10:59:28 -08:00
Aleksandr Melnikov
f8f23451f3 Merge pull request #771 from Vafilor/test/istio.inject
feat: Use env var instead of tty for interactive sidecars
2020-12-09 10:17:53 -08:00
Andrey Melnikov
f8a6670f2d chore: double quotes to single quotes in yaml 2020-12-09 09:54:41 -08:00
Andrey Melnikov
6d165921d8 fix: yaml errors in new migration data 2020-12-08 19:46:50 -08:00
Andrey Melnikov
be8f157235 Merge pull request #770 from rushtehrani/feat/limits
feat: Support GPU resource limits in Workspaces and Workflows
2020-12-08 18:54:04 -08:00
Andrey Melnikov
f9373561fb chore: added missing migration comments 2020-12-08 16:50:42 -08:00
Andrey Melnikov
b1812006f9 update: changed tty to be under the "ONEPANEL_INTERACTIVE_SIDECAR" 2020-12-08 16:46:13 -08:00
Andrey Melnikov
e42ac38103 feat: re-organized data folder for migrations 2020-12-08 16:44:43 -08:00
Aleksandr Melnikov
28651bf333 Merge pull request #774 from Vafilor/fix/add.timeout.to.k8s
feat: update kubernetes timeout to be set via environment variable
2020-12-08 15:31:44 -08:00
Andrey Melnikov
701d31cb74 feat: update kubernetes timeout to be set via environment variable 2020-12-08 13:22:19 -08:00
Aleksandr Melnikov
2331e9fa0f Merge pull request #773 from Vafilor/fix/add.timeout.to.k8s
fix: added timeout to k8s so it doesn't wait forever.
2020-12-08 12:21:45 -08:00
Andrey Melnikov
e29b6266e4 fix: added timeout to k8s so it doesn't wait forever. 2020-12-08 12:14:15 -08:00
Andrey Melnikov
70d604b2d0 test: istio inject var instead of tty 2020-12-07 18:21:57 -08:00
rushtehrani
3abdda5b81 name methods more explicitly 2020-12-07 16:52:26 -08:00
rushtehrani
78fde018fd support resource limits for GPUs in Workflows 2020-12-07 15:51:50 -08:00
rushtehrani
b4ea002387 support resource limits for GPUs in Workspaces 2020-12-07 15:51:37 -08:00
Andrey Melnikov
f11a36f62a Merge pull request #765 from Vafilor/feat/requests.updates
feat: added total results counts to list requests
2020-12-05 13:24:03 -08:00
Andrey Melnikov
a85f97256b Merge pull request #757 from onepanelio/fix/dynamic-envs
fix: Move env vars to workspace creation
2020-12-04 12:58:42 -08:00
rushtehrani
6ca3d60298 update method name to be more descriptive 2020-12-04 12:54:52 -08:00
Andrey Melnikov
906e7c4d7b fix: issue where container env vars were not being updated 2020-12-04 12:37:55 -08:00
rushtehrani
39e9c2e572 wip - move env vars to workspace creation 2020-12-02 10:02:27 -08:00
Rush Tehrani
762abe8e9a Merge pull request #756 from savan77/cvat_tfod_migration
fix: Add migration for changes in TFOD and CVAT template
2020-11-30 13:25:29 -08:00
savan
dbc008100a update indentation in the template 2020-11-30 15:11:40 -06:00
savan
8c00552ba0 remove namespace from path 2020-11-30 15:05:53 -06:00
Rush Tehrani
0639f10834 Fix template name and package name 2020-11-30 12:43:40 -08:00
Rush Tehrani
1946fdd254 Rename 20201130130433_update_tfod_patch.go to 20201130130433_update_tfod_path.go 2020-11-30 12:35:09 -08:00
savan
c556e65a88 use latest template for up 2020-11-30 14:33:40 -06:00
savan
72fa2f1270 update template to the previous one 2020-11-30 14:26:09 -06:00
savan
83812bb68c update TFOD based on last migration 2020-11-30 13:58:59 -06:00
savan
2366cbce01 add migration in db and add comments 2020-11-30 13:45:15 -06:00
Rush Tehrani
446f591a06 Merge pull request #755 from onepanelio/chore/issue-templates
chore: Add issue templates
2020-11-30 11:22:33 -08:00
Rush Tehrani
59492c021d chore: Add issue templates 2020-11-30 11:18:11 -08:00
savan
f6be3732a1 add migration for TFOD and CVAT 2020-11-30 13:17:45 -06:00
Andrey Melnikov
b8b6853909 feat: added total results counts to list requests. This simplifies client logic for determining resource counts 2020-11-24 10:55:52 -08:00
Andrey Melnikov
1aa1cf9cb7 Merge pull request #744 from onepanelio/feat/update.github.workflow
fix: github actions
2020-11-23 12:27:58 -08:00
Andrey Melnikov
0f9902d5c1 test: fix env var reference 2020-11-23 12:08:23 -08:00
Andrey Melnikov
ad55e8fa60 fix: update get-tag to get by set-env github error 2020-11-23 11:55:52 -08:00
Andrey Melnikov
d7e9e19de9 update: slack message 2020-11-23 11:49:57 -08:00
Andrey Melnikov
840e4b1006 Merge pull request #729 from onepanelio/dsdon10-patch-1
feat: include LF AI Landscape onepanel link
2020-11-23 11:29:04 -08:00
Andrey Melnikov
1d0892f245 Merge pull request #740 from gliptak/patch-1
build: Bring Go to 1.15.5 in Dockerfile
2020-11-23 11:26:56 -08:00
Gábor Lipták
9d9b1ab88f Bring Go to 1.15.5 in Dockerfile
Signed-off-by: Gábor Lipták <gliptak@gmail.com>
2020-11-20 20:10:10 -05:00
Rush Tehrani
cfe3d57bb7 Merge pull request #739 from Vafilor/fix/metrics.migration
fix: issue where previous metrics migration was using incorrect format
2020-11-18 20:19:55 -08:00
Andrey Melnikov
5ada969517 fix: issue where previous metrics migration was using old design for metrics column 2020-11-18 20:10:26 -08:00
Andrey Melnikov
c5464d7120 Merge pull request #738 from Vafilor/feat/onepanelio.core.724-metrics.api
feat: add metrics API to core
2020-11-18 12:40:06 -08:00
Andrey Melnikov
ed4b0ae127 fix: metrics add test 2020-11-18 11:12:16 -08:00
Rush Tehrani
e43d7d74a1 Update support options 2020-11-18 11:03:09 -08:00
Andrey Melnikov
0cf38f8c85 chore: method documentation 2020-11-17 13:49:14 -08:00
Andrey Melnikov
fd713e0800 feat: added update metrics endpoint which replaces the contents. Also renamed merge to add to better distinguish the two 2020-11-17 13:42:19 -08:00
Andrey Melnikov
6af5d5b5b0 feat: added merge method workflow executions merge api 2020-11-17 13:32:55 -08:00
Andrey Melnikov
f22c6b051f Merge pull request #736 from Vafilor/feat/onepanelio.723-metrics.db
feat: add metrics database support to workflow executions
2020-11-17 12:39:49 -08:00
Andrey Melnikov
cb402b9496 feat: added methods to Metrics to Add/Merge items 2020-11-17 12:28:51 -08:00
Rush Tehrani
a00e155afb Merge pull request #730 from rushtehrani/fix/cvat
feat: Update CVAT env vars + add TensorBoard
2020-11-17 09:55:54 -08:00
Andrey Melnikov
0a73aed929 feat: updated metrics structure to be an array of structs 2020-11-16 16:04:20 -08:00
Rush Tehrani
085e2a7427 Merge pull request #733 from Vafilor/fix/workspaces.labels
fix: issue where workspace label selection wasn't working.
2020-11-16 15:25:28 -08:00
Andrey Melnikov
0f0616ec6d fix: issue where workspace label selection wasn't working. 2020-11-16 15:19:06 -08:00
rushtehrani
a2fe9f2619 remove incorrect migration 2020-11-16 12:09:14 -08:00
Andrey Melnikov
212ef7c0de feat: added metrics to workflow_executions database related code 2020-11-16 12:08:17 -08:00
Andrey Melnikov
d3af2059d4 Merge pull request #731 from Vafilor/feat/revert.remove.token
fix: puts back IsValidToken endpoint for backwards compatibility
2020-11-16 10:51:06 -08:00
Andrey Melnikov
89c0f26103 Revert "feat: remove is valid token endpoint"
This reverts commit 466a417e60.

Also marks the IsValidToken endpoint as deprecated
2020-11-16 10:46:44 -08:00
rushtehrani
37c01428e2 update models location for previous CVAT templates 2020-11-16 08:50:33 -08:00
Donald Scott
1a5df76cec Update README.md
Added link to http://landscape.lfai.foundation/selected=onepanel
2020-11-16 08:07:45 -08:00
rushtehrani
dc65fc10b9 add tensorboard to maskrcnn workflow 2020-11-15 15:57:28 -08:00
rushtehrani
4abe355ef8 add tensorboard sidecar to tfod workflow 2020-11-15 14:43:53 -08:00
rushtehrani
341a010fc0 update CVAT env vars 2020-11-15 13:42:33 -08:00
Rush Tehrani
52ca9663f5 Merge pull request #728 from aleksandrmelnikov/chore/core.714-get.access.token.cvat
chore: Adding migration for new CVAT image.
2020-11-14 12:41:47 -08:00
Aleksandr Melnikov
173d043074 Commenting on functions. 2020-11-13 13:38:50 -08:00
Aleksandr Melnikov
9ddd69bce8 Adding migration for new CVAT image.
- This image updates the authentication endpoint used for Onepanel
user credentials, inside of CVAT.
2020-11-13 13:06:36 -08:00
Rush Tehrani
7edfc606a0 Merge pull request #713 from onepanelio/test/argo.update
feat: update argo to 2.11.6
2020-11-13 12:41:27 -08:00
Andrey Melnikov
d51db584b7 chore: added comment explaining quotation 2020-11-13 12:09:00 -08:00
Andrey Melnikov
a79100bdf6 Merge branch 'test/argo.update' of github.com:onepanelio/core into test/argo.update 2020-11-13 12:07:21 -08:00
Andrey Melnikov
8a9637bc22 fix: add hydrator 2020-11-13 12:06:18 -08:00
Andrey Melnikov
a291e08252 fix: migrations that had numbers where new argo expects strings 2020-11-13 12:03:53 -08:00
Andrey Melnikov
091e1d7c44 chore: removed todo comments that have been resolved 2020-11-13 12:03:53 -08:00
Andrey Melnikov
3ae2dd8077 upgraded argo to v2.11.6 (wip) 2020-11-13 11:59:44 -08:00
Rush Tehrani
cc919f6d89 Merge pull request #722 from Vafilor/feat/remove.valid.token.endpoint
feat: remove is valid token endpoint
2020-11-13 11:16:11 -08:00
Rush Tehrani
27bebcbc1d Merge pull request #718 from aleksandrmelnikov/chore/removing.unused.function
chore: Removing ensureWorkflowRunsOnDedicatedNode function.
2020-11-13 11:06:02 -08:00
Aleksandr Melnikov
b296d85c07 Merge branch 'master' into chore/removing.unused.function 2020-11-13 10:17:35 -08:00
Andrey Melnikov
466a417e60 feat: remove is valid token endpoint 2020-11-12 15:55:58 -08:00
Aleksandr Melnikov
bfa4def06b Merge pull request #719 from rushtehrani/feat/stop-workflow
feat: Terminate Workflow action will still execute exitHandler tasks
2020-11-12 14:00:25 -08:00
rushtehrani
4fec204e7f use correct where statement 2020-11-12 12:22:15 -08:00
Rush Tehrani
363c430703 Merge pull request #691 from aleksandrmelnikov/feat/core.416-add.ts.to.workflows
feat: Add support for visualization sidecars
2020-11-11 12:04:02 -08:00
rushtehrani
f7e48a0be7 don't update phase for already terminated workflow 2020-11-11 09:53:13 -08:00
rushtehrani
3f70f26da4 use stop instead of terminate 2020-11-10 19:38:52 -08:00
Aleksandr Melnikov
f7c74ebf13 Removing ensureWorkflowRunsOnDedicatedNode function.
- Not used
- We're using a different function
2020-11-10 16:05:36 -08:00
Aleksandr Melnikov
a5ec80e586 If tty is set to true, mirror the main container volume mounts to
sidecars.
- This way, sidecars have access
2020-11-10 15:58:26 -08:00
Aleksandr Melnikov
a67012f893 Tweaking the dependencies of the sys-exit task.
- This ensures that multiple sidecars will vertically end
at the sys-exit task.
2020-11-10 15:58:26 -08:00
Aleksandr Melnikov
806d15f4c9 Adjusting the exit-handler task order.
- sys-exit will run after deletion of service and virtual service
2020-11-10 15:58:26 -08:00
Aleksandr Melnikov
74752efd20 Adding output parameters to the template with the sidecars.
- These are the URLs for the side-cars.
2020-11-10 15:58:26 -08:00
Aleksandr Melnikov
5e4d5c0242 Changed the order of tasks for the exit handler.
- The clean up tasks for service(s) and virtualservice(s) will
now display vertically.
If multiple sidecars were present, parallel vertical rows will display.
2020-11-10 15:58:26 -08:00
Aleksandr Melnikov
c699b5b2ba Changed the order of tasks per feedback.
The new structure is:
 sys-send-status -> service -> virtual service -> main task
If there are multiple sidecars for the same template, they
are displayed next to each other, vertically and in parallel.
2020-11-10 15:58:26 -08:00
Aleksandr Melnikov
5bd7f222cd Removing the workflow.uid, because it causes a doubly long uid string. 2020-11-10 15:58:26 -08:00
Aleksandr Melnikov
04a1db0f81 Adding "sys-" prefix to onepanel injected services and virtualservices. 2020-11-10 15:58:26 -08:00
Aleksandr Melnikov
d4846b521e Putting the services and virtualservices for sidecars logic, into
it's own function.
2020-11-10 15:58:26 -08:00
Aleksandr Melnikov
544991117c Changing the label that maps between the service and pod.
- For multiple sidecars, this needs to be unique as well.
2020-11-10 15:58:26 -08:00
Aleksandr Melnikov
8057098e29 Fixing envoyfilter by adding "--" to the sub-domain url that gets
generate.d
2020-11-10 15:58:26 -08:00
Aleksandr Melnikov
a4c40dff8b Removing jwt-go library since it's no longer used. 2020-11-10 15:58:26 -08:00
Aleksandr Melnikov
ccb991207b Adding code to clean-up the service and virtualservice after the
workflow is finished.
- Adding clean-up code to run alongside any onExit tasks.
2020-11-10 15:58:26 -08:00
Aleksandr Melnikov
70007d6d23 Codacy: Fixing variable names. 2020-11-10 15:58:26 -08:00
Aleksandr Melnikov
af47ffbd2f Updating logic that checks if a sidecar needs routing and service.
- Check if tty is set to true on the sidecar.
- Updated formatting.
2020-11-10 15:58:26 -08:00
Aleksandr Melnikov
4f28882d05 Adding go.sum changes. 2020-11-10 15:58:26 -08:00
Aleksandr Melnikov
d8101bff8e Checking for istio injection by checking if the sidecar has "tty"
set to true.
2020-11-10 15:58:26 -08:00
Aleksandr Melnikov
0f226eb0b7 Adding google uuid library to go.mod. 2020-11-10 15:58:26 -08:00
Aleksandr Melnikov
e1c3dc3979 Enabling Istio for workflows with sidecars.
- WIP
2020-11-10 15:58:26 -08:00
Aleksandr Melnikov
7698b705d8 Removing unused code. 2020-11-10 15:58:26 -08:00
Aleksandr Melnikov
7b7142da49 Generating names using uuid.
- workflow.name is assigned at run-time, and may not be DNS compliant
for a service name. So that variable is not used.
2020-11-10 15:58:26 -08:00
Aleksandr Melnikov
d903baea00 Adding uuid generating library 2020-11-10 15:58:26 -08:00
Aleksandr Melnikov
530e24180d Simplifying prefix to "/" 2020-11-10 15:58:26 -08:00
Aleksandr Melnikov
f5fb44c59b Port and TargetPort are assumed to be the same.
If Tensorboard has 6006 set, we also set it to 6006.
2020-11-10 15:58:26 -08:00
Aleksandr Melnikov
6d42a44957 Removing condition tests. 2020-11-10 15:58:26 -08:00
Aleksandr Melnikov
2fef7d78c1 Fixing typo. 2020-11-10 15:58:26 -08:00
Aleksandr Melnikov
b46e7fd3b9 Excluding istio side-car from resource creation.
- Otherwise, the step hangs and never finishes, so long as istio
container runs.
2020-11-10 15:58:26 -08:00
Aleksandr Melnikov
e5f2f3e937 Adding k8s-service-resource and k8s-routes-resource as tasks
and dependencies to the entry point template.
- Issue: Argo throws this error

Message:             invalid spec: templates.main.tasks.train-model.dependencies[1] dependency 'k8s-service-resource' not defined
2020-11-10 15:58:26 -08:00
Aleksandr Melnikov
af361d5045 Renaming the side-car check per feedback. 2020-11-10 15:58:26 -08:00
Aleksandr Melnikov
3e1a4dd313 Refactoring code since it's empty initialization. 2020-11-10 15:58:26 -08:00
Aleksandr Melnikov
d2dfd4cc34 Updating the host placeholder. 2020-11-10 15:58:26 -08:00
Aleksandr Melnikov
2d45b0a015 Using the right yaml library to marshal. 2020-11-10 15:58:26 -08:00
Aleksandr Melnikov
cb7bb793e7 Adding code to support sidecars and accessing them.
- Specifically, if a sidecar is labeled with "sys-tensorboard-like",
code attempts to create services and virtual services (routes).
- Code will create argo templates that are resource type, where the
manifests are the generated resources.
The templates are then added right before the template with the
sidecar that requires these services and routes.
2020-11-10 15:58:26 -08:00
Andrey Melnikov
90f01f8036 Merge pull request #711 from rushtehrani/fix/send-status
fix: Only inject one sys-send-status task
2020-11-09 11:12:27 -08:00
Andrey Melnikov
850b184788 Merge pull request #715 from Vafilor/feat/add.auth.back
fix: add backwards compatibility for auth token requests
2020-11-09 10:34:31 -08:00
rushtehrani
875097fed7 only inject one sys-send-status task 2020-11-06 17:35:55 -08:00
Andrey Melnikov
cd28474249 Merge pull request #710 from Vafilor/feat/upgrade.argo
feat: upgrade argo
2020-11-06 15:17:17 -08:00
Andrey Melnikov
855fd43301 Merge branch 'feat/upgrade.argo' of github.com:Vafilor/core into feat/upgrade.argo 2020-11-06 15:15:35 -08:00
Andrey Melnikov
e037d89a0a fix: issue where new migration ran before all others, causing issues 2020-11-06 15:14:47 -08:00
Rush Tehrani
623964dc6b Update description in README.md 2020-11-06 15:14:47 -08:00
Andrey Melnikov
f6aff415d5 fix: migrations that had numbers where new argo expects strings 2020-11-06 15:14:47 -08:00
Andrey Melnikov
316016765d chore: removed todo comments that have been resolved 2020-11-06 15:14:47 -08:00
Andrey Melnikov
8bce73417a upgraded argo to v2.11.6 (wip) 2020-11-06 15:14:47 -08:00
Andrey Melnikov
9c400e82e6 Merge pull request #709 from Vafilor/fix/migration
fix: issue where new migration ran before all others, causing issues
2020-11-06 15:14:11 -08:00
Andrey Melnikov
f9bf162b94 fix: issue where new migration ran before all others, causing issues 2020-11-06 15:10:34 -08:00
Rush Tehrani
91b9fb37c2 Update description in README.md 2020-11-06 12:45:15 -08:00
Andrey Melnikov
594390d742 Merge pull request #704 from Vafilor/feat/upgrade.argo
feat: upgrade argo to v2.11.6
2020-11-06 12:41:57 -08:00
Andrey Melnikov
e3cbbc7d00 Merge branch 'feat/upgrade.argo' of github.com:Vafilor/core into feat/upgrade.argo 2020-11-06 12:13:58 -08:00
Andrey Melnikov
6d511f7c8e upgraded argo to v2.11.6 (wip) 2020-11-06 12:12:34 -08:00
Andrey Melnikov
717a4bc2e8 fix: temporary fix while cvat is not updated to use new auth 2020-11-06 12:11:40 -08:00
Andrey Melnikov
74bc140107 Merge pull request #705 from Vafilor/fix/rename.auth
fix: rename LogIn request to GetAccessToken
2020-11-03 13:45:06 -08:00
Andrey Melnikov
a405e8bf46 feat: update api to use accessTokenAuth 2020-11-03 13:37:30 -08:00
Andrey Melnikov
93bdc7cd70 fix: rename LogIn to GetAccessToken 2020-11-03 10:29:02 -08:00
Andrey Melnikov
3b3784508c upgraded argo to v2.11.6 (wip) 2020-11-02 15:17:17 -08:00
Rush Tehrani
ff0526db9a Merge pull request #703 from aleksandrmelnikov/fix/fixing.namespace.typo
fix: Fixing typo in CVAT migration yaml.
2020-11-02 14:41:45 -08:00
Andrey Melnikov
8b35c1709c Merge pull request #702 from Vafilor/fix/workspaces.terminated.labels
fix: issue where terminated workspace labels were being selected
2020-11-02 11:26:35 -08:00
Aleksandr Melnikov
98c086ad1e Fixing typo. 2020-11-02 11:20:18 -08:00
Rush Tehrani
e07aebcc3c Merge pull request #700 from aleksandrmelnikov/feat/core.681-update.mnt.vol.locations.in.cvat
feat: Adding migration to reduce the number of volumes in CVAT workspace template
2020-11-02 11:13:10 -08:00
Rush Tehrani
6c1f522921 Merge pull request #699 from rushtehrani/fix/tensorboard
fix: Set TENSORBOARD_PROXY_URL so TensorBoard can easily be used in JupyterLab
2020-11-02 11:12:31 -08:00
Andrey Melnikov
31840afab1 fix: issue where terminated workspace labels were being selected. 2020-11-02 11:09:55 -08:00
Aleksandr Melnikov
cf607513aa Adding down migration for new migration.
- Refactoring yaml files per feedback.
2020-11-02 10:53:45 -08:00
Aleksandr Melnikov
0e35ed2d52 Adding migration for cvat template.
- Main changes are a reduction of volumes needed.
2020-11-02 10:51:54 -08:00
Andrey Melnikov
5e82311efb Merge pull request #698 from Vafilor/fix/concurrent.map
fix: concurrency issues with token
2020-11-02 10:36:19 -08:00
rushtehrani
0bb5ad7f2c fix migrations 2020-11-01 22:39:03 -08:00
rushtehrani
a598b3f620 set TENSORBOARD_PROXY_URL so it can be used in JupyterLab 2020-10-31 17:00:38 -07:00
Rush Tehrani
a184c294da Merge pull request #697 from Vafilor/fix/revert.system.flag
fix: removed is_system flag
2020-10-31 14:41:46 -07:00
Andrey Melnikov
b129a1da7d fix: moved token to be inside client instead of sysconfig as it is not a system config value, but it is applicable to the current client.
This fixes some concurrency issues since you could have multiple requests handled at the same time that try to read and modify the system values.
2020-10-30 23:48:51 -07:00
Andrey Melnikov
7854aa15ca fix: removed is_system flag 2020-10-30 23:45:39 -07:00
Andrey Melnikov
7814502404 Merge pull request #693 from Vafilor/feat/onepanelio.core.688.login
feat: support for login endpoint
2020-10-30 12:04:13 -07:00
Andrey Melnikov
5d6fae152d feat: added system flag to workflow template creation 2020-10-29 12:30:55 -07:00
Andrey Melnikov
e41d5c38af feat: added log in endpoint which is essentially an alias for auth token, but is more descriptive 2020-10-29 12:14:53 -07:00
Rush Tehrani
0cdb8ffac8 Merge pull request #689 from Vafilor/fix/upgrade.migrations
feat: update latest migrations to use file format
2020-10-28 15:16:27 -07:00
Andrey Melnikov
a274daa811 update: updated migrations to use new file format and renamed them so they run after the latest migration updates. 2020-10-28 15:08:31 -07:00
Rush Tehrani
79d4c44817 Merge pull request #646 from aleksandrmelnikov/feat/core.623-persist.packages.between.ws.switch.pause
feat: Add lifecycle hooks to VSCode and Jupyterlab Workspaces to provide persistence of conda, pip, and extensions.
2020-10-28 12:55:20 -07:00
Aleksandr Melnikov
6591d19dae Adding --minimize=False to build command.
- This is a trade-off to reduce workspace start-up time, but increase
browser load times for Jupyterlab.
2020-10-28 12:51:10 -07:00
Aleksandr Melnikov
4ea8ca8635 Tweaking when jupyter lab build runs.
- We want it to run only if the installation succeeds.
2020-10-27 11:34:48 -07:00
Aleksandr Melnikov
cbc07693bc We need to actually build the extensions after installing them.
- This ensures all the extensions installed with "--no-build" will
be compiled in one go, instead of individually.
2020-10-27 11:23:03 -07:00
Rush Tehrani
c77711b887 Merge pull request #684 from Vafilor/feat/onepanelio.core.492.filter.labels
feat: add support to list labels for resources
2020-10-27 10:31:10 -07:00
Andrey Melnikov
bcbccbe68d fix: issue where null json labels were selected, causing a crash. 2020-10-27 10:15:16 -07:00
Aleksandr Melnikov
a4b9e9d444 Renaming container as specified. 2020-10-26 15:45:25 -07:00
Aleksandr Melnikov
7c0b5a06f8 Removing whitespace. 2020-10-26 15:42:34 -07:00
Andrey Melnikov
a756684ae5 feat: API support for selecting labels 2020-10-26 15:38:03 -07:00
Aleksandr Melnikov
d4f676210e Removing unused yaml. 2020-10-26 15:35:30 -07:00
Aleksandr Melnikov
83f6ef3e27 Removing migrationsRan code.
- This is SQL and will never evaluate to true. These templates are
go migrations, not sql based.
See https://github.com/onepanelio/core/pull/646/#discussion_r504214052
for context.
2020-10-26 13:44:13 -07:00
Aleksandr Melnikov
ee29c12eb2 Merge branch 'master' into feat/core.623-persist.packages.between.ws.switch.pause 2020-10-26 13:33:48 -07:00
Aleksandr Melnikov
6758e260c9 Adding "--no-build" to code that re-installs jupyterlab extensions.
- Otherwise, the extension installation process also kicks off a
production minimization of code, which takes minutes.
- This leads to Jupyterlab Workspace taking ~10 minutes to resume, even
if no new extensions had been installed.
2020-10-26 13:29:37 -07:00
Andrey Melnikov
5de512136a fix: added migration to fix existing null labels 2020-10-23 12:24:34 -07:00
Andrey Melnikov
94c5850eda fix: issue where nil values for JSON Labels sometimes returned "null" and not "{}" 2020-10-23 12:11:18 -07:00
Andrey Melnikov
50145cccdf feat: added more logging for getBearerToken errors 2020-10-23 11:40:29 -07:00
Rush Tehrani
83acc5a5ce Merge pull request #683 from rushtehrani/docs/readme-1
docs: Update support badge
2020-10-23 10:59:07 -07:00
Rush Tehrani
19378c62f3 Update README.md 2020-10-23 10:51:51 -07:00
Rush Tehrani
0d4f5fbb37 Merge pull request #678 from rushtehrani/docs/readme
docs: Update README
2020-10-20 14:11:01 -07:00
rushtehrani
43a4d60b5b add onepanel.gif 2020-10-20 13:43:57 -07:00
rushtehrani
6c85a81709 docs: Update README 2020-10-20 13:40:34 -07:00
Aleksandr Melnikov
e9d8a6ebe0 Merge pull request #677 from Vafilor/fix/artifact.repository.generic
fix: non-generic filesyncer for latest cvat migration
2020-10-20 11:17:54 -07:00
Andrey Melnikov
c8c0b6ffd4 fix: non-generic filesyncer for latest cvat migration 2020-10-20 11:03:03 -07:00
Andrey Melnikov
38780c2e08 Merge pull request #675 from Vafilor/feat/cvat.upgrade
feat: upgrade cvat to v14
2020-10-19 10:52:51 -07:00
Andrey Melnikov
e1f8ee846c feat: update-cvat 2020-10-19 10:48:10 -07:00
Andrey Melnikov
2cc4cbd6f8 cleanup: simplified updating workspace template into a separate function 2020-10-16 17:33:35 -07:00
Andrey Melnikov
276aaf6e7a feat: placeholder for updating cvat template. 2020-10-16 17:20:27 -07:00
Rush Tehrani
6e1a08fdc3 Merge pull request #673 from Vafilor/feat/gcs.compatible.files
fix: issue where files were not being listed when using gcs
2020-10-16 16:47:18 -07:00
Andrey Melnikov
7129fdf55f fix: issue where s3 with gcs wasn't working because of incompatible listing of files. 2020-10-16 16:41:49 -07:00
Rush Tehrani
00e3247fcd Merge pull request #672 from rushtehrani/fix/sys-uid-env-var
fix: Use sys-uid instead of sys-name for ONEPANEL_RESOURCE_UID
2020-10-16 12:58:23 -07:00
rushtehrani
c26019b4d5 use sys-uid instead of sys-name for ONEPANEL_RESOURCE_UID 2020-10-16 12:55:12 -07:00
Andrey Melnikov
acadc0c0a7 Merge pull request #670 from Vafilor/feat/tag.channel
fix: change notify slack channel to be org instead of dev
2020-10-16 09:57:46 -07:00
Rush Tehrani
1b97099d11 Merge pull request #669 from Vafilor/fix/db.connections
fix: use system-wide db connection for auth
2020-10-16 09:55:41 -07:00
Andrey Melnikov
c5365975ac fix: change notify slack channel to be org instead of dev 2020-10-16 09:53:45 -07:00
Andrey Melnikov
b7d37586a8 fix: add method to get client with a provided db 2020-10-16 09:45:51 -07:00
Andrey Melnikov
2bd3c3dde0 fix: use system-wide connection when checking authentication 2020-10-16 09:45:29 -07:00
Rush Tehrani
957313423c Merge pull request #668 from Vafilor/fix/db.connections
fix: close db connection when not in use.
2020-10-16 09:21:32 -07:00
Andrey Melnikov
c883f69fc9 fix: close db connection when not in use. 2020-10-15 21:48:25 -07:00
Andrey Melnikov
6c5b6c877e Merge pull request #660 from Vafilor/feat/revert.jwt
feat: revert jwt changes as it creates issues with workflow authentication logic
2020-10-14 12:15:27 -07:00
Andrey Melnikov
67e684a715 revert: remove util/tokens/jwt as it is no longer used. 2020-10-14 11:54:23 -07:00
Andrey Melnikov
20c4950b69 feat: revert jwt token from auth 2020-10-14 11:53:05 -07:00
Andrey Melnikov
5e5c3cca67 Merge pull request #657 from rushtehrani/fix/workspace-resource
fix: Update label function to return group and resource
2020-10-13 16:15:28 -07:00
Andrey Melnikov
575a33c272 Merge pull request #658 from Vafilor/feat/onepanel.io.653-additional-fixes
fix: issue with concurrent map access
2020-10-13 16:09:22 -07:00
rushtehrani
8e9b95aa12 update label function to return group and resource 2020-10-13 16:06:08 -07:00
Andrey Melnikov
38f1aafaec fix: issue with concurrent map access 2020-10-13 16:02:40 -07:00
rushtehrani
30ebda4918 use workspaces instead of statefulset for resource 2020-10-13 15:47:20 -07:00
Andrey Melnikov
ce972f2988 Merge pull request #656 from Vafilor/feat/onepanel.io.653-additional-fixes
fix: bad token issue
2020-10-13 15:27:45 -07:00
Andrey Melnikov
ede4c67c8f fix: bad token issue 2020-10-13 15:17:56 -07:00
Aleksandr Melnikov
cc05c4994c Fixing whitespace, so we have valid YAML. 2020-10-13 13:13:23 -07:00
Rush Tehrani
68ddec78c8 Merge pull request #655 from Vafilor/feat/onepanelio.core.653-auth.changes
feat: update incoming token to be a JWT token that takes in username
2020-10-13 12:45:14 -07:00
Andrey Melnikov
c42997a643 fix: error to be API friendly 2020-10-13 12:21:32 -07:00
Andrey Melnikov
5bd2feaa86 update: added username to returned auth token 2020-10-12 17:01:26 -07:00
Andrey Melnikov
de4302d226 chore: formatting updates for error strings 2020-10-12 16:17:16 -07:00
Andrey Melnikov
7150f24631 feat: update incoming token to be a JWT token that takes in username 2020-10-12 16:07:12 -07:00
Rush Tehrani
0e1e48dfc8 Merge pull request #647 from rushtehrani/master
fix: Use correct group for workspaces resource
2020-10-08 20:03:51 -07:00
rushtehrani
dd0f1f7705 use correct group for workspaces resource 2020-10-08 19:52:48 -07:00
Aleksandr Melnikov
ac589bfb62 Added migration for VSCode workspace template
- Added lifecycle hooks to template
- This enables persistence of conda, pip, and vscode extensions.
2020-10-08 15:59:02 -07:00
Aleksandr Melnikov
1d35adbeaa Added migration for Jupyterlab workspace template
- Added lifecycle hooks to template
- This enables persistence of conda, pip, and jupyter labextensions.
2020-10-08 15:49:47 -07:00
Aleksandr Melnikov
2b52f46ba6 Adding design document related to ticket and general implementation. 2020-10-08 15:13:23 -07:00
Aleksandr Melnikov
03f8f47664 Merge pull request #642 from Vafilor/fix/jupyterlab.migrations
feat: added convenience method to update workspace template manifest
2020-10-06 10:47:18 -07:00
Andrey Melnikov
c85496d216 update: added method specifically to update the manifest of a workspace template and modified recent migration to use it.
This fixes an issue where the jupyterlab migration wiped out the old description.
2020-10-06 10:28:03 -07:00
Rush Tehrani
5f6415548d Merge pull request #640 from aleksandrmelnikov/fix/core.637-dedicated.nodes.via.hostport
fix: Fixing issues with using hostPort. Removed prior logic that still relied on running nodes.
2020-10-05 15:40:26 -07:00
Aleksandr Melnikov
c641c17a8c Updating code that generates an extra container for a workspace.
- Renamed function to make it clearer what it's doing with the extra container
- Added documentation for the function
- Removed listing nodes code, since we only care if the workspace has
a nodeSelector set.
2020-10-05 14:17:00 -07:00
Aleksandr Melnikov
83a2543b13 Updating function name to reflect what it's doing. 2020-10-05 14:04:32 -07:00
Aleksandr Melnikov
e8dae0f2e9 Since we're no longer relying on running nodes, we don't need logic
relating to them.
- We can just check if a nodeSelector is set on the template.
2020-10-05 13:59:14 -07:00
Rush Tehrani
b85bf4d688 Merge pull request #638 from aleksandrmelnikov/fix/core.637-dedicated.nodes.via.hostport
fix: Replace resource requests and limits with hostPort, as a means of grabbing dedicated nodes.
2020-10-05 12:17:45 -07:00
Aleksandr Melnikov
7fe0ab2654 Tweaking names so it's more clear why they are there. 2020-10-05 11:51:04 -07:00
Aleksandr Melnikov
dfa6eb2fe6 Removing function that's no longer used. 2020-10-05 11:46:19 -07:00
Aleksandr Melnikov
cc2c51ace5 Removing resource requests and limits.
- Using hostPort on the node as a way to require dedicated nodes
for workspaces and workflows.
2020-10-05 11:46:01 -07:00
88 changed files with 6962 additions and 1333 deletions

35
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,35 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**`opctl` version**
```bash
$ opctl version
CLI version: v0.16.0-rc.0
Manifest version: v0.16.0-rc.0
API version: v0.16.0-rc.0
Web UI version: v0.16.0-rc.0
```
**`opctl init` command**
You can find this at the top of your `params.yaml` file. [e.g. `opctl init --provider eks --artifact-repository-provider s3 --gpu-device-plugins nvidia`]
**Kubernetes information**
- Cloud provider: [e.g. AKS, EKS, GKE, Microk8s]
- Kubernetes version: [e.g. 1.17.13]
**Machine information**
- OS: [e.g. Ubuntu 18.04, Windows 10 19042.631, macOS 10.14.6]
- Browser: [e.g. Chrome, Firefox, Safari]
**Screenshots**
If applicable, add screenshots to help explain your problem.

View File

@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is.
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- uses: olegtarasov/get-tag@v2
- uses: little-core-labs/get-git-tag@v3.0.1
id: tagName
- name: Publish to Registry
uses: elgohr/Publish-Docker-Github-Action@master
@@ -17,13 +17,13 @@ jobs:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_TOKEN }}
tags: "${{ env.GIT_TAG_NAME }}"
- name: Set Slack Message
run: echo "::set-env name=SLACK_MESSAGE::Tag $GIT_TAG_NAME. Docker Tag onepanel/core:$GIT_TAG_NAME"
- name: Notify Slack Channels
uses: rtCamp/action-slack-notify@v2.0.0
uses: rtCamp/action-slack-notify@v2.1.1
env:
SLACK_CHANNEL: dev
SLACK_CHANNEL: org
SLACK_ICON: https://avatars1.githubusercontent.com/u/30390575?s=48&v=4
SLACK_TITLE: New Core Version
SLACK_USERNAME: opBot
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
MSG_MINIMAL: true
SLACK_MESSAGE: "${{ env.GIT_TAG_NAME }}\nDocker Tag: onepanel/core:${{ env.GIT_TAG_NAME }}"

View File

@@ -1,4 +1,4 @@
FROM golang:1.13.10 AS builder
FROM golang:1.15.5 AS builder
WORKDIR /go/src
COPY . .
@@ -8,7 +8,7 @@ RUN go install -v ./...
RUN go get -u github.com/pressly/goose/cmd/goose
RUN go build -o /go/bin/goose ./cmd/goose/goose.go
FROM golang:1.13.10
FROM golang:1.15.5
COPY --from=builder /go/bin/core .
COPY --from=builder /go/src/db ./db
COPY --from=builder /go/bin/goose .

View File

@@ -33,6 +33,11 @@ docker-build:
docker-push:
docker push onepanel/core:$(COMMIT_HASH)
docker-custom:
docker build -t onepanel-core .
docker tag onepanel-core:latest onepanel/core:$(TAG)
docker push onepanel/core:$(TAG)
docker: docker-build docker-push
run-tests:

View File

@@ -6,60 +6,39 @@
[![sdk](https://img.shields.io/pypi/v/onepanel-sdk?color=01579b&label=sdk)](https://pypi.org/project/onepanel-sdk/)
[![docs](https://img.shields.io/github/v/release/onepanelio/core?color=01579b&label=docs)](https://docs.onepanel.io)
[![issues](https://img.shields.io/github/issues-raw/onepanelio/core?color=01579b&label=issues)](https://github.com/onepanelio/core/issues)
[![chat](https://img.shields.io/badge/support-slack-01579b)](https://onepanel-ce.slack.com/join/shared_invite/zt-eyjnwec0-nLaHhjif9Y~gA05KuX6AUg#/)
[![chat](https://img.shields.io/badge/support-slack-01579b)](https://join.slack.com/t/onepanel-ce/shared_invite/zt-eyjnwec0-nLaHhjif9Y~gA05KuX6AUg)
[![license](https://img.shields.io/github/license/onepanelio/core?color=01579b)](https://opensource.org/licenses/Apache-2.0)
Production scale, Kubernetes-native vision AI platform, with fully integrated components for model building, automated labeling, data processing and model training pipelines.
Production scale vision AI platform with fully integrated components for model building, automated labeling, data processing and model training pipelines.
<img width="100%" src="img/onepanel.gif">
## Why Onepanel?
- End-to-end workflow and infrastructure automation for production scale vision AI
- Automatic resource management and on-demand scaling of CPU and GPU nodes
- Easily scale your data processing and training pipelines to multiple nodes
- Collaborate on all your deep learning tools and workflows through a unified web interface and SDKs
- End-to-end automation for production scale vision AI pipelines
- Best of breed, open source deep learning tools seamlessly integrated in one unified platform
- Infrastructure automation so you can easily scale your data processing and training pipelines to multiple nodes
- Customizable, reproducible and version controlled tooling and pipeline templates
- Scalability, flexibility and resiliency of Kubernetes without the deployment and configuration complexities
## Features
<table>
<tr>
<td width="50%" align="center">
<h3>Image and video annotation with automatic annotation</h3>
<img width="100%" src="img/auto-annotation.gif">
<p>
Annotate images and video with automatic annotation of bounding boxes and polygon masks, integrated with training pipelines to iteratively improve models for pre-annotation and inference
</p>
</td>
<td width="50%" align="center">
<h3>JupyterLab with TensorFlow, PyTorch and GPU support</h3>
<img width="100%" src="img/jupyterlab.gif">
<p>
JupyterLab configured with extensions for debugging, Git/GitHub, notebook diffing and TensorBoard and support for Conda, OpenCV, Tensorflow and PyTorch with GPU and <a href="https://github.com/onepanelio/templates/tree/master/workspaces/jupyterlab">much more</a>
</p>
</td>
</tr>
<tr>
<td width="50%" align="center">
<h3>Auto scaling, distributed and parallel data processing and training pipelines</h3>
<img width="100%" src="img/pipelines.gif">
<p>
Build fully reproducible, distributed and parallel data processing and training pipelines with real-time logs and output snapshots
</p>
</td>
<td width="50%" align="center">
<h3>Version controlled pipelines and environments as code</h3>
<img width="100%" src="img/tools.gif">
<p>
Bring your own IDEs, annotation tools and pipelines with a version controlled YAML and Docker based template engine
</p>
</td>
</tr>
</table>
Onepanel can be found on [LF AI Landscape](http://landscape.lfai.foundation/selected=onepanel)
## Features
- Annotate images and video with automatic annotation of bounding boxes and polygon masks, fully integrated with data processing and training pipelines.
- JupyterLab configured with extensions for TensorBoard, Git/GitHub, debugging, notebook diffing and support for Conda, OpenCV, Tensorflow and PyTorch with GPU.
- Build fully reproducible, distributed and parallel data processing and training pipelines with real-time logs and output snapshots.
- Bring your own IDEs, annotation tools and pipelines with a version controlled YAML and Docker based template engine.
- Track and visualize model metrics and experiments with TensorBoard or bring your own experiment tracking tools.
- Access and share tools like AirSim, Carla, Gazebo or OpenAI Gym through your browser with VNC enabled workspaces.
- Extend Onepanel with powerful REST APIs and SDKs to further automate your pipelines and environments.
- Workflows, environments and infrastructure are all defined as code and version controlled, making them reproducible and portable.
- Powered by Kubernetes so you can deploy anywhere Kubernetes can run.
- Extend Onepanel with powerful REST APIs and SDKs to further automate your workflows.
## Online demo
We have created an [online demo environment](https://onepanel.typeform.com/to/kQfDX5Vf?product=github) so that you can quickly try Onepanel.
Note that this is a shared demo environment with the following restrictions:
- Data is reset every few hours
- One type of node pool (machine type) with a limit of 5 concurrent nodes
- Certain actions may be restricted
## Quick start
See [quick start guide](https://docs.onepanel.ai/docs/getting-started/quickstart) to get started with the platform of your choice.
@@ -74,17 +53,17 @@ See [documentation](https://docs.onepanel.ai) to get started or for more detaile
To submit a feature request, report a bug or documentation issue, please open a GitHub [pull request](https://github.com/onepanelio/core/pulls) or [issue](https://github.com/onepanelio/core/issues).
For help, questions, release announcements and contribution discussions, join us on [Slack](https://join.slack.com/t/onepanel-ce/shared_invite/zt-eyjnwec0-nLaHhjif9Y~gA05KuX6AUg).
For help, questions, release announcements and contribution discussions, join us on [Slack](https://join.slack.com/t/onepanel-ce/shared_invite/zt-eyjnwec0-nLaHhjif9Y~gA05KuX6AUg) or [GitHub discussions](https://github.com/onepanelio/core/discussions).
## Contributing
Onepanel is modular and consists of the following repositories:
[Core API](https://github.com/onepanelio/core/) (this repository) - Code base for backend (Go)\
[Core UI](https://github.com/onepanelio/core-ui/) - Code base for UI (Angular + TypeScript)\
[CLI](https://github.com/onepanelio/cli/) - Code base for Go CLI for installation and management (Go)\
[Manifests](https://github.com/onepanelio/core-ui/) - Kustomize manifests used by CLI for installation and management (YAML)\
[Python SDK](https://github.com/onepanelio/python-sdk/) - Python SDK code and documentation\
[Backend](https://github.com/onepanelio/core/) (this repository) - Code base for backend (Go)\
[Frontend](https://github.com/onepanelio/core-ui/) - Code base for frontend (Angular + TypeScript)\
[CLI](https://github.com/onepanelio/cli/) - Code base for installation and management CLI (Go)\
[Manifests](https://github.com/onepanelio/core-ui/) - Kustomize manifests used by installation and management CLI (YAML)\
[Python SDK](https://github.com/onepanelio/python-sdk/) - Python SDK code and documentation (Python)\
[Templates](https://github.com/onepanelio/templates) - Various Workspace, Workflow, Task and Sidecar Templates\
[Documentation](https://github.com/onepanelio/core-docs/) - The repository for documentation site\
[API Documentation](https://github.com/onepanelio/core-api-docs/) - API documentation if you choose to use the API directly
@@ -97,8 +76,8 @@ Onepanel seamlessly integrates the following excellent open source projects. We
[Argo](https://github.com/argoproj/argo)\
[CVAT](https://github.com/opencv/cvat)\
[JupyterLab](https://github.com/jupyterlab/jupyterlab)
[JupyterLab](https://github.com/jupyterlab/jupyterlab)\
[NNI](https://github.com/microsoft/nni)
## License
Onepanel is licensed under [Apache 2.0](https://github.com/onepanelio/core/blob/master/LICENSE).

View File

@@ -3,7 +3,7 @@
"info": {
"title": "Onepanel",
"description": "Onepanel API",
"version": "0.13.0",
"version": "0.16.0",
"contact": {
"name": "Onepanel project",
"url": "https://github.com/onepanelio/core"
@@ -54,6 +54,39 @@
]
}
},
"/apis/v1beta1/auth/get_access_token": {
"post": {
"operationId": "GetAccessToken",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/GetAccessTokenResponse"
}
},
"default": {
"description": "An unexpected error response",
"schema": {
"$ref": "#/definitions/grpc.gateway.runtime.Error"
}
}
},
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/GetAccessTokenRequest"
}
}
],
"tags": [
"AuthService"
],
"security": []
}
},
"/apis/v1beta1/auth/token": {
"post": {
"operationId": "IsValidToken",
@@ -77,7 +110,7 @@
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/TokenWrapper"
"$ref": "#/definitions/IsValidTokenRequest"
}
}
],
@@ -108,6 +141,54 @@
]
}
},
"/apis/v1beta1/labels/{namespace}/{resource}/labels": {
"get": {
"operationId": "GetAvailableLabels",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/GetLabelsResponse"
}
},
"default": {
"description": "An unexpected error response",
"schema": {
"$ref": "#/definitions/grpc.gateway.runtime.Error"
}
}
},
"parameters": [
{
"name": "namespace",
"in": "path",
"required": true,
"type": "string"
},
{
"name": "resource",
"in": "path",
"required": true,
"type": "string"
},
{
"name": "keyLike",
"in": "query",
"required": false,
"type": "string"
},
{
"name": "skipKeys",
"in": "query",
"required": false,
"type": "string"
}
],
"tags": [
"LabelService"
]
}
},
"/apis/v1beta1/namespaces": {
"get": {
"operationId": "ListNamespaces",
@@ -1159,6 +1240,92 @@
]
}
},
"/apis/v1beta1/{namespace}/workflow_executions/{uid}/metric": {
"post": {
"operationId": "AddWorkflowExecutionMetrics",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/WorkflowExecutionsMetricsResponse"
}
},
"default": {
"description": "An unexpected error response",
"schema": {
"$ref": "#/definitions/grpc.gateway.runtime.Error"
}
}
},
"parameters": [
{
"name": "namespace",
"in": "path",
"required": true,
"type": "string"
},
{
"name": "uid",
"in": "path",
"required": true,
"type": "string"
},
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/AddWorkflowExecutionsMetricsRequest"
}
}
],
"tags": [
"WorkflowService"
]
},
"put": {
"operationId": "UpdateWorkflowExecutionMetrics",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/WorkflowExecutionsMetricsResponse"
}
},
"default": {
"description": "An unexpected error response",
"schema": {
"$ref": "#/definitions/grpc.gateway.runtime.Error"
}
}
},
"parameters": [
{
"name": "namespace",
"in": "path",
"required": true,
"type": "string"
},
{
"name": "uid",
"in": "path",
"required": true,
"type": "string"
},
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/UpdateWorkflowExecutionsMetricsRequest"
}
}
],
"tags": [
"WorkflowService"
]
}
},
"/apis/v1beta1/{namespace}/workflow_executions/{uid}/pods/{podName}/containers/{containerName}/logs": {
"get": {
"operationId": "GetWorkflowExecutionLogs",
@@ -2737,6 +2904,27 @@
}
}
},
"AddWorkflowExecutionsMetricsRequest": {
"type": "object",
"properties": {
"namespace": {
"type": "string"
},
"uid": {
"type": "string"
},
"override": {
"type": "boolean",
"format": "boolean"
},
"metrics": {
"type": "array",
"items": {
"$ref": "#/definitions/Metric"
}
}
}
},
"ArchiveWorkflowTemplateResponse": {
"type": "object",
"properties": {
@@ -2883,6 +3071,31 @@
}
}
},
"GetAccessTokenRequest": {
"type": "object",
"properties": {
"username": {
"type": "string"
},
"token": {
"type": "string"
}
}
},
"GetAccessTokenResponse": {
"type": "object",
"properties": {
"domain": {
"type": "string"
},
"accessToken": {
"type": "string"
},
"username": {
"type": "string"
}
}
},
"GetConfigResponse": {
"type": "object",
"properties": {
@@ -2967,11 +3180,28 @@
}
}
},
"IsValidTokenRequest": {
"type": "object",
"properties": {
"username": {
"type": "string"
},
"token": {
"type": "string"
}
}
},
"IsValidTokenResponse": {
"type": "object",
"properties": {
"domain": {
"type": "string"
},
"token": {
"type": "string"
},
"username": {
"type": "string"
}
}
},
@@ -3131,6 +3361,10 @@
"totalCount": {
"type": "integer",
"format": "int32"
},
"totalAvailableCount": {
"type": "integer",
"format": "int32"
}
}
},
@@ -3173,6 +3407,10 @@
"totalCount": {
"type": "integer",
"format": "int32"
},
"totalAvailableCount": {
"type": "integer",
"format": "int32"
}
}
},
@@ -3200,6 +3438,10 @@
"totalCount": {
"type": "integer",
"format": "int32"
},
"totalAvailableCount": {
"type": "integer",
"format": "int32"
}
}
},
@@ -3394,14 +3636,6 @@
}
}
},
"TokenWrapper": {
"type": "object",
"properties": {
"token": {
"type": "string"
}
}
},
"UpdateSecretKeyValueResponse": {
"type": "object",
"properties": {
@@ -3411,6 +3645,23 @@
}
}
},
"UpdateWorkflowExecutionsMetricsRequest": {
"type": "object",
"properties": {
"namespace": {
"type": "string"
},
"uid": {
"type": "string"
},
"metrics": {
"type": "array",
"items": {
"$ref": "#/definitions/Metric"
}
}
}
},
"UpdateWorkspaceBody": {
"type": "object",
"properties": {
@@ -3469,6 +3720,12 @@
},
"metadata": {
"$ref": "#/definitions/WorkflowExecutionMetadata"
},
"metrics": {
"type": "array",
"items": {
"$ref": "#/definitions/Metric"
}
}
}
},
@@ -3516,6 +3773,17 @@
}
}
},
"WorkflowExecutionsMetricsResponse": {
"type": "object",
"properties": {
"metrics": {
"type": "array",
"items": {
"$ref": "#/definitions/Metric"
}
}
}
},
"WorkflowTemplate": {
"type": "object",
"properties": {

View File

@@ -9,7 +9,7 @@ package api
import (
context "context"
proto "github.com/golang/protobuf/proto"
_ "github.com/golang/protobuf/ptypes/empty"
_ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options"
_ "google.golang.org/genproto/googleapis/api/annotations"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
@@ -31,6 +31,124 @@ const (
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4
type IsValidTokenRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"`
Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"`
}
func (x *IsValidTokenRequest) Reset() {
*x = IsValidTokenRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_auth_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *IsValidTokenRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*IsValidTokenRequest) ProtoMessage() {}
func (x *IsValidTokenRequest) ProtoReflect() protoreflect.Message {
mi := &file_auth_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use IsValidTokenRequest.ProtoReflect.Descriptor instead.
func (*IsValidTokenRequest) Descriptor() ([]byte, []int) {
return file_auth_proto_rawDescGZIP(), []int{0}
}
func (x *IsValidTokenRequest) GetUsername() string {
if x != nil {
return x.Username
}
return ""
}
func (x *IsValidTokenRequest) GetToken() string {
if x != nil {
return x.Token
}
return ""
}
type IsValidTokenResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Domain string `protobuf:"bytes,1,opt,name=domain,proto3" json:"domain,omitempty"`
Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"`
Username string `protobuf:"bytes,3,opt,name=username,proto3" json:"username,omitempty"`
}
func (x *IsValidTokenResponse) Reset() {
*x = IsValidTokenResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_auth_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *IsValidTokenResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*IsValidTokenResponse) ProtoMessage() {}
func (x *IsValidTokenResponse) ProtoReflect() protoreflect.Message {
mi := &file_auth_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use IsValidTokenResponse.ProtoReflect.Descriptor instead.
func (*IsValidTokenResponse) Descriptor() ([]byte, []int) {
return file_auth_proto_rawDescGZIP(), []int{1}
}
func (x *IsValidTokenResponse) GetDomain() string {
if x != nil {
return x.Domain
}
return ""
}
func (x *IsValidTokenResponse) GetToken() string {
if x != nil {
return x.Token
}
return ""
}
func (x *IsValidTokenResponse) GetUsername() string {
if x != nil {
return x.Username
}
return ""
}
type IsAuthorized struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -46,7 +164,7 @@ type IsAuthorized struct {
func (x *IsAuthorized) Reset() {
*x = IsAuthorized{}
if protoimpl.UnsafeEnabled {
mi := &file_auth_proto_msgTypes[0]
mi := &file_auth_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -59,7 +177,7 @@ func (x *IsAuthorized) String() string {
func (*IsAuthorized) ProtoMessage() {}
func (x *IsAuthorized) ProtoReflect() protoreflect.Message {
mi := &file_auth_proto_msgTypes[0]
mi := &file_auth_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -72,7 +190,7 @@ func (x *IsAuthorized) ProtoReflect() protoreflect.Message {
// Deprecated: Use IsAuthorized.ProtoReflect.Descriptor instead.
func (*IsAuthorized) Descriptor() ([]byte, []int) {
return file_auth_proto_rawDescGZIP(), []int{0}
return file_auth_proto_rawDescGZIP(), []int{2}
}
func (x *IsAuthorized) GetNamespace() string {
@@ -121,7 +239,7 @@ type IsAuthorizedRequest struct {
func (x *IsAuthorizedRequest) Reset() {
*x = IsAuthorizedRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_auth_proto_msgTypes[1]
mi := &file_auth_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -134,7 +252,7 @@ func (x *IsAuthorizedRequest) String() string {
func (*IsAuthorizedRequest) ProtoMessage() {}
func (x *IsAuthorizedRequest) ProtoReflect() protoreflect.Message {
mi := &file_auth_proto_msgTypes[1]
mi := &file_auth_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -147,7 +265,7 @@ func (x *IsAuthorizedRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use IsAuthorizedRequest.ProtoReflect.Descriptor instead.
func (*IsAuthorizedRequest) Descriptor() ([]byte, []int) {
return file_auth_proto_rawDescGZIP(), []int{1}
return file_auth_proto_rawDescGZIP(), []int{3}
}
func (x *IsAuthorizedRequest) GetIsAuthorized() *IsAuthorized {
@@ -168,7 +286,7 @@ type IsAuthorizedResponse struct {
func (x *IsAuthorizedResponse) Reset() {
*x = IsAuthorizedResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_auth_proto_msgTypes[2]
mi := &file_auth_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -181,7 +299,7 @@ func (x *IsAuthorizedResponse) String() string {
func (*IsAuthorizedResponse) ProtoMessage() {}
func (x *IsAuthorizedResponse) ProtoReflect() protoreflect.Message {
mi := &file_auth_proto_msgTypes[2]
mi := &file_auth_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -194,7 +312,7 @@ func (x *IsAuthorizedResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use IsAuthorizedResponse.ProtoReflect.Descriptor instead.
func (*IsAuthorizedResponse) Descriptor() ([]byte, []int) {
return file_auth_proto_rawDescGZIP(), []int{2}
return file_auth_proto_rawDescGZIP(), []int{4}
}
func (x *IsAuthorizedResponse) GetAuthorized() bool {
@@ -204,110 +322,17 @@ func (x *IsAuthorizedResponse) GetAuthorized() bool {
return false
}
type TokenWrapper struct {
type GetAccessTokenRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"`
Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"`
Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"`
}
func (x *TokenWrapper) Reset() {
*x = TokenWrapper{}
if protoimpl.UnsafeEnabled {
mi := &file_auth_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *TokenWrapper) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*TokenWrapper) ProtoMessage() {}
func (x *TokenWrapper) ProtoReflect() protoreflect.Message {
mi := &file_auth_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use TokenWrapper.ProtoReflect.Descriptor instead.
func (*TokenWrapper) Descriptor() ([]byte, []int) {
return file_auth_proto_rawDescGZIP(), []int{3}
}
func (x *TokenWrapper) GetToken() string {
if x != nil {
return x.Token
}
return ""
}
type IsValidTokenRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Token *TokenWrapper `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"`
}
func (x *IsValidTokenRequest) Reset() {
*x = IsValidTokenRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_auth_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *IsValidTokenRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*IsValidTokenRequest) ProtoMessage() {}
func (x *IsValidTokenRequest) ProtoReflect() protoreflect.Message {
mi := &file_auth_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use IsValidTokenRequest.ProtoReflect.Descriptor instead.
func (*IsValidTokenRequest) Descriptor() ([]byte, []int) {
return file_auth_proto_rawDescGZIP(), []int{4}
}
func (x *IsValidTokenRequest) GetToken() *TokenWrapper {
if x != nil {
return x.Token
}
return nil
}
type IsValidTokenResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Domain string `protobuf:"bytes,1,opt,name=domain,proto3" json:"domain,omitempty"`
}
func (x *IsValidTokenResponse) Reset() {
*x = IsValidTokenResponse{}
func (x *GetAccessTokenRequest) Reset() {
*x = GetAccessTokenRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_auth_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -315,13 +340,13 @@ func (x *IsValidTokenResponse) Reset() {
}
}
func (x *IsValidTokenResponse) String() string {
func (x *GetAccessTokenRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*IsValidTokenResponse) ProtoMessage() {}
func (*GetAccessTokenRequest) ProtoMessage() {}
func (x *IsValidTokenResponse) ProtoReflect() protoreflect.Message {
func (x *GetAccessTokenRequest) ProtoReflect() protoreflect.Message {
mi := &file_auth_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -333,61 +358,153 @@ func (x *IsValidTokenResponse) ProtoReflect() protoreflect.Message {
return mi.MessageOf(x)
}
// Deprecated: Use IsValidTokenResponse.ProtoReflect.Descriptor instead.
func (*IsValidTokenResponse) Descriptor() ([]byte, []int) {
// Deprecated: Use GetAccessTokenRequest.ProtoReflect.Descriptor instead.
func (*GetAccessTokenRequest) Descriptor() ([]byte, []int) {
return file_auth_proto_rawDescGZIP(), []int{5}
}
func (x *IsValidTokenResponse) GetDomain() string {
func (x *GetAccessTokenRequest) GetUsername() string {
if x != nil {
return x.Username
}
return ""
}
func (x *GetAccessTokenRequest) GetToken() string {
if x != nil {
return x.Token
}
return ""
}
type GetAccessTokenResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Domain string `protobuf:"bytes,1,opt,name=domain,proto3" json:"domain,omitempty"`
AccessToken string `protobuf:"bytes,2,opt,name=accessToken,proto3" json:"accessToken,omitempty"`
Username string `protobuf:"bytes,3,opt,name=username,proto3" json:"username,omitempty"`
}
func (x *GetAccessTokenResponse) Reset() {
*x = GetAccessTokenResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_auth_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *GetAccessTokenResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetAccessTokenResponse) ProtoMessage() {}
func (x *GetAccessTokenResponse) ProtoReflect() protoreflect.Message {
mi := &file_auth_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetAccessTokenResponse.ProtoReflect.Descriptor instead.
func (*GetAccessTokenResponse) Descriptor() ([]byte, []int) {
return file_auth_proto_rawDescGZIP(), []int{6}
}
func (x *GetAccessTokenResponse) GetDomain() string {
if x != nil {
return x.Domain
}
return ""
}
func (x *GetAccessTokenResponse) GetAccessToken() string {
if x != nil {
return x.AccessToken
}
return ""
}
func (x *GetAccessTokenResponse) GetUsername() string {
if x != nil {
return x.Username
}
return ""
}
var File_auth_proto protoreflect.FileDescriptor
var file_auth_proto_rawDesc = []byte{
0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x03, 0x61, 0x70,
0x69, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e,
0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a,
0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x96, 0x01, 0x0a,
0x0c, 0x49, 0x73, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x12, 0x1c, 0x0a,
0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x76,
0x65, 0x72, 0x62, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x76, 0x65, 0x72, 0x62, 0x12,
0x14, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
0x65, 0x12, 0x22, 0x0a, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d,
0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x4c, 0x0a, 0x13, 0x49, 0x73, 0x41, 0x75, 0x74, 0x68, 0x6f,
0x72, 0x69, 0x7a, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x35, 0x0a, 0x0c,
0x69, 0x73, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x49, 0x73, 0x41, 0x75, 0x74, 0x68, 0x6f,
0x72, 0x69, 0x7a, 0x65, 0x64, 0x52, 0x0c, 0x69, 0x73, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
0x7a, 0x65, 0x64, 0x22, 0x36, 0x0a, 0x14, 0x49, 0x73, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
0x7a, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x61,
0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52,
0x0a, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x22, 0x24, 0x0a, 0x0c, 0x54,
0x6f, 0x6b, 0x65, 0x6e, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x74,
0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65,
0x6e, 0x22, 0x3e, 0x0a, 0x13, 0x49, 0x73, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x54, 0x6f, 0x6b, 0x65,
0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65,
0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x54, 0x6f,
0x6b, 0x65, 0x6e, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65,
0x6e, 0x22, 0x2e, 0x0a, 0x14, 0x49, 0x73, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x54, 0x6f, 0x6b, 0x65,
0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d,
0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69,
0x6e, 0x32, 0xea, 0x01, 0x0a, 0x0b, 0x41, 0x75, 0x74, 0x68, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
0x65, 0x12, 0x6c, 0x0a, 0x0c, 0x49, 0x73, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x54, 0x6f, 0x6b, 0x65,
0x6e, 0x12, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x49, 0x73, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x54,
0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x61, 0x70,
0x69, 0x2e, 0x49, 0x73, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x22, 0x18,
0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x75,
0x74, 0x68, 0x2f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12,
0x2c, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x73, 0x77, 0x61, 0x67,
0x67, 0x65, 0x72, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x61, 0x6e, 0x6e, 0x6f,
0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x47, 0x0a,
0x13, 0x49, 0x73, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65,
0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x60, 0x0a, 0x14, 0x49, 0x73, 0x56, 0x61, 0x6c, 0x69,
0x64, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16,
0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18,
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1a, 0x0a, 0x08,
0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x96, 0x01, 0x0a, 0x0c, 0x49, 0x73, 0x41,
0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d,
0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61,
0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x76, 0x65, 0x72, 0x62, 0x18,
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x76, 0x65, 0x72, 0x62, 0x12, 0x14, 0x0a, 0x05, 0x67,
0x72, 0x6f, 0x75, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75,
0x70, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20,
0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x22, 0x0a,
0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20,
0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d,
0x65, 0x22, 0x4c, 0x0a, 0x13, 0x49, 0x73, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65,
0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x35, 0x0a, 0x0c, 0x69, 0x73, 0x41, 0x75,
0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11,
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x49, 0x73, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65,
0x64, 0x52, 0x0c, 0x69, 0x73, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x22,
0x36, 0x0a, 0x14, 0x49, 0x73, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x6f,
0x72, 0x69, 0x7a, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x61, 0x75, 0x74,
0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x22, 0x49, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x41, 0x63,
0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05,
0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b,
0x65, 0x6e, 0x22, 0x6e, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54,
0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06,
0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f,
0x6d, 0x61, 0x69, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f,
0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73,
0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61,
0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61,
0x6d, 0x65, 0x32, 0xe9, 0x02, 0x0a, 0x0b, 0x41, 0x75, 0x74, 0x68, 0x53, 0x65, 0x72, 0x76, 0x69,
0x63, 0x65, 0x12, 0x6b, 0x0a, 0x0c, 0x49, 0x73, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x54, 0x6f, 0x6b,
0x65, 0x6e, 0x12, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x49, 0x73, 0x56, 0x61, 0x6c, 0x69, 0x64,
0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x61,
0x70, 0x69, 0x2e, 0x49, 0x73, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x88, 0x02, 0x01, 0x82, 0xd3, 0xe4, 0x93,
0x02, 0x1d, 0x22, 0x18, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61,
0x31, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x01, 0x2a, 0x12,
0x7e, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65,
0x6e, 0x12, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x73,
0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e,
0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b,
0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x33, 0x82, 0xd3, 0xe4, 0x93,
0x02, 0x28, 0x22, 0x23, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61,
0x31, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73,
0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x01, 0x2a, 0x92, 0x41, 0x02, 0x62, 0x00, 0x12,
0x6d, 0x0a, 0x0c, 0x49, 0x73, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x12,
0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x49, 0x73, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a,
0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e,
@@ -410,27 +527,29 @@ func file_auth_proto_rawDescGZIP() []byte {
return file_auth_proto_rawDescData
}
var file_auth_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
var file_auth_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
var file_auth_proto_goTypes = []interface{}{
(*IsAuthorized)(nil), // 0: api.IsAuthorized
(*IsAuthorizedRequest)(nil), // 1: api.IsAuthorizedRequest
(*IsAuthorizedResponse)(nil), // 2: api.IsAuthorizedResponse
(*TokenWrapper)(nil), // 3: api.TokenWrapper
(*IsValidTokenRequest)(nil), // 4: api.IsValidTokenRequest
(*IsValidTokenResponse)(nil), // 5: api.IsValidTokenResponse
(*IsValidTokenRequest)(nil), // 0: api.IsValidTokenRequest
(*IsValidTokenResponse)(nil), // 1: api.IsValidTokenResponse
(*IsAuthorized)(nil), // 2: api.IsAuthorized
(*IsAuthorizedRequest)(nil), // 3: api.IsAuthorizedRequest
(*IsAuthorizedResponse)(nil), // 4: api.IsAuthorizedResponse
(*GetAccessTokenRequest)(nil), // 5: api.GetAccessTokenRequest
(*GetAccessTokenResponse)(nil), // 6: api.GetAccessTokenResponse
}
var file_auth_proto_depIdxs = []int32{
0, // 0: api.IsAuthorizedRequest.isAuthorized:type_name -> api.IsAuthorized
3, // 1: api.IsValidTokenRequest.token:type_name -> api.TokenWrapper
4, // 2: api.AuthService.IsValidToken:input_type -> api.IsValidTokenRequest
1, // 3: api.AuthService.IsAuthorized:input_type -> api.IsAuthorizedRequest
5, // 4: api.AuthService.IsValidToken:output_type -> api.IsValidTokenResponse
2, // 5: api.AuthService.IsAuthorized:output_type -> api.IsAuthorizedResponse
4, // [4:6] is the sub-list for method output_type
2, // [2:4] is the sub-list for method input_type
2, // [2:2] is the sub-list for extension type_name
2, // [2:2] is the sub-list for extension extendee
0, // [0:2] is the sub-list for field type_name
2, // 0: api.IsAuthorizedRequest.isAuthorized:type_name -> api.IsAuthorized
0, // 1: api.AuthService.IsValidToken:input_type -> api.IsValidTokenRequest
5, // 2: api.AuthService.GetAccessToken:input_type -> api.GetAccessTokenRequest
3, // 3: api.AuthService.IsAuthorized:input_type -> api.IsAuthorizedRequest
1, // 4: api.AuthService.IsValidToken:output_type -> api.IsValidTokenResponse
6, // 5: api.AuthService.GetAccessToken:output_type -> api.GetAccessTokenResponse
4, // 6: api.AuthService.IsAuthorized:output_type -> api.IsAuthorizedResponse
4, // [4:7] is the sub-list for method output_type
1, // [1:4] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name
1, // [1:1] is the sub-list for extension extendee
0, // [0:1] is the sub-list for field type_name
}
func init() { file_auth_proto_init() }
@@ -440,54 +559,6 @@ func file_auth_proto_init() {
}
if !protoimpl.UnsafeEnabled {
file_auth_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*IsAuthorized); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_auth_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*IsAuthorizedRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_auth_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*IsAuthorizedResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_auth_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*TokenWrapper); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_auth_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*IsValidTokenRequest); i {
case 0:
return &v.state
@@ -499,7 +570,7 @@ func file_auth_proto_init() {
return nil
}
}
file_auth_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
file_auth_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*IsValidTokenResponse); i {
case 0:
return &v.state
@@ -511,6 +582,66 @@ func file_auth_proto_init() {
return nil
}
}
file_auth_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*IsAuthorized); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_auth_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*IsAuthorizedRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_auth_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*IsAuthorizedResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_auth_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetAccessTokenRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_auth_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetAccessTokenResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
@@ -518,7 +649,7 @@ func file_auth_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_auth_proto_rawDesc,
NumEnums: 0,
NumMessages: 6,
NumMessages: 7,
NumExtensions: 0,
NumServices: 1,
},
@@ -544,7 +675,9 @@ const _ = grpc.SupportPackageIsVersion6
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type AuthServiceClient interface {
// Deprecated: Do not use.
IsValidToken(ctx context.Context, in *IsValidTokenRequest, opts ...grpc.CallOption) (*IsValidTokenResponse, error)
GetAccessToken(ctx context.Context, in *GetAccessTokenRequest, opts ...grpc.CallOption) (*GetAccessTokenResponse, error)
IsAuthorized(ctx context.Context, in *IsAuthorizedRequest, opts ...grpc.CallOption) (*IsAuthorizedResponse, error)
}
@@ -556,6 +689,7 @@ func NewAuthServiceClient(cc grpc.ClientConnInterface) AuthServiceClient {
return &authServiceClient{cc}
}
// Deprecated: Do not use.
func (c *authServiceClient) IsValidToken(ctx context.Context, in *IsValidTokenRequest, opts ...grpc.CallOption) (*IsValidTokenResponse, error) {
out := new(IsValidTokenResponse)
err := c.cc.Invoke(ctx, "/api.AuthService/IsValidToken", in, out, opts...)
@@ -565,6 +699,15 @@ func (c *authServiceClient) IsValidToken(ctx context.Context, in *IsValidTokenRe
return out, nil
}
func (c *authServiceClient) GetAccessToken(ctx context.Context, in *GetAccessTokenRequest, opts ...grpc.CallOption) (*GetAccessTokenResponse, error) {
out := new(GetAccessTokenResponse)
err := c.cc.Invoke(ctx, "/api.AuthService/GetAccessToken", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *authServiceClient) IsAuthorized(ctx context.Context, in *IsAuthorizedRequest, opts ...grpc.CallOption) (*IsAuthorizedResponse, error) {
out := new(IsAuthorizedResponse)
err := c.cc.Invoke(ctx, "/api.AuthService/IsAuthorized", in, out, opts...)
@@ -576,7 +719,9 @@ func (c *authServiceClient) IsAuthorized(ctx context.Context, in *IsAuthorizedRe
// AuthServiceServer is the server API for AuthService service.
type AuthServiceServer interface {
// Deprecated: Do not use.
IsValidToken(context.Context, *IsValidTokenRequest) (*IsValidTokenResponse, error)
GetAccessToken(context.Context, *GetAccessTokenRequest) (*GetAccessTokenResponse, error)
IsAuthorized(context.Context, *IsAuthorizedRequest) (*IsAuthorizedResponse, error)
}
@@ -587,6 +732,9 @@ type UnimplementedAuthServiceServer struct {
func (*UnimplementedAuthServiceServer) IsValidToken(context.Context, *IsValidTokenRequest) (*IsValidTokenResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method IsValidToken not implemented")
}
func (*UnimplementedAuthServiceServer) GetAccessToken(context.Context, *GetAccessTokenRequest) (*GetAccessTokenResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetAccessToken not implemented")
}
func (*UnimplementedAuthServiceServer) IsAuthorized(context.Context, *IsAuthorizedRequest) (*IsAuthorizedResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method IsAuthorized not implemented")
}
@@ -613,6 +761,24 @@ func _AuthService_IsValidToken_Handler(srv interface{}, ctx context.Context, dec
return interceptor(ctx, in, info, handler)
}
func _AuthService_GetAccessToken_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetAccessTokenRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(AuthServiceServer).GetAccessToken(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/api.AuthService/GetAccessToken",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(AuthServiceServer).GetAccessToken(ctx, req.(*GetAccessTokenRequest))
}
return interceptor(ctx, in, info, handler)
}
func _AuthService_IsAuthorized_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(IsAuthorizedRequest)
if err := dec(in); err != nil {
@@ -639,6 +805,10 @@ var _AuthService_serviceDesc = grpc.ServiceDesc{
MethodName: "IsValidToken",
Handler: _AuthService_IsValidToken_Handler,
},
{
MethodName: "GetAccessToken",
Handler: _AuthService_GetAccessToken_Handler,
},
{
MethodName: "IsAuthorized",
Handler: _AuthService_IsAuthorized_Handler,

View File

@@ -39,7 +39,7 @@ func request_AuthService_IsValidToken_0(ctx context.Context, marshaler runtime.M
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Token); err != nil && err != io.EOF {
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
@@ -56,7 +56,7 @@ func local_request_AuthService_IsValidToken_0(ctx context.Context, marshaler run
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Token); err != nil && err != io.EOF {
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
@@ -65,6 +65,40 @@ func local_request_AuthService_IsValidToken_0(ctx context.Context, marshaler run
}
func request_AuthService_GetAccessToken_0(ctx context.Context, marshaler runtime.Marshaler, client AuthServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq GetAccessTokenRequest
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.GetAccessToken(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_AuthService_GetAccessToken_0(ctx context.Context, marshaler runtime.Marshaler, server AuthServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq GetAccessTokenRequest
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.GetAccessToken(ctx, &protoReq)
return msg, metadata, err
}
func request_AuthService_IsAuthorized_0(ctx context.Context, marshaler runtime.Marshaler, client AuthServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq IsAuthorizedRequest
var metadata runtime.ServerMetadata
@@ -124,6 +158,26 @@ func RegisterAuthServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux
})
mux.Handle("POST", pattern_AuthService_GetAccessToken_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_AuthService_GetAccessToken_0(rctx, inboundMarshaler, server, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_AuthService_GetAccessToken_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("POST", pattern_AuthService_IsAuthorized_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
@@ -205,6 +259,26 @@ func RegisterAuthServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux
})
mux.Handle("POST", pattern_AuthService_GetAccessToken_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_AuthService_GetAccessToken_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_AuthService_GetAccessToken_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("POST", pattern_AuthService_IsAuthorized_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
@@ -231,11 +305,15 @@ func RegisterAuthServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux
var (
pattern_AuthService_IsValidToken_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"apis", "v1beta1", "auth", "token"}, "", runtime.AssumeColonVerbOpt(true)))
pattern_AuthService_GetAccessToken_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"apis", "v1beta1", "auth", "get_access_token"}, "", runtime.AssumeColonVerbOpt(true)))
pattern_AuthService_IsAuthorized_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"apis", "v1beta1", "auth"}, "", runtime.AssumeColonVerbOpt(true)))
)
var (
forward_AuthService_IsValidToken_0 = runtime.ForwardResponseMessage
forward_AuthService_GetAccessToken_0 = runtime.ForwardResponseMessage
forward_AuthService_IsAuthorized_0 = runtime.ForwardResponseMessage
)

View File

@@ -3,13 +3,25 @@ syntax = "proto3";
package api;
import "google/api/annotations.proto";
import "google/protobuf/empty.proto";
import "protoc-gen-swagger/options/annotations.proto";
service AuthService {
rpc IsValidToken(IsValidTokenRequest) returns (IsValidTokenResponse) {
option (google.api.http) = {
post: "/apis/v1beta1/auth/token"
body: "token"
body: "*"
};
option deprecated = true;
}
rpc GetAccessToken(GetAccessTokenRequest) returns (GetAccessTokenResponse) {
option (google.api.http) = {
post: "/apis/v1beta1/auth/get_access_token"
body: "*"
};
option (grpc.gateway.protoc_gen_swagger.options.openapiv2_operation) = {
security: {
}
};
}
@@ -21,6 +33,17 @@ service AuthService {
}
}
message IsValidTokenRequest {
string username = 1;
string token = 2;
}
message IsValidTokenResponse {
string domain = 1;
string token = 2;
string username = 3;
}
message IsAuthorized {
string namespace = 1;
string verb = 2;
@@ -37,14 +60,13 @@ message IsAuthorizedResponse {
bool authorized = 1;
}
message TokenWrapper {
string token = 1;
message GetAccessTokenRequest {
string username = 1;
string token = 2;
}
message IsValidTokenRequest {
TokenWrapper token = 1;
}
message IsValidTokenResponse {
message GetAccessTokenResponse {
string domain = 1;
string accessToken = 2;
string username = 3;
}

View File

@@ -337,6 +337,77 @@ func (x *GetLabelsRequest) GetUid() string {
return ""
}
type GetAvailableLabelsRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Namespace string `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"`
Resource string `protobuf:"bytes,2,opt,name=resource,proto3" json:"resource,omitempty"`
KeyLike string `protobuf:"bytes,3,opt,name=keyLike,proto3" json:"keyLike,omitempty"`
SkipKeys string `protobuf:"bytes,4,opt,name=skipKeys,proto3" json:"skipKeys,omitempty"`
}
func (x *GetAvailableLabelsRequest) Reset() {
*x = GetAvailableLabelsRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_label_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *GetAvailableLabelsRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetAvailableLabelsRequest) ProtoMessage() {}
func (x *GetAvailableLabelsRequest) ProtoReflect() protoreflect.Message {
mi := &file_label_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetAvailableLabelsRequest.ProtoReflect.Descriptor instead.
func (*GetAvailableLabelsRequest) Descriptor() ([]byte, []int) {
return file_label_proto_rawDescGZIP(), []int{5}
}
func (x *GetAvailableLabelsRequest) GetNamespace() string {
if x != nil {
return x.Namespace
}
return ""
}
func (x *GetAvailableLabelsRequest) GetResource() string {
if x != nil {
return x.Resource
}
return ""
}
func (x *GetAvailableLabelsRequest) GetKeyLike() string {
if x != nil {
return x.KeyLike
}
return ""
}
func (x *GetAvailableLabelsRequest) GetSkipKeys() string {
if x != nil {
return x.SkipKeys
}
return ""
}
type GetLabelsResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -348,7 +419,7 @@ type GetLabelsResponse struct {
func (x *GetLabelsResponse) Reset() {
*x = GetLabelsResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_label_proto_msgTypes[5]
mi := &file_label_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -361,7 +432,7 @@ func (x *GetLabelsResponse) String() string {
func (*GetLabelsResponse) ProtoMessage() {}
func (x *GetLabelsResponse) ProtoReflect() protoreflect.Message {
mi := &file_label_proto_msgTypes[5]
mi := &file_label_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -374,7 +445,7 @@ func (x *GetLabelsResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use GetLabelsResponse.ProtoReflect.Descriptor instead.
func (*GetLabelsResponse) Descriptor() ([]byte, []int) {
return file_label_proto_rawDescGZIP(), []int{5}
return file_label_proto_rawDescGZIP(), []int{6}
}
func (x *GetLabelsResponse) GetLabels() []*KeyValue {
@@ -398,7 +469,7 @@ type DeleteLabelRequest struct {
func (x *DeleteLabelRequest) Reset() {
*x = DeleteLabelRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_label_proto_msgTypes[6]
mi := &file_label_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -411,7 +482,7 @@ func (x *DeleteLabelRequest) String() string {
func (*DeleteLabelRequest) ProtoMessage() {}
func (x *DeleteLabelRequest) ProtoReflect() protoreflect.Message {
mi := &file_label_proto_msgTypes[6]
mi := &file_label_proto_msgTypes[7]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -424,7 +495,7 @@ func (x *DeleteLabelRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use DeleteLabelRequest.ProtoReflect.Descriptor instead.
func (*DeleteLabelRequest) Descriptor() ([]byte, []int) {
return file_label_proto_rawDescGZIP(), []int{6}
return file_label_proto_rawDescGZIP(), []int{7}
}
func (x *DeleteLabelRequest) GetNamespace() string {
@@ -490,51 +561,69 @@ var file_label_proto_rawDesc = []byte{
0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
0x75, 0x69, 0x64, 0x22, 0x3a, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65,
0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4b,
0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x22,
0x72, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61,
0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70,
0x61, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18,
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12,
0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69,
0x64, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
0x6b, 0x65, 0x79, 0x32, 0x8d, 0x04, 0x0a, 0x0c, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x53, 0x65, 0x72,
0x76, 0x69, 0x63, 0x65, 0x12, 0x75, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x62, 0x65, 0x6c,
0x73, 0x12, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x62, 0x65, 0x6c,
0x75, 0x69, 0x64, 0x22, 0x8b, 0x01, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c,
0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12,
0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6b,
0x65, 0x79, 0x4c, 0x69, 0x6b, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, 0x65,
0x79, 0x4c, 0x69, 0x6b, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x6b, 0x69, 0x70, 0x4b, 0x65, 0x79,
0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x6b, 0x69, 0x70, 0x4b, 0x65, 0x79,
0x73, 0x22, 0x3a, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73,
0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4b, 0x65, 0x79,
0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x22, 0x72, 0x0a,
0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63,
0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20,
0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x10, 0x0a,
0x03, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12,
0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65,
0x79, 0x32, 0x98, 0x05, 0x0a, 0x0c, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69,
0x63, 0x65, 0x12, 0x88, 0x01, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61,
0x62, 0x6c, 0x65, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e,
0x47, 0x65, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x62, 0x65,
0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e,
0x47, 0x65, 0x74, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x22, 0x3a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x34, 0x12, 0x32, 0x2f, 0x61, 0x70, 0x69, 0x73,
0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x2f,
0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0x2f, 0x7b, 0x72, 0x65, 0x73,
0x6f, 0x75, 0x72, 0x63, 0x65, 0x7d, 0x2f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x75, 0x0a,
0x09, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x15, 0x2e, 0x61, 0x70, 0x69,
0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x62, 0x65, 0x6c,
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x39, 0x82, 0xd3, 0xe4, 0x93, 0x02,
0x33, 0x12, 0x31, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31,
0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0x2f, 0x7b, 0x72, 0x65,
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x7d, 0x2f, 0x7b, 0x75, 0x69, 0x64, 0x7d, 0x2f, 0x6c, 0x61,
0x62, 0x65, 0x6c, 0x73, 0x12, 0x7d, 0x0a, 0x09, 0x41, 0x64, 0x64, 0x4c, 0x61, 0x62, 0x65, 0x6c,
0x73, 0x12, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x41, 0x64, 0x64, 0x4c, 0x61, 0x62, 0x65, 0x6c,
0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47,
0x65, 0x74, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x39, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x33, 0x12, 0x31, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f,
0x22, 0x41, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3b, 0x22, 0x31, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f,
0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61,
0x63, 0x65, 0x7d, 0x2f, 0x7b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x7d, 0x2f, 0x7b,
0x75, 0x69, 0x64, 0x7d, 0x2f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x7d, 0x0a, 0x09, 0x41,
0x64, 0x64, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x41,
0x64, 0x64, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x41, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3b, 0x22,
0x31, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x7b,
0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0x2f, 0x7b, 0x72, 0x65, 0x73, 0x6f,
0x75, 0x72, 0x63, 0x65, 0x7d, 0x2f, 0x7b, 0x75, 0x69, 0x64, 0x7d, 0x2f, 0x6c, 0x61, 0x62, 0x65,
0x6c, 0x73, 0x3a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x85, 0x01, 0x0a, 0x0d, 0x52,
0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x19, 0x2e, 0x61,
0x70, 0x69, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65,
0x74, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x41, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3b, 0x1a, 0x31, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76,
0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63,
0x65, 0x7d, 0x2f, 0x7b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x7d, 0x2f, 0x7b, 0x75,
0x69, 0x64, 0x7d, 0x2f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x3a, 0x06, 0x6c, 0x61, 0x62, 0x65,
0x6c, 0x73, 0x12, 0x7f, 0x0a, 0x0b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4c, 0x61, 0x62, 0x65,
0x6c, 0x12, 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4c, 0x61,
0x62, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x61, 0x70, 0x69,
0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x22, 0x3f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x39, 0x2a, 0x37, 0x2f, 0x61, 0x70, 0x69,
0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73,
0x70, 0x61, 0x63, 0x65, 0x7d, 0x2f, 0x7b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x7d,
0x2f, 0x7b, 0x75, 0x69, 0x64, 0x7d, 0x2f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x2f, 0x7b, 0x6b,
0x65, 0x79, 0x7d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x75, 0x69, 0x64, 0x7d, 0x2f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x3a, 0x06, 0x6c, 0x61, 0x62,
0x65, 0x6c, 0x73, 0x12, 0x85, 0x01, 0x0a, 0x0d, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x4c,
0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x70, 0x6c,
0x61, 0x63, 0x65, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x41, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3b,
0x1a, 0x31, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f,
0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0x2f, 0x7b, 0x72, 0x65, 0x73,
0x6f, 0x75, 0x72, 0x63, 0x65, 0x7d, 0x2f, 0x7b, 0x75, 0x69, 0x64, 0x7d, 0x2f, 0x6c, 0x61, 0x62,
0x65, 0x6c, 0x73, 0x3a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x7f, 0x0a, 0x0b, 0x44,
0x65, 0x6c, 0x65, 0x74, 0x65, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x17, 0x2e, 0x61, 0x70, 0x69,
0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x62,
0x65, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3f, 0x82, 0xd3, 0xe4,
0x93, 0x02, 0x39, 0x2a, 0x37, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74,
0x61, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0x2f, 0x7b,
0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x7d, 0x2f, 0x7b, 0x75, 0x69, 0x64, 0x7d, 0x2f,
0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x2f, 0x7b, 0x6b, 0x65, 0x79, 0x7d, 0x62, 0x06, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -549,31 +638,34 @@ func file_label_proto_rawDescGZIP() []byte {
return file_label_proto_rawDescData
}
var file_label_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
var file_label_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
var file_label_proto_goTypes = []interface{}{
(*KeyValue)(nil), // 0: api.KeyValue
(*Labels)(nil), // 1: api.Labels
(*AddLabelsRequest)(nil), // 2: api.AddLabelsRequest
(*ReplaceLabelsRequest)(nil), // 3: api.ReplaceLabelsRequest
(*GetLabelsRequest)(nil), // 4: api.GetLabelsRequest
(*GetLabelsResponse)(nil), // 5: api.GetLabelsResponse
(*DeleteLabelRequest)(nil), // 6: api.DeleteLabelRequest
(*KeyValue)(nil), // 0: api.KeyValue
(*Labels)(nil), // 1: api.Labels
(*AddLabelsRequest)(nil), // 2: api.AddLabelsRequest
(*ReplaceLabelsRequest)(nil), // 3: api.ReplaceLabelsRequest
(*GetLabelsRequest)(nil), // 4: api.GetLabelsRequest
(*GetAvailableLabelsRequest)(nil), // 5: api.GetAvailableLabelsRequest
(*GetLabelsResponse)(nil), // 6: api.GetLabelsResponse
(*DeleteLabelRequest)(nil), // 7: api.DeleteLabelRequest
}
var file_label_proto_depIdxs = []int32{
0, // 0: api.Labels.items:type_name -> api.KeyValue
1, // 1: api.AddLabelsRequest.labels:type_name -> api.Labels
1, // 2: api.ReplaceLabelsRequest.labels:type_name -> api.Labels
0, // 3: api.GetLabelsResponse.labels:type_name -> api.KeyValue
4, // 4: api.LabelService.GetLabels:input_type -> api.GetLabelsRequest
2, // 5: api.LabelService.AddLabels:input_type -> api.AddLabelsRequest
3, // 6: api.LabelService.ReplaceLabels:input_type -> api.ReplaceLabelsRequest
6, // 7: api.LabelService.DeleteLabel:input_type -> api.DeleteLabelRequest
5, // 8: api.LabelService.GetLabels:output_type -> api.GetLabelsResponse
5, // 9: api.LabelService.AddLabels:output_type -> api.GetLabelsResponse
5, // 10: api.LabelService.ReplaceLabels:output_type -> api.GetLabelsResponse
5, // 11: api.LabelService.DeleteLabel:output_type -> api.GetLabelsResponse
8, // [8:12] is the sub-list for method output_type
4, // [4:8] is the sub-list for method input_type
5, // 4: api.LabelService.GetAvailableLabels:input_type -> api.GetAvailableLabelsRequest
4, // 5: api.LabelService.GetLabels:input_type -> api.GetLabelsRequest
2, // 6: api.LabelService.AddLabels:input_type -> api.AddLabelsRequest
3, // 7: api.LabelService.ReplaceLabels:input_type -> api.ReplaceLabelsRequest
7, // 8: api.LabelService.DeleteLabel:input_type -> api.DeleteLabelRequest
6, // 9: api.LabelService.GetAvailableLabels:output_type -> api.GetLabelsResponse
6, // 10: api.LabelService.GetLabels:output_type -> api.GetLabelsResponse
6, // 11: api.LabelService.AddLabels:output_type -> api.GetLabelsResponse
6, // 12: api.LabelService.ReplaceLabels:output_type -> api.GetLabelsResponse
6, // 13: api.LabelService.DeleteLabel:output_type -> api.GetLabelsResponse
9, // [9:14] is the sub-list for method output_type
4, // [4:9] is the sub-list for method input_type
4, // [4:4] is the sub-list for extension type_name
4, // [4:4] is the sub-list for extension extendee
0, // [0:4] is the sub-list for field type_name
@@ -646,7 +738,7 @@ func file_label_proto_init() {
}
}
file_label_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetLabelsResponse); i {
switch v := v.(*GetAvailableLabelsRequest); i {
case 0:
return &v.state
case 1:
@@ -658,6 +750,18 @@ func file_label_proto_init() {
}
}
file_label_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetLabelsResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_label_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DeleteLabelRequest); i {
case 0:
return &v.state
@@ -676,7 +780,7 @@ func file_label_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_label_proto_rawDesc,
NumEnums: 0,
NumMessages: 7,
NumMessages: 8,
NumExtensions: 0,
NumServices: 1,
},
@@ -702,6 +806,7 @@ const _ = grpc.SupportPackageIsVersion6
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type LabelServiceClient interface {
GetAvailableLabels(ctx context.Context, in *GetAvailableLabelsRequest, opts ...grpc.CallOption) (*GetLabelsResponse, error)
GetLabels(ctx context.Context, in *GetLabelsRequest, opts ...grpc.CallOption) (*GetLabelsResponse, error)
AddLabels(ctx context.Context, in *AddLabelsRequest, opts ...grpc.CallOption) (*GetLabelsResponse, error)
ReplaceLabels(ctx context.Context, in *ReplaceLabelsRequest, opts ...grpc.CallOption) (*GetLabelsResponse, error)
@@ -716,6 +821,15 @@ func NewLabelServiceClient(cc grpc.ClientConnInterface) LabelServiceClient {
return &labelServiceClient{cc}
}
func (c *labelServiceClient) GetAvailableLabels(ctx context.Context, in *GetAvailableLabelsRequest, opts ...grpc.CallOption) (*GetLabelsResponse, error) {
out := new(GetLabelsResponse)
err := c.cc.Invoke(ctx, "/api.LabelService/GetAvailableLabels", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *labelServiceClient) GetLabels(ctx context.Context, in *GetLabelsRequest, opts ...grpc.CallOption) (*GetLabelsResponse, error) {
out := new(GetLabelsResponse)
err := c.cc.Invoke(ctx, "/api.LabelService/GetLabels", in, out, opts...)
@@ -754,6 +868,7 @@ func (c *labelServiceClient) DeleteLabel(ctx context.Context, in *DeleteLabelReq
// LabelServiceServer is the server API for LabelService service.
type LabelServiceServer interface {
GetAvailableLabels(context.Context, *GetAvailableLabelsRequest) (*GetLabelsResponse, error)
GetLabels(context.Context, *GetLabelsRequest) (*GetLabelsResponse, error)
AddLabels(context.Context, *AddLabelsRequest) (*GetLabelsResponse, error)
ReplaceLabels(context.Context, *ReplaceLabelsRequest) (*GetLabelsResponse, error)
@@ -764,6 +879,9 @@ type LabelServiceServer interface {
type UnimplementedLabelServiceServer struct {
}
func (*UnimplementedLabelServiceServer) GetAvailableLabels(context.Context, *GetAvailableLabelsRequest) (*GetLabelsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetAvailableLabels not implemented")
}
func (*UnimplementedLabelServiceServer) GetLabels(context.Context, *GetLabelsRequest) (*GetLabelsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetLabels not implemented")
}
@@ -781,6 +899,24 @@ func RegisterLabelServiceServer(s *grpc.Server, srv LabelServiceServer) {
s.RegisterService(&_LabelService_serviceDesc, srv)
}
func _LabelService_GetAvailableLabels_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetAvailableLabelsRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(LabelServiceServer).GetAvailableLabels(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/api.LabelService/GetAvailableLabels",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(LabelServiceServer).GetAvailableLabels(ctx, req.(*GetAvailableLabelsRequest))
}
return interceptor(ctx, in, info, handler)
}
func _LabelService_GetLabels_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetLabelsRequest)
if err := dec(in); err != nil {
@@ -857,6 +993,10 @@ var _LabelService_serviceDesc = grpc.ServiceDesc{
ServiceName: "api.LabelService",
HandlerType: (*LabelServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "GetAvailableLabels",
Handler: _LabelService_GetAvailableLabels_Handler,
},
{
MethodName: "GetLabels",
Handler: _LabelService_GetLabels_Handler,

View File

@@ -31,6 +31,97 @@ var _ = runtime.String
var _ = utilities.NewDoubleArray
var _ = descriptor.ForMessage
var (
filter_LabelService_GetAvailableLabels_0 = &utilities.DoubleArray{Encoding: map[string]int{"namespace": 0, "resource": 1}, Base: []int{1, 1, 2, 0, 0}, Check: []int{0, 1, 1, 2, 3}}
)
func request_LabelService_GetAvailableLabels_0(ctx context.Context, marshaler runtime.Marshaler, client LabelServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq GetAvailableLabelsRequest
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["namespace"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "namespace")
}
protoReq.Namespace, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "namespace", err)
}
val, ok = pathParams["resource"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "resource")
}
protoReq.Resource, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "resource", err)
}
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_LabelService_GetAvailableLabels_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.GetAvailableLabels(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_LabelService_GetAvailableLabels_0(ctx context.Context, marshaler runtime.Marshaler, server LabelServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq GetAvailableLabelsRequest
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["namespace"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "namespace")
}
protoReq.Namespace, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "namespace", err)
}
val, ok = pathParams["resource"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "resource")
}
protoReq.Resource, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "resource", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_LabelService_GetAvailableLabels_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.GetAvailableLabels(ctx, &protoReq)
return msg, metadata, err
}
func request_LabelService_GetLabels_0(ctx context.Context, marshaler runtime.Marshaler, client LabelServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq GetLabelsRequest
var metadata runtime.ServerMetadata
@@ -482,6 +573,26 @@ func local_request_LabelService_DeleteLabel_0(ctx context.Context, marshaler run
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
func RegisterLabelServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server LabelServiceServer) error {
mux.Handle("GET", pattern_LabelService_GetAvailableLabels_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_LabelService_GetAvailableLabels_0(rctx, inboundMarshaler, server, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_LabelService_GetAvailableLabels_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_LabelService_GetLabels_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
@@ -603,6 +714,26 @@ func RegisterLabelServiceHandler(ctx context.Context, mux *runtime.ServeMux, con
// "LabelServiceClient" to call the correct interceptors.
func RegisterLabelServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client LabelServiceClient) error {
mux.Handle("GET", pattern_LabelService_GetAvailableLabels_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_LabelService_GetAvailableLabels_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_LabelService_GetAvailableLabels_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_LabelService_GetLabels_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
@@ -687,6 +818,8 @@ func RegisterLabelServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu
}
var (
pattern_LabelService_GetAvailableLabels_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 1, 0, 4, 1, 5, 4, 2, 2}, []string{"apis", "v1beta1", "labels", "namespace", "resource"}, "", runtime.AssumeColonVerbOpt(true)))
pattern_LabelService_GetLabels_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 1, 0, 4, 1, 5, 3, 1, 0, 4, 1, 5, 4, 2, 5}, []string{"apis", "v1beta1", "namespace", "resource", "uid", "labels"}, "", runtime.AssumeColonVerbOpt(true)))
pattern_LabelService_AddLabels_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 1, 0, 4, 1, 5, 3, 1, 0, 4, 1, 5, 4, 2, 5}, []string{"apis", "v1beta1", "namespace", "resource", "uid", "labels"}, "", runtime.AssumeColonVerbOpt(true)))
@@ -697,6 +830,8 @@ var (
)
var (
forward_LabelService_GetAvailableLabels_0 = runtime.ForwardResponseMessage
forward_LabelService_GetLabels_0 = runtime.ForwardResponseMessage
forward_LabelService_AddLabels_0 = runtime.ForwardResponseMessage

View File

@@ -5,6 +5,12 @@ package api;
import "google/api/annotations.proto";
service LabelService {
rpc GetAvailableLabels (GetAvailableLabelsRequest) returns (GetLabelsResponse) {
option (google.api.http) = {
get: "/apis/v1beta1/labels/{namespace}/{resource}/labels"
};
}
rpc GetLabels (GetLabelsRequest) returns (GetLabelsResponse) {
option (google.api.http) = {
get: "/apis/v1beta1/{namespace}/{resource}/{uid}/labels"
@@ -61,6 +67,13 @@ message GetLabelsRequest {
string uid = 3;
}
message GetAvailableLabelsRequest {
string namespace = 1;
string resource = 2;
string keyLike = 3;
string skipKeys = 4;
}
message GetLabelsResponse {
repeated KeyValue labels = 1;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1212,6 +1212,190 @@ func local_request_WorkflowService_UpdateWorkflowExecutionStatus_0(ctx context.C
}
func request_WorkflowService_AddWorkflowExecutionMetrics_0(ctx context.Context, marshaler runtime.Marshaler, client WorkflowServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq AddWorkflowExecutionsMetricsRequest
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["namespace"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "namespace")
}
protoReq.Namespace, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "namespace", err)
}
val, ok = pathParams["uid"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "uid")
}
protoReq.Uid, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "uid", err)
}
msg, err := client.AddWorkflowExecutionMetrics(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_WorkflowService_AddWorkflowExecutionMetrics_0(ctx context.Context, marshaler runtime.Marshaler, server WorkflowServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq AddWorkflowExecutionsMetricsRequest
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["namespace"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "namespace")
}
protoReq.Namespace, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "namespace", err)
}
val, ok = pathParams["uid"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "uid")
}
protoReq.Uid, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "uid", err)
}
msg, err := server.AddWorkflowExecutionMetrics(ctx, &protoReq)
return msg, metadata, err
}
func request_WorkflowService_UpdateWorkflowExecutionMetrics_0(ctx context.Context, marshaler runtime.Marshaler, client WorkflowServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq UpdateWorkflowExecutionsMetricsRequest
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["namespace"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "namespace")
}
protoReq.Namespace, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "namespace", err)
}
val, ok = pathParams["uid"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "uid")
}
protoReq.Uid, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "uid", err)
}
msg, err := client.UpdateWorkflowExecutionMetrics(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_WorkflowService_UpdateWorkflowExecutionMetrics_0(ctx context.Context, marshaler runtime.Marshaler, server WorkflowServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq UpdateWorkflowExecutionsMetricsRequest
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["namespace"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "namespace")
}
protoReq.Namespace, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "namespace", err)
}
val, ok = pathParams["uid"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "uid")
}
protoReq.Uid, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "uid", err)
}
msg, err := server.UpdateWorkflowExecutionMetrics(ctx, &protoReq)
return msg, metadata, err
}
// RegisterWorkflowServiceHandlerServer registers the http handlers for service WorkflowService to "mux".
// UnaryRPC :call WorkflowServiceServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
@@ -1491,6 +1675,46 @@ func RegisterWorkflowServiceHandlerServer(ctx context.Context, mux *runtime.Serv
})
mux.Handle("POST", pattern_WorkflowService_AddWorkflowExecutionMetrics_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_WorkflowService_AddWorkflowExecutionMetrics_0(rctx, inboundMarshaler, server, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_WorkflowService_AddWorkflowExecutionMetrics_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("PUT", pattern_WorkflowService_UpdateWorkflowExecutionMetrics_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_WorkflowService_UpdateWorkflowExecutionMetrics_0(rctx, inboundMarshaler, server, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_WorkflowService_UpdateWorkflowExecutionMetrics_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
@@ -1832,6 +2056,46 @@ func RegisterWorkflowServiceHandlerClient(ctx context.Context, mux *runtime.Serv
})
mux.Handle("POST", pattern_WorkflowService_AddWorkflowExecutionMetrics_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_WorkflowService_AddWorkflowExecutionMetrics_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_WorkflowService_AddWorkflowExecutionMetrics_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("PUT", pattern_WorkflowService_UpdateWorkflowExecutionMetrics_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_WorkflowService_UpdateWorkflowExecutionMetrics_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_WorkflowService_UpdateWorkflowExecutionMetrics_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
@@ -1865,6 +2129,10 @@ var (
pattern_WorkflowService_CronStartWorkflowExecutionStatistic_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5}, []string{"apis", "v1beta1", "namespace", "workflow_executions", "uid", "cron_start_statistics"}, "", runtime.AssumeColonVerbOpt(true)))
pattern_WorkflowService_UpdateWorkflowExecutionStatus_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5}, []string{"apis", "v1beta1", "namespace", "workflow_executions", "uid", "status"}, "", runtime.AssumeColonVerbOpt(true)))
pattern_WorkflowService_AddWorkflowExecutionMetrics_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5}, []string{"apis", "v1beta1", "namespace", "workflow_executions", "uid", "metric"}, "", runtime.AssumeColonVerbOpt(true)))
pattern_WorkflowService_UpdateWorkflowExecutionMetrics_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5}, []string{"apis", "v1beta1", "namespace", "workflow_executions", "uid", "metric"}, "", runtime.AssumeColonVerbOpt(true)))
)
var (
@@ -1897,4 +2165,8 @@ var (
forward_WorkflowService_CronStartWorkflowExecutionStatistic_0 = runtime.ForwardResponseMessage
forward_WorkflowService_UpdateWorkflowExecutionStatus_0 = runtime.ForwardResponseMessage
forward_WorkflowService_AddWorkflowExecutionMetrics_0 = runtime.ForwardResponseMessage
forward_WorkflowService_UpdateWorkflowExecutionMetrics_0 = runtime.ForwardResponseMessage
)

View File

@@ -105,6 +105,20 @@ service WorkflowService {
body: "status"
};
}
rpc AddWorkflowExecutionMetrics (AddWorkflowExecutionsMetricsRequest) returns (WorkflowExecutionsMetricsResponse) {
option (google.api.http) = {
post: "/apis/v1beta1/{namespace}/workflow_executions/{uid}/metric"
body: "*"
};
}
rpc UpdateWorkflowExecutionMetrics (UpdateWorkflowExecutionsMetricsRequest) returns (WorkflowExecutionsMetricsResponse) {
option (google.api.http) = {
put: "/apis/v1beta1/{namespace}/workflow_executions/{uid}/metric"
body: "*"
};
}
}
message CreateWorkflowExecutionBody {
@@ -187,6 +201,7 @@ message ListWorkflowExecutionsResponse {
int32 page = 3;
int32 pages = 4;
int32 totalCount = 5;
int32 totalAvailableCount = 6;
}
message LogEntry {
@@ -214,6 +229,8 @@ message WorkflowExecution {
repeated KeyValue labels = 10;
WorkflowExecutionMetadata metadata = 11;
repeated Metric metrics = 12;
}
message ArtifactResponse {
@@ -274,4 +291,27 @@ message GetWorkflowExecutionStatisticsForNamespaceRequest {
message GetWorkflowExecutionStatisticsForNamespaceResponse {
WorkflowExecutionStatisticReport stats = 1;
}
message AddWorkflowExecutionMetricRequest {
string namespace = 1;
string uid = 2;
Metric metric = 3;
}
message AddWorkflowExecutionsMetricsRequest {
string namespace = 1;
string uid = 2;
bool override = 3;
repeated Metric metrics = 4;
}
message UpdateWorkflowExecutionsMetricsRequest {
string namespace = 1;
string uid = 2;
repeated Metric metrics = 4;
}
message WorkflowExecutionsMetricsResponse {
repeated Metric metrics = 4;
}

View File

@@ -460,11 +460,12 @@ type ListWorkflowTemplatesResponse struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Count int32 `protobuf:"varint,1,opt,name=count,proto3" json:"count,omitempty"`
WorkflowTemplates []*WorkflowTemplate `protobuf:"bytes,2,rep,name=workflowTemplates,proto3" json:"workflowTemplates,omitempty"`
Page int32 `protobuf:"varint,3,opt,name=page,proto3" json:"page,omitempty"`
Pages int32 `protobuf:"varint,4,opt,name=pages,proto3" json:"pages,omitempty"`
TotalCount int32 `protobuf:"varint,5,opt,name=totalCount,proto3" json:"totalCount,omitempty"`
Count int32 `protobuf:"varint,1,opt,name=count,proto3" json:"count,omitempty"`
WorkflowTemplates []*WorkflowTemplate `protobuf:"bytes,2,rep,name=workflowTemplates,proto3" json:"workflowTemplates,omitempty"`
Page int32 `protobuf:"varint,3,opt,name=page,proto3" json:"page,omitempty"`
Pages int32 `protobuf:"varint,4,opt,name=pages,proto3" json:"pages,omitempty"`
TotalCount int32 `protobuf:"varint,5,opt,name=totalCount,proto3" json:"totalCount,omitempty"`
TotalAvailableCount int32 `protobuf:"varint,6,opt,name=totalAvailableCount,proto3" json:"totalAvailableCount,omitempty"`
}
func (x *ListWorkflowTemplatesResponse) Reset() {
@@ -534,6 +535,13 @@ func (x *ListWorkflowTemplatesResponse) GetTotalCount() int32 {
return 0
}
func (x *ListWorkflowTemplatesResponse) GetTotalAvailableCount() int32 {
if x != nil {
return x.TotalAvailableCount
}
return 0
}
type ArchiveWorkflowTemplateRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -1037,7 +1045,7 @@ var file_workflow_template_proto_rawDesc = []byte{
0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65,
0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04,
0x70, 0x61, 0x67, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x04,
0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x22, 0xc4, 0x01, 0x0a,
0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x22, 0xf6, 0x01, 0x0a,
0x1d, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d,
0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14,
0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x63,
@@ -1050,156 +1058,159 @@ var file_workflow_template_proto_rawDesc = []byte{
0x05, 0x70, 0x61, 0x67, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x70, 0x61,
0x67, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x43, 0x6f, 0x75, 0x6e,
0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x43, 0x6f,
0x75, 0x6e, 0x74, 0x22, 0x50, 0x0a, 0x1e, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x57, 0x6f,
0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61,
0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70,
0x61, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
0x52, 0x03, 0x75, 0x69, 0x64, 0x22, 0x64, 0x0a, 0x1f, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65,
0x75, 0x6e, 0x74, 0x12, 0x30, 0x0a, 0x13, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x41, 0x76, 0x61, 0x69,
0x6c, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05,
0x52, 0x13, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65,
0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x50, 0x0a, 0x1e, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65,
0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x10, 0x77, 0x6f, 0x72, 0x6b,
0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f,
0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x10, 0x77, 0x6f, 0x72, 0x6b, 0x66,
0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x22, 0xcc, 0x01, 0x0a, 0x20,
0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f,
0x6e, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74,
0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52,
0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x22, 0x0a, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x45, 0x78,
0x65, 0x63, 0x75, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6c, 0x61,
0x73, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x75,
0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x72, 0x75, 0x6e,
0x6e, 0x69, 0x6e, 0x67, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65,
0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74,
0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01,
0x28, 0x05, 0x52, 0x06, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x65,
0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a,
0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x22, 0x34, 0x0a, 0x1c, 0x43, 0x72,
0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73,
0x74, 0x69, 0x63, 0x73, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f,
0x74, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c,
0x22, 0xd9, 0x03, 0x0a, 0x10, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d,
0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64,
0x41, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65,
0x64, 0x41, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x41,
0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65,
0x64, 0x41, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20,
0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72,
0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73,
0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18,
0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12,
0x1a, 0x0a, 0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28,
0x09, 0x52, 0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x69,
0x73, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x69,
0x73, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x69, 0x73, 0x41, 0x72, 0x63,
0x68, 0x69, 0x76, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x73, 0x41,
0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c,
0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4b, 0x65,
0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x3b,
0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e,
0x61, 0x70, 0x69, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x45, 0x78, 0x65, 0x63,
0x75, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x52, 0x65,
0x70, 0x6f, 0x72, 0x74, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x12, 0x3f, 0x0a, 0x09, 0x63,
0x72, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21,
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f,
0x77, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x52, 0x65, 0x70, 0x6f, 0x72,
0x74, 0x52, 0x09, 0x63, 0x72, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x2e, 0x0a, 0x0a,
0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b,
0x32, 0x0e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72,
0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x22, 0x6e, 0x0a, 0x20,
0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c,
0x61, 0x74, 0x65, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12,
0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,
0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20,
0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x32, 0xbb, 0x0a, 0x0a,
0x17, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74,
0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x9b, 0x01, 0x0a, 0x16, 0x43, 0x72, 0x65,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73,
0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65,
0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01,
0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x22, 0x64, 0x0a, 0x1f, 0x41, 0x72, 0x63, 0x68, 0x69,
0x76, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61,
0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x10, 0x77, 0x6f,
0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x01,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66,
0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x10, 0x77, 0x6f, 0x72,
0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x22, 0xcc, 0x01,
0x0a, 0x20, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74,
0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x52, 0x65, 0x70, 0x6f,
0x72, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28,
0x05, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x22, 0x0a, 0x0c, 0x6c, 0x61, 0x73, 0x74,
0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c,
0x6c, 0x61, 0x73, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07,
0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x72,
0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65,
0x74, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6c,
0x65, 0x74, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x18, 0x05,
0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x1e, 0x0a, 0x0a,
0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05,
0x52, 0x0a, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x22, 0x34, 0x0a, 0x1c,
0x43, 0x72, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74,
0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x14, 0x0a, 0x05,
0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x74, 0x6f, 0x74,
0x61, 0x6c, 0x22, 0xd9, 0x03, 0x0a, 0x10, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54,
0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74,
0x65, 0x64, 0x41, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61,
0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65,
0x64, 0x41, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x6f, 0x64, 0x69, 0x66,
0x69, 0x65, 0x64, 0x41, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01,
0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18,
0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76,
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65,
0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
0x73, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x18, 0x07, 0x20,
0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a,
0x08, 0x69, 0x73, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52,
0x08, 0x69, 0x73, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x69, 0x73, 0x41,
0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69,
0x73, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x6c, 0x61, 0x62,
0x65, 0x6c, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x61, 0x70, 0x69, 0x2e,
0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73,
0x12, 0x3b, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x25, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x45, 0x78,
0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63,
0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x12, 0x3f, 0x0a,
0x09, 0x63, 0x72, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x21, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66,
0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x52, 0x65, 0x70,
0x6f, 0x72, 0x74, 0x52, 0x09, 0x63, 0x72, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x2e,
0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x0d, 0x20, 0x03,
0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74,
0x65, 0x72, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x22, 0x6e,
0x0a, 0x20, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d,
0x70, 0x6c, 0x61, 0x74, 0x65, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65,
0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18,
0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x32, 0xbb,
0x0a, 0x0a, 0x17, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c,
0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x9b, 0x01, 0x0a, 0x16, 0x43,
0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d,
0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x22, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61,
0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61,
0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e,
0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65,
0x22, 0x46, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x40, 0x22, 0x2c, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f,
0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61,
0x63, 0x65, 0x7d, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x74, 0x65, 0x6d,
0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x3a, 0x10, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77,
0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0xc2, 0x01, 0x0a, 0x1d, 0x43, 0x72, 0x65,
0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c,
0x61, 0x74, 0x65, 0x12, 0x22, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x57, 0x6f,
0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x22, 0x46,
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x40, 0x22, 0x2c, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31,
0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x2e, 0x61, 0x70, 0x69,
0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54,
0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15,
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d,
0x70, 0x6c, 0x61, 0x74, 0x65, 0x22, 0x66, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x60, 0x22, 0x4c, 0x2f,
0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x7b, 0x6e, 0x61,
0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f,
0x77, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x77, 0x6f, 0x72,
0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x2e, 0x75, 0x69,
0x64, 0x7d, 0x2f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x10, 0x77, 0x6f, 0x72,
0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0xd3, 0x01,
0x0a, 0x13, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d,
0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x57,
0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x57, 0x6f, 0x72,
0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x22, 0x83, 0x01,
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x7d, 0x12, 0x32, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31,
0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65,
0x7d, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c,
0x61, 0x74, 0x65, 0x73, 0x3a, 0x10, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65,
0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0xc2, 0x01, 0x0a, 0x1d, 0x43, 0x72, 0x65, 0x61, 0x74,
0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74,
0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43,
0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d,
0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x61,
0x70, 0x69, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c,
0x61, 0x74, 0x65, 0x22, 0x66, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x60, 0x22, 0x4c, 0x2f, 0x61, 0x70,
0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65,
0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f,
0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x77, 0x6f, 0x72, 0x6b, 0x66,
0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x2e, 0x75, 0x69, 0x64, 0x7d,
0x2f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x10, 0x77, 0x6f, 0x72, 0x6b, 0x66,
0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0xd3, 0x01, 0x0a, 0x13,
0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c,
0x61, 0x74, 0x65, 0x12, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72,
0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66,
0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x22, 0x83, 0x01, 0x82, 0xd3,
0xe4, 0x93, 0x02, 0x7d, 0x12, 0x32, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65,
0x74, 0x61, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0x2f,
0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74,
0x65, 0x73, 0x2f, 0x7b, 0x75, 0x69, 0x64, 0x7d, 0x5a, 0x47, 0x12, 0x45, 0x2f, 0x61, 0x70, 0x69,
0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73,
0x70, 0x61, 0x63, 0x65, 0x7d, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x74,
0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x75, 0x69, 0x64, 0x7d, 0x2f, 0x76,
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
0x7d, 0x12, 0xb8, 0x01, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c,
0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
0x6e, 0x73, 0x12, 0x28, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x6f, 0x72,
0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72,
0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x61,
0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54,
0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x43, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3d, 0x12,
0x3b, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x7b,
0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x66,
0x6c, 0x6f, 0x77, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x75,
0x69, 0x64, 0x7d, 0x2f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x94, 0x01, 0x0a,
0x15, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d,
0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x12, 0x21, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73,
0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74,
0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x61, 0x70, 0x69, 0x2e,
0x4c, 0x69, 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70,
0x6c, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x34, 0x82,
0xd3, 0xe4, 0x93, 0x02, 0x2e, 0x12, 0x2c, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62,
0x65, 0x74, 0x61, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d,
0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61,
0x74, 0x65, 0x73, 0x12, 0xe9, 0x01, 0x0a, 0x15, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x57, 0x6f, 0x72,
0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x21, 0x2e,
0x61, 0x70, 0x69, 0x2e, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f,
0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54,
0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x22, 0x95, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x8e,
0x01, 0x12, 0x3f, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31,
0x61, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x75, 0x69, 0x64, 0x7d, 0x5a, 0x47, 0x12, 0x45, 0x2f, 0x61,
0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d,
0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77,
0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x75, 0x69, 0x64, 0x7d,
0x2f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x76, 0x65, 0x72, 0x73, 0x69,
0x6f, 0x6e, 0x7d, 0x12, 0xb8, 0x01, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b,
0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73,
0x69, 0x6f, 0x6e, 0x73, 0x12, 0x28, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57,
0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x56,
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29,
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f,
0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x43, 0x82, 0xd3, 0xe4, 0x93, 0x02,
0x3d, 0x12, 0x3b, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31,
0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0x2f, 0x77, 0x6f, 0x72,
0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x2f,
0x7b, 0x75, 0x69, 0x64, 0x7d, 0x2f, 0x63, 0x6c, 0x6f, 0x6e, 0x65, 0x2f, 0x7b, 0x6e, 0x61, 0x6d,
0x65, 0x7d, 0x5a, 0x4b, 0x12, 0x49, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65,
0x74, 0x61, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0x2f,
0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74,
0x65, 0x73, 0x2f, 0x7b, 0x75, 0x69, 0x64, 0x7d, 0x2f, 0x63, 0x6c, 0x6f, 0x6e, 0x65, 0x2f, 0x7b,
0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x7b, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x7d, 0x12,
0xa8, 0x01, 0x0a, 0x17, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66,
0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x23, 0x2e, 0x61, 0x70,
0x69, 0x2e, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f,
0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x24, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x57, 0x6f,
0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x42, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3c, 0x1a, 0x3a,
0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x7b, 0x6e,
0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c,
0x6f, 0x77, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x75, 0x69,
0x64, 0x7d, 0x2f, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x33,
0x7b, 0x75, 0x69, 0x64, 0x7d, 0x2f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x94,
0x01, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54,
0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x12, 0x21, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c,
0x69, 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c,
0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x61, 0x70,
0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65,
0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x34, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2e, 0x12, 0x2c, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76,
0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63,
0x65, 0x7d, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x74, 0x65, 0x6d, 0x70,
0x6c, 0x61, 0x74, 0x65, 0x73, 0x12, 0xe9, 0x01, 0x0a, 0x15, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x57,
0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12,
0x21, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66,
0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f,
0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x22, 0x95, 0x01, 0x82, 0xd3, 0xe4, 0x93,
0x02, 0x8e, 0x01, 0x12, 0x3f, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74,
0x61, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0x2f, 0x77,
0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65,
0x73, 0x2f, 0x7b, 0x75, 0x69, 0x64, 0x7d, 0x2f, 0x63, 0x6c, 0x6f, 0x6e, 0x65, 0x2f, 0x7b, 0x6e,
0x61, 0x6d, 0x65, 0x7d, 0x5a, 0x4b, 0x12, 0x49, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31,
0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65,
0x7d, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c,
0x61, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x75, 0x69, 0x64, 0x7d, 0x2f, 0x63, 0x6c, 0x6f, 0x6e, 0x65,
0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x7b, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
0x7d, 0x12, 0xa8, 0x01, 0x0a, 0x17, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x57, 0x6f, 0x72,
0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x23, 0x2e,
0x61, 0x70, 0x69, 0x2e, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66,
0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x24, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65,
0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x42, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3c,
0x1a, 0x3a, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f,
0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0x2f, 0x77, 0x6f, 0x72, 0x6b,
0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x2f, 0x7b,
0x75, 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x62, 0x06, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x33,
}
var (

View File

@@ -105,6 +105,7 @@ message ListWorkflowTemplatesResponse {
int32 page = 3;
int32 pages = 4;
int32 totalCount = 5;
int32 totalAvailableCount = 6;
}
message ArchiveWorkflowTemplateRequest {

View File

@@ -675,11 +675,12 @@ type ListWorkspaceResponse struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Count int32 `protobuf:"varint,1,opt,name=count,proto3" json:"count,omitempty"`
Workspaces []*Workspace `protobuf:"bytes,2,rep,name=workspaces,proto3" json:"workspaces,omitempty"`
Page int32 `protobuf:"varint,3,opt,name=page,proto3" json:"page,omitempty"`
Pages int32 `protobuf:"varint,4,opt,name=pages,proto3" json:"pages,omitempty"`
TotalCount int32 `protobuf:"varint,5,opt,name=totalCount,proto3" json:"totalCount,omitempty"`
Count int32 `protobuf:"varint,1,opt,name=count,proto3" json:"count,omitempty"`
Workspaces []*Workspace `protobuf:"bytes,2,rep,name=workspaces,proto3" json:"workspaces,omitempty"`
Page int32 `protobuf:"varint,3,opt,name=page,proto3" json:"page,omitempty"`
Pages int32 `protobuf:"varint,4,opt,name=pages,proto3" json:"pages,omitempty"`
TotalCount int32 `protobuf:"varint,5,opt,name=totalCount,proto3" json:"totalCount,omitempty"`
TotalAvailableCount int32 `protobuf:"varint,6,opt,name=totalAvailableCount,proto3" json:"totalAvailableCount,omitempty"`
}
func (x *ListWorkspaceResponse) Reset() {
@@ -749,6 +750,13 @@ func (x *ListWorkspaceResponse) GetTotalCount() int32 {
return 0
}
func (x *ListWorkspaceResponse) GetTotalAvailableCount() int32 {
if x != nil {
return x.TotalAvailableCount
}
return 0
}
type PauseWorkspaceRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -1324,7 +1332,7 @@ var file_workspace_proto_rawDesc = []byte{
0x72, 0x64, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x05,
0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x14, 0x0a, 0x05,
0x70, 0x68, 0x61, 0x73, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x70, 0x68, 0x61,
0x73, 0x65, 0x22, 0xa7, 0x01, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73,
0x73, 0x65, 0x22, 0xd9, 0x01, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73,
0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05,
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x63, 0x6f, 0x75,
0x6e, 0x74, 0x12, 0x2e, 0x0a, 0x0a, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73,
@@ -1334,155 +1342,158 @@ var file_workspace_proto_rawDesc = []byte{
0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x61, 0x67, 0x65, 0x73, 0x18,
0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x70, 0x61, 0x67, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a,
0x74, 0x6f, 0x74, 0x61, 0x6c, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05,
0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x47, 0x0a, 0x15,
0x50, 0x61, 0x75, 0x73, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61,
0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70,
0x61, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
0x52, 0x03, 0x75, 0x69, 0x64, 0x22, 0x48, 0x0a, 0x16, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x57,
0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x10, 0x0a,
0x03, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x22,
0x48, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61,
0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d,
0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61,
0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x02,
0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x22, 0x4d, 0x0a, 0x1b, 0x52, 0x65, 0x74,
0x72, 0x79, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63,
0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x30, 0x0a, 0x13,
0x74, 0x6f, 0x74, 0x61, 0x6c, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f,
0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x13, 0x74, 0x6f, 0x74, 0x61, 0x6c,
0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x47,
0x0a, 0x15, 0x50, 0x61, 0x75, 0x73, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73,
0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65,
0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01,
0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x22, 0x48, 0x0a, 0x16, 0x52, 0x65, 0x73, 0x75, 0x6d,
0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12,
0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69,
0x64, 0x22, 0x48, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73,
0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6e,
0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09,
0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64,
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x22, 0x4d, 0x0a, 0x1b, 0x52,
0x65, 0x74, 0x72, 0x79, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70,
0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61,
0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e,
0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18,
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x22, 0xfe, 0x03, 0x0a, 0x18, 0x57,
0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69,
0x63, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c,
0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x20, 0x0a,
0x0b, 0x6c, 0x61, 0x73, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01,
0x28, 0x09, 0x52, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x12,
0x1c, 0x0a, 0x09, 0x6c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01,
0x28, 0x05, 0x52, 0x09, 0x6c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x12, 0x18, 0x0a,
0x07, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07,
0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x70, 0x64, 0x61, 0x74,
0x69, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x75, 0x70, 0x64, 0x61, 0x74,
0x69, 0x6e, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x18, 0x06,
0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x70, 0x61, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x12, 0x16, 0x0a,
0x06, 0x70, 0x61, 0x75, 0x73, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x70,
0x61, 0x75, 0x73, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61,
0x74, 0x69, 0x6e, 0x67, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x74, 0x65, 0x72, 0x6d,
0x69, 0x6e, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x65, 0x72, 0x6d, 0x69,
0x6e, 0x61, 0x74, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x74, 0x65, 0x72,
0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x66, 0x61, 0x69, 0x6c, 0x65,
0x64, 0x54, 0x6f, 0x50, 0x61, 0x75, 0x73, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d,
0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x54, 0x6f, 0x50, 0x61, 0x75, 0x73, 0x65, 0x12, 0x26, 0x0a,
0x0e, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x54, 0x6f, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x18,
0x0b, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x54, 0x6f, 0x52,
0x65, 0x73, 0x75, 0x6d, 0x65, 0x12, 0x2c, 0x0a, 0x11, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x54,
0x6f, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x05,
0x52, 0x11, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x54, 0x6f, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e,
0x61, 0x74, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x54, 0x6f, 0x4c,
0x61, 0x75, 0x6e, 0x63, 0x68, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x66, 0x61, 0x69,
0x6c, 0x65, 0x64, 0x54, 0x6f, 0x4c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x12, 0x26, 0x0a, 0x0e, 0x66,
0x61, 0x69, 0x6c, 0x65, 0x64, 0x54, 0x6f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x0e, 0x20,
0x01, 0x28, 0x05, 0x52, 0x0e, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x54, 0x6f, 0x55, 0x70, 0x64,
0x61, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x18, 0x0f, 0x20,
0x01, 0x28, 0x05, 0x52, 0x06, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x22, 0x49, 0x0a, 0x29, 0x47,
0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x69,
0x73, 0x74, 0x69, 0x63, 0x73, 0x46, 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63,
0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65,
0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d,
0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20,
0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x22, 0xfe, 0x03, 0x0a, 0x18, 0x57, 0x6f, 0x72,
0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x52,
0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x01,
0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x20, 0x0a, 0x0b, 0x6c,
0x61, 0x73, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
0x52, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x12, 0x1c, 0x0a,
0x09, 0x6c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05,
0x52, 0x09, 0x6c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x72,
0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x72, 0x75,
0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x70, 0x64, 0x61, 0x74, 0x69, 0x6e,
0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x75, 0x70, 0x64, 0x61, 0x74, 0x69, 0x6e,
0x67, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x18, 0x06, 0x20, 0x01,
0x28, 0x05, 0x52, 0x07, 0x70, 0x61, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x70,
0x61, 0x75, 0x73, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x70, 0x61, 0x75,
0x73, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x69,
0x6e, 0x67, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e,
0x61, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61,
0x74, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x74, 0x65, 0x72, 0x6d, 0x69,
0x6e, 0x61, 0x74, 0x65, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x54,
0x6f, 0x50, 0x61, 0x75, 0x73, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x66, 0x61,
0x69, 0x6c, 0x65, 0x64, 0x54, 0x6f, 0x50, 0x61, 0x75, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x66,
0x61, 0x69, 0x6c, 0x65, 0x64, 0x54, 0x6f, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x18, 0x0b, 0x20,
0x01, 0x28, 0x05, 0x52, 0x0e, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x54, 0x6f, 0x52, 0x65, 0x73,
0x75, 0x6d, 0x65, 0x12, 0x2c, 0x0a, 0x11, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x54, 0x6f, 0x54,
0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11,
0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x54, 0x6f, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74,
0x65, 0x12, 0x26, 0x0a, 0x0e, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x54, 0x6f, 0x4c, 0x61, 0x75,
0x6e, 0x63, 0x68, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x66, 0x61, 0x69, 0x6c, 0x65,
0x64, 0x54, 0x6f, 0x4c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x12, 0x26, 0x0a, 0x0e, 0x66, 0x61, 0x69,
0x6c, 0x65, 0x64, 0x54, 0x6f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28,
0x05, 0x52, 0x0e, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x54, 0x6f, 0x55, 0x70, 0x64, 0x61, 0x74,
0x65, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x18, 0x0f, 0x20, 0x01, 0x28,
0x05, 0x52, 0x06, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x22, 0x49, 0x0a, 0x29, 0x47, 0x65, 0x74,
0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74,
0x69, 0x63, 0x73, 0x46, 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70,
0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73,
0x70, 0x61, 0x63, 0x65, 0x22, 0x61, 0x0a, 0x2a, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73,
0x70, 0x61, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x46, 0x6f,
0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x12, 0x33, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63,
0x65, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74,
0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x32, 0xd7, 0x0a, 0x0a, 0x10, 0x57, 0x6f, 0x72, 0x6b,
0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x72, 0x0a, 0x0f,
0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12,
0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b,
0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x61, 0x0a, 0x2a, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72,
0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73,
0x46, 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70,
0x61, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x52, 0x65, 0x70, 0x6f,
0x72, 0x74, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x32, 0xd7, 0x0a, 0x0a, 0x10, 0x57, 0x6f,
0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x72,
0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63,
0x65, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x6f,
0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0e,
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x32,
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x22, 0x24, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31,
0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65,
0x7d, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x3a, 0x04, 0x62, 0x6f,
0x64, 0x79, 0x12, 0xbd, 0x01, 0x0a, 0x22, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70,
0x61, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x46, 0x6f, 0x72,
0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x2e, 0x2e, 0x61, 0x70, 0x69, 0x2e,
0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74,
0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x46, 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61,
0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x61, 0x70, 0x69, 0x2e,
0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74,
0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x46, 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61,
0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x36, 0x82, 0xd3, 0xe4, 0x93,
0x02, 0x30, 0x12, 0x2e, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61,
0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0x2f, 0x77, 0x6f,
0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69,
0x63, 0x73, 0x12, 0x6c, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61,
0x63, 0x65, 0x12, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b,
0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x61,
0x70, 0x69, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x32, 0x82, 0xd3,
0xe4, 0x93, 0x02, 0x2c, 0x22, 0x24, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65,
0x74, 0x61, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0x2f,
0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x3a, 0x04, 0x62, 0x6f, 0x64, 0x79,
0x12, 0xbd, 0x01, 0x0a, 0x22, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63,
0x65, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x46, 0x6f, 0x72, 0x4e, 0x61,
0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x2e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65,
0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73,
0x74, 0x69, 0x63, 0x73, 0x46, 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65,
0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73,
0x74, 0x69, 0x63, 0x73, 0x46, 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x36, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x30,
0x12, 0x2e, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f,
0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0x2f, 0x77, 0x6f, 0x72, 0x6b,
0x73, 0x70, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73,
0x12, 0x6c, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65,
0x12, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70,
0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x61, 0x70, 0x69,
0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x32, 0x82, 0xd3, 0xe4, 0x93,
0x02, 0x2c, 0x12, 0x2a, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61,
0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0x2f, 0x77, 0x6f,
0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x75, 0x69, 0x64, 0x7d, 0x12, 0x75,
0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73,
0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73,
0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x61, 0x70,
0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x12,
0x24, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x7b,
0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x73,
0x70, 0x61, 0x63, 0x65, 0x73, 0x12, 0x95, 0x01, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12,
0x21, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b,
0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x41, 0x82, 0xd3, 0xe4, 0x93,
0x02, 0x3b, 0x1a, 0x31, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61,
0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0x2f, 0x77, 0x6f,
0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x75, 0x69, 0x64, 0x7d, 0x2f, 0x73,
0x74, 0x61, 0x74, 0x75, 0x73, 0x3a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x80, 0x01,
0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63,
0x65, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x6f,
0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16,
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x38, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x32, 0x1a, 0x2a,
0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x7b, 0x6e,
0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70,
0x61, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x75, 0x69, 0x64, 0x7d, 0x3a, 0x04, 0x62, 0x6f, 0x64, 0x79,
0x12, 0x7e, 0x0a, 0x0e, 0x50, 0x61, 0x75, 0x73, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61,
0x63, 0x65, 0x12, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x50, 0x61, 0x75, 0x73, 0x65, 0x57, 0x6f,
0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16,
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x38, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x32, 0x1a, 0x30,
0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x7b, 0x6e,
0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70,
0x61, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x75, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x61, 0x75, 0x73, 0x65,
0x12, 0x81, 0x01, 0x0a, 0x0f, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73,
0x70, 0x61, 0x63, 0x65, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6d,
0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x39, 0x82, 0xd3, 0xe4, 0x93, 0x02,
0x33, 0x1a, 0x31, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31,
0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0x2f, 0x77, 0x6f, 0x72,
0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x75, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65,
0x73, 0x75, 0x6d, 0x65, 0x12, 0x7a, 0x0a, 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x6f,
0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65,
0x6c, 0x65, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x32, 0x82, 0xd3,
0xe4, 0x93, 0x02, 0x2c, 0x2a, 0x2a, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65,
0xe4, 0x93, 0x02, 0x2c, 0x12, 0x2a, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65,
0x74, 0x61, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0x2f,
0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x75, 0x69, 0x64, 0x7d,
0x12, 0x8e, 0x01, 0x0a, 0x18, 0x52, 0x65, 0x74, 0x72, 0x79, 0x4c, 0x61, 0x73, 0x74, 0x57, 0x6f,
0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x2e,
0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x74, 0x72, 0x79, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x57,
0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x38, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x32, 0x1a,
0x30, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x7b,
0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x73,
0x70, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x75, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x74, 0x72,
0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x12, 0x75, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63,
0x65, 0x73, 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x6f, 0x72,
0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e,
0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63,
0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0x82, 0xd3, 0xe4, 0x93, 0x02,
0x26, 0x12, 0x24, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31,
0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0x2f, 0x77, 0x6f, 0x72,
0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x12, 0x95, 0x01, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61,
0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75,
0x73, 0x12, 0x21, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x6f,
0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x41, 0x82, 0xd3,
0xe4, 0x93, 0x02, 0x3b, 0x1a, 0x31, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65,
0x74, 0x61, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0x2f,
0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x75, 0x69, 0x64, 0x7d,
0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12,
0x80, 0x01, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70,
0x61, 0x63, 0x65, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x38, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x32,
0x1a, 0x2a, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f,
0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0x2f, 0x77, 0x6f, 0x72, 0x6b,
0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x75, 0x69, 0x64, 0x7d, 0x3a, 0x04, 0x62, 0x6f,
0x64, 0x79, 0x12, 0x7e, 0x0a, 0x0e, 0x50, 0x61, 0x75, 0x73, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73,
0x70, 0x61, 0x63, 0x65, 0x12, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x50, 0x61, 0x75, 0x73, 0x65,
0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x38, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x32,
0x1a, 0x30, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f,
0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0x2f, 0x77, 0x6f, 0x72, 0x6b,
0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x75, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x61, 0x75,
0x73, 0x65, 0x12, 0x81, 0x01, 0x0a, 0x0f, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x57, 0x6f, 0x72,
0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73,
0x75, 0x6d, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x39, 0x82, 0xd3, 0xe4,
0x93, 0x02, 0x33, 0x1a, 0x31, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74,
0x61, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0x2f, 0x77,
0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x75, 0x69, 0x64, 0x7d, 0x2f,
0x72, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x12, 0x7a, 0x0a, 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e,
0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x32,
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x2a, 0x2a, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31,
0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65,
0x7d, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x75, 0x69,
0x64, 0x7d, 0x12, 0x8e, 0x01, 0x0a, 0x18, 0x52, 0x65, 0x74, 0x72, 0x79, 0x4c, 0x61, 0x73, 0x74,
0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12,
0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x74, 0x72, 0x79, 0x41, 0x63, 0x74, 0x69, 0x6f,
0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x38, 0x82, 0xd3, 0xe4, 0x93, 0x02,
0x32, 0x1a, 0x30, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31,
0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x7d, 0x2f, 0x77, 0x6f, 0x72,
0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x75, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65,
0x74, 0x72, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (

View File

@@ -144,6 +144,7 @@ message ListWorkspaceResponse {
int32 page = 3;
int32 pages = 4;
int32 totalCount = 5;
int32 totalAvailableCount = 6;
}
message PauseWorkspaceRequest {

View File

@@ -37,7 +37,7 @@ const maskRCNNWorkflowTemplate = `arguments:
- name: sys-num-classes
displayName: Number of classes
hint: Number of classes (i.e in CVAT taks) + 1 for background
value: 81
value: '81'
visibility: private
- name: extras
@@ -265,7 +265,7 @@ const tensorflowObjectDetectionWorkflowTemplate = `arguments:
visibility: public
- name: sys-num-classes
value: 81
value: '81'
hint: Number of classes
displayName: Number of classes
visibility: private

View File

@@ -35,7 +35,7 @@ const maskRCNNTemplate2 = `arguments:
- name: cvat-num-classes
displayName: Number of classes
hint: Number of classes (i.e in CVAT taks) + 1 for background
value: 81
value: '81'
visibility: private
- name: hyperparameters

View File

@@ -73,7 +73,7 @@ const tensorflowObjectDetectionTraining2 = `arguments:
visibility: public
- name: cvat-num-classes
value: 81
value: '81'
hint: Number of classes
displayName: Number of classes
visibility: private

View File

@@ -2,7 +2,6 @@ package migration
import (
"database/sql"
v1 "github.com/onepanelio/core/pkg"
uid2 "github.com/onepanelio/core/pkg/util/uid"
"github.com/pressly/goose"
)
@@ -103,13 +102,7 @@ func Up20200929153931(tx *sql.Tx) error {
return err
}
for _, namespace := range namespaces {
workspaceTemplate := &v1.WorkspaceTemplate{
UID: uid,
Name: jupyterLabTemplateName,
Manifest: jupyterWorkspaceTemplate3,
}
if _, err := client.UpdateWorkspaceTemplate(namespace.Name, workspaceTemplate); err != nil {
if _, err := client.UpdateWorkspaceTemplateManifest(namespace.Name, uid, jupyterWorkspaceTemplate3); err != nil {
return err
}
}
@@ -144,14 +137,9 @@ func Down20200929153931(tx *sql.Tx) error {
if err != nil {
return err
}
workspaceTemplate := &v1.WorkspaceTemplate{
UID: uid,
Name: jupyterLabTemplateName,
Manifest: jupyterWorkspaceTemplate2,
}
for _, namespace := range namespaces {
if _, err := client.UpdateWorkspaceTemplate(namespace.Name, workspaceTemplate); err != nil {
if _, err := client.UpdateWorkspaceTemplateManifest(namespace.Name, uid, jupyterWorkspaceTemplate2); err != nil {
return err
}
}

View File

@@ -0,0 +1,28 @@
package migration
import (
"database/sql"
"github.com/pressly/goose"
"path/filepath"
)
func initialize20201016170415() {
if _, ok := initializedMigrations[20201016170415]; !ok {
goose.AddMigration(Up20201016170415, Down20201016170415)
initializedMigrations[20201016170415] = true
}
}
// Up20201016170415 updates cvat to a new version
func Up20201016170415(tx *sql.Tx) error {
// This code is executed when the migration is applied.
return updateWorkspaceTemplateManifest(
filepath.Join("cvat", "20201016170415.yaml"),
cvatTemplateName)
}
// Down20201016170415 does nothing
func Down20201016170415(tx *sql.Tx) error {
// This code is executed when the migration is rolled back.
return nil
}

View File

@@ -0,0 +1,29 @@
package migration
import (
"database/sql"
"github.com/pressly/goose"
"path/filepath"
)
func initialize20201028145442() {
if _, ok := initializedMigrations[20201028145442]; !ok {
goose.AddMigration(Up20201028145442, Down20201028145442)
initializedMigrations[20201028145442] = true
}
}
// Up20201028145442 updates the jupyterlab workspace to include container lifecycle hooks.
// These hooks will attempt to persist conda, pip, and jupyterlab extensions between pause and shut-down.
func Up20201028145442(tx *sql.Tx) error {
// This code is executed when the migration is applied.
return updateWorkspaceTemplateManifest(
filepath.Join("jupyterlab", "20201028145442.yaml"),
jupyterLabTemplateName)
}
// Down20201028145442 removes the lifecycle hooks from the template.
func Down20201028145442(tx *sql.Tx) error {
// This code is executed when the migration is rolled back.
return nil
}

View File

@@ -0,0 +1,33 @@
package migration
import (
"database/sql"
"github.com/pressly/goose"
"path/filepath"
)
func initialize20201028145443() {
if _, ok := initializedMigrations[20201028145443]; !ok {
goose.AddMigration(Up20201028145443, Down20201028145443)
initializedMigrations[20201028145443] = true
}
}
// Up20201028145443 migration will add lifecycle hooks to VSCode template.
// These hooks will attempt to export the conda, pip, and vscode packages that are installed,
// to a text file.
// On workspace resume / start, the code then tries to install these packages.
func Up20201028145443(tx *sql.Tx) error {
// This code is executed when the migration is applied.
return updateWorkspaceTemplateManifest(
filepath.Join("vscode", "20201028145443.yaml"),
vscodeWorkspaceTemplateName)
}
// Down20201028145443 removes the lifecycle hooks from VSCode workspace template.
func Down20201028145443(tx *sql.Tx) error {
// This code is executed when the migration is rolled back.
return updateWorkspaceTemplateManifest(
filepath.Join("vscode", "20201028145443.yaml"),
vscodeWorkspaceTemplateName)
}

View File

@@ -0,0 +1,31 @@
package migration
import (
"database/sql"
"github.com/pressly/goose"
"path/filepath"
)
func initialize20201031165106() {
if _, ok := initializedMigrations[20201031165106]; !ok {
goose.AddMigration(Up20201031165106, Down20201031165106)
initializedMigrations[20201031165106] = true
}
}
// Up20201031165106 updates the jupyterlab workspace to include container lifecycle hooks.
// These hooks will attempt to persist conda, pip, and jupyterlab extensions between pause and shut-down.
func Up20201031165106(tx *sql.Tx) error {
// This code is executed when the migration is applied.
return updateWorkspaceTemplateManifest(
filepath.Join("jupyterlab", "20201031165106.yaml"),
jupyterLabTemplateName)
}
// Down20201031165106 removes the lifecycle hooks from the template.
func Down20201031165106(tx *sql.Tx) error {
// This code is executed when the migration is rolled back.
return updateWorkspaceTemplateManifest(
filepath.Join("jupyterlab", "20201028145442.yaml"),
jupyterLabTemplateName)
}

View File

@@ -0,0 +1,32 @@
package migration
import (
"database/sql"
"github.com/pressly/goose"
"path/filepath"
)
func initialize20201102104048() {
if _, ok := initializedMigrations[20201102104048]; !ok {
goose.AddMigration(Up20201102104048, Down20201102104048)
initializedMigrations[20201102104048] = true
}
}
// Up20201102104048 updates CVAT to use less volumes.
// Through the use of environment variables, various CVAT data directories
// are placed under one path, and that path is on one volume.
func Up20201102104048(tx *sql.Tx) error {
// This code is executed when the migration is applied.
return updateWorkspaceTemplateManifest(
filepath.Join("cvat", "20201102104048.yaml"),
cvatTemplateName)
}
// Down20201102104048 reverts CVAT back to original amount of volumes.
func Down20201102104048(tx *sql.Tx) error {
// This code is executed when the migration is rolled back.
return updateWorkspaceTemplateManifest(
filepath.Join("cvat", "20201016170415.yaml"),
cvatTemplateName)
}

View File

@@ -0,0 +1,31 @@
package migration
import (
"database/sql"
"github.com/pressly/goose"
"path/filepath"
)
func initialize20201113094916() {
if _, ok := initializedMigrations[20201113094916]; !ok {
goose.AddMigration(Up20201113094916, Down20201113094916)
initializedMigrations[20201113094916] = true
}
}
//Up20201113094916 updates CVAT with python-sdk 0.15.0
//Of note, this replaces the authentication request endpoint.
func Up20201113094916(tx *sql.Tx) error {
// This code is executed when the migration is applied.
return updateWorkspaceTemplateManifest(
filepath.Join("cvat", "20201113094916.yaml"),
cvatTemplateName)
}
//Down20201113094916 updates CVAT back to previous python-sdk version of 0.14.0
func Down20201113094916(tx *sql.Tx) error {
// This code is executed when the migration is rolled back.
return updateWorkspaceTemplateManifest(
filepath.Join("cvat", "20201102104048.yaml"),
cvatTemplateName)
}

View File

@@ -0,0 +1,30 @@
package migration
import (
"database/sql"
"github.com/pressly/goose"
"path/filepath"
)
func initialize20201115133046() {
if _, ok := initializedMigrations[20201115133046]; !ok {
goose.AddMigration(Up20201115133046, Down20201115133046)
initializedMigrations[20201115133046] = true
}
}
//Up20201115133046 updates CVAT environment variables
func Up20201115133046(tx *sql.Tx) error {
// This code is executed when the migration is applied.
return updateWorkspaceTemplateManifest(
filepath.Join("cvat", "20201115133046.yaml"),
cvatTemplateName)
}
//Down20201115133046 reverts latest environment variable updates
func Down20201115133046(tx *sql.Tx) error {
// This code is executed when the migration is rolled back.
return updateWorkspaceTemplateManifest(
filepath.Join("cvat", "20201113094916"),
cvatTemplateName)
}

View File

@@ -0,0 +1,32 @@
package migration
import (
"database/sql"
"github.com/pressly/goose"
"path/filepath"
)
func initialize20201115134934() {
if _, ok := initializedMigrations[20201115134934]; !ok {
goose.AddMigration(Up20201115134934, Down20201115134934)
initializedMigrations[20201115134934] = true
}
}
// Up20201115134934 add TensorBoard sidecar to TFODs
func Up20201115134934(tx *sql.Tx) error {
// This code is executed when the migration is applied.
return updateWorkflowTemplateManifest(
filepath.Join("tfod", "20201115134934.yaml"),
tensorflowObjectDetectionWorkflowTemplateName,
map[string]string{
"used-by": "cvat",
},
)
}
// Down20201115134934 do nothing
func Down20201115134934(tx *sql.Tx) error {
// This code is executed when the migration is rolled back.
return nil
}

View File

@@ -0,0 +1,32 @@
package migration
import (
"database/sql"
"github.com/pressly/goose"
"path/filepath"
)
func initialize20201115145814() {
if _, ok := initializedMigrations[20201115145814]; !ok {
goose.AddMigration(Up20201115145814, Down20201115145814)
initializedMigrations[20201115145814] = true
}
}
// Up20201115145814 add TensorBoard sidecar to TFODs
func Up20201115145814(tx *sql.Tx) error {
// This code is executed when the migration is applied.
return updateWorkflowTemplateManifest(
filepath.Join("maskrcnn", "20201115145814.yaml"),
maskRCNNWorkflowTemplateName,
map[string]string{
"used-by": "cvat",
},
)
}
// Down20201115145814 do nothing
func Down20201115145814(tx *sql.Tx) error {
// This code is executed when the migration is rolled back.
return nil
}

View File

@@ -0,0 +1,38 @@
package migration
import (
"database/sql"
"github.com/pressly/goose"
"path/filepath"
)
func initialize20201130130433() {
if _, ok := initializedMigrations[20201130130433]; !ok {
goose.AddMigration(Up20201130130433, Down20201130130433)
initializedMigrations[20201130130433] = true
}
}
// Up20201130130433 remove namespace to resolve checkpoint path issue
func Up20201130130433(tx *sql.Tx) error {
// This code is executed when the migration is applied.
return updateWorkflowTemplateManifest(
filepath.Join("tfod", "20201130130433.yaml"),
tensorflowObjectDetectionWorkflowTemplateName,
map[string]string{
"used-by": "cvat",
},
)
}
// Down20201130130433 do nothing
func Down20201130130433(tx *sql.Tx) error {
// This code is executed when the migration is rolled back.
return updateWorkflowTemplateManifest(
filepath.Join("tfod", "20201115134934.yaml"),
tensorflowObjectDetectionWorkflowTemplateName,
map[string]string{
"used-by": "cvat",
},
)
}

View File

@@ -0,0 +1,38 @@
package migration
import (
"database/sql"
"github.com/pressly/goose"
"path/filepath"
)
func initialize20201208155115() {
if _, ok := initializedMigrations[20201208155115]; !ok {
goose.AddMigration(Up20201208155115, Down20201208155115)
initializedMigrations[20201208155115] = true
}
}
// Up20201208155115 update the tfod workflow template to replace tty with an environment variable
func Up20201208155115(tx *sql.Tx) error {
// This code is executed when the migration is applied.
return updateWorkflowTemplateManifest(
filepath.Join("tfod", "20201208155115.yaml"),
tensorflowObjectDetectionWorkflowTemplateName,
map[string]string{
"used-by": "cvat",
},
)
}
// Down20201208155115 rolls back the environment variable change
func Down20201208155115(tx *sql.Tx) error {
// This code is executed when the migration is rolled back.
return updateWorkflowTemplateManifest(
filepath.Join("tfod", "20201130130433.yaml"),
tensorflowObjectDetectionWorkflowTemplateName,
map[string]string{
"used-by": "cvat",
},
)
}

View File

@@ -0,0 +1,38 @@
package migration
import (
"database/sql"
"github.com/pressly/goose"
"path/filepath"
)
func initialize20201208155805() {
if _, ok := initializedMigrations[20201208155805]; !ok {
goose.AddMigration(Up20201208155805, Down20201208155805)
initializedMigrations[20201208155805] = true
}
}
// Up20201208155805 update the maskrcnn workflow template to replace tty with an environment variable
func Up20201208155805(tx *sql.Tx) error {
// This code is executed when the migration is applied.
return updateWorkflowTemplateManifest(
filepath.Join("maskrcnn", "20201208155115.yaml"),
maskRCNNWorkflowTemplateName,
map[string]string{
"used-by": "cvat",
},
)
}
// Down20201208155805 rolls back the environment variable change
func Down20201208155805(tx *sql.Tx) error {
// This code is executed when the migration is rolled back.
return updateWorkflowTemplateManifest(
filepath.Join("maskrcnn", "20201115145814.yaml"),
maskRCNNWorkflowTemplateName,
map[string]string{
"used-by": "cvat",
},
)
}

View File

@@ -0,0 +1,38 @@
package migration
import (
"database/sql"
"github.com/pressly/goose"
"path/filepath"
)
func initialize20201209124226() {
if _, ok := initializedMigrations[20201209124226]; !ok {
goose.AddMigration(Up20201209124226, Down20201209124226)
initializedMigrations[20201209124226] = true
}
}
// Up20201209124226 updates the tensorflow workflow
func Up20201209124226(tx *sql.Tx) error {
// This code is executed when the migration is applied.
return updateWorkflowTemplateManifest(
filepath.Join("tf_training", "20201209124226.yaml"),
tensorflowWorkflowTemplateName,
map[string]string{
"framework": "tensorflow",
},
)
}
// Down20201209124226 rolls back the tensorflow workflow
func Down20201209124226(tx *sql.Tx) error {
// This code is executed when the migration is rolled back.
return updateWorkflowTemplateManifest(
filepath.Join("tf_training", "20200605090535.yaml"),
tensorflowWorkflowTemplateName,
map[string]string{
"framework": "tensorflow",
},
)
}

View File

@@ -0,0 +1,30 @@
package migration
import (
"database/sql"
"github.com/pressly/goose"
"path/filepath"
)
func initialize20201211161117() {
if _, ok := initializedMigrations[20201211161117]; !ok {
goose.AddMigration(Up20201211161117, Down20201211161117)
initializedMigrations[20201211161117] = true
}
}
// Up20201211161117 updated cvat workspace template with a new ONEPANEL_MAIN_CONTAINER environment variable
func Up20201211161117(tx *sql.Tx) error {
// This code is executed when the migration is applied.
return updateWorkspaceTemplateManifest(
filepath.Join("cvat", "20201211161117.yaml"),
cvatTemplateName)
}
// Down20201211161117 reverts the cvat workspace update
func Down20201211161117(tx *sql.Tx) error {
// This code is executed when the migration is rolled back.
return updateWorkspaceTemplateManifest(
filepath.Join("cvat", "20201115133046.yaml"),
cvatTemplateName)
}

View File

@@ -0,0 +1,29 @@
package migration
import (
"database/sql"
"github.com/pressly/goose"
"path/filepath"
)
func initialize20201214133458() {
if _, ok := initializedMigrations[20201214133458]; !ok {
goose.AddMigration(Up20201214133458, Down20201214133458)
}
}
// Up20201214133458 fixes an issue where LD_LIBRARY_PATH is not present for JupyterLab
func Up20201214133458(tx *sql.Tx) error {
// This code is executed when the migration is applied.
return updateWorkspaceTemplateManifest(
filepath.Join("jupyterlab", "20201214133458.yaml"),
jupyterLabTemplateName)
}
// Down20201214133458 undoes the change
func Down20201214133458(tx *sql.Tx) error {
// This code is executed when the migration is rolled back.
return updateWorkspaceTemplateManifest(
filepath.Join("jupyterlab", "20201031165106.yaml"),
jupyterLabTemplateName)
}

View File

@@ -5,7 +5,10 @@ import (
sq "github.com/Masterminds/squirrel"
"github.com/jmoiron/sqlx"
v1 "github.com/onepanelio/core/pkg"
"io/ioutil"
"log"
"os"
"path/filepath"
"strings"
)
@@ -60,6 +63,21 @@ func Initialize() {
initialize20200929144301()
initialize20200929153931()
initialize20201001070806()
initialize20201016170415()
initialize20201028145442()
initialize20201028145443()
initialize20201031165106()
initialize20201102104048()
initialize20201113094916()
initialize20201115133046()
initialize20201115134934()
initialize20201115145814()
initialize20201130130433()
initialize20201208155115()
initialize20201208155805()
initialize20201209124226()
initialize20201211161117()
initialize20201214133458()
if err := client.DB.Close(); err != nil {
log.Printf("[error] closing db %v", err)
@@ -128,3 +146,25 @@ func ReplaceArtifactRepositoryType(client *v1.Client, namespace *v1.Namespace, w
return nil
}
// readDataFile returns the contents of a file in the db/data/{path} directory
// path can indicate subdirectories like cvat/20201016170415.yaml
func readDataFile(path string) (string, error) {
curDir, err := os.Getwd()
if err != nil {
return "", err
}
finalPath := []string{curDir, "db", "yaml"}
for _, pathPart := range strings.Split(path, string(os.PathSeparator)) {
finalPath = append(finalPath, pathPart)
}
data, err := ioutil.ReadFile(filepath.Join(finalPath...))
if err != nil {
return "", err
}
return string(data), nil
}

94
db/go/util.go Normal file
View File

@@ -0,0 +1,94 @@
package migration
import (
v1 "github.com/onepanelio/core/pkg"
uid2 "github.com/onepanelio/core/pkg/util/uid"
)
// updateWorkspaceTemplateManifest will update the workspace template given by {{templateName}} with the contents
// given by {{filename}}
// It will do so for all namespaces.
func updateWorkspaceTemplateManifest(filename, templateName string) error {
client, err := getClient()
if err != nil {
return err
}
defer client.DB.Close()
namespaces, err := client.ListOnepanelEnabledNamespaces()
if err != nil {
return err
}
newManifest, err := readDataFile(filename)
if err != nil {
return err
}
uid, err := uid2.GenerateUID(templateName, 30)
if err != nil {
return err
}
for _, namespace := range namespaces {
workspaceTemplate := &v1.WorkspaceTemplate{
UID: uid,
Name: templateName,
Manifest: newManifest,
}
err = ReplaceArtifactRepositoryType(client, namespace, nil, workspaceTemplate)
if err != nil {
return err
}
if _, err := client.UpdateWorkspaceTemplateManifest(namespace.Name, uid, workspaceTemplate.Manifest); err != nil {
return err
}
}
return nil
}
// updateWorkflowTemplateManifest will update the workflow template given by {{templateName}} with the contents
// given by {{filename}}
// It will do so for all namespaces.
func updateWorkflowTemplateManifest(filename, templateName string, labels map[string]string) error {
client, err := getClient()
if err != nil {
return err
}
defer client.DB.Close()
namespaces, err := client.ListOnepanelEnabledNamespaces()
if err != nil {
return err
}
newManifest, err := readDataFile(filename)
if err != nil {
return err
}
uid, err := uid2.GenerateUID(templateName, 30)
if err != nil {
return err
}
for _, namespace := range namespaces {
workflowTemplate := &v1.WorkflowTemplate{
UID: uid,
Name: templateName,
Manifest: newManifest,
Labels: labels,
}
err = ReplaceArtifactRepositoryType(client, namespace, workflowTemplate, nil)
if err != nil {
return err
}
if _, err := client.CreateWorkflowTemplateVersion(namespace.Name, workflowTemplate); err != nil {
return err
}
}
return nil
}

View File

@@ -0,0 +1,24 @@
-- +goose Up
-- SQL in this section is executed when the migration is applied.
UPDATE workflow_executions
SET labels = '{}'::jsonb
WHERE labels = 'null'::jsonb;
UPDATE workflow_templates
SET labels = '{}'::jsonb
WHERE labels = 'null'::jsonb;
UPDATE workspace_templates
SET labels = '{}'::jsonb
WHERE labels = 'null'::jsonb;
UPDATE workflow_template_versions
SET labels = '{}'::jsonb
WHERE labels = 'null'::jsonb;
UPDATE workspace_template_Versions
SET labels = '{}'::jsonb
WHERE labels = 'null'::jsonb;
-- +goose Down
-- SQL in this section is executed when the migration is rolled back.

View File

@@ -0,0 +1,9 @@
-- +goose Up
-- SQL in this section is executed when the migration is applied.
ALTER TABLE workflow_executions ADD COLUMN metrics JSONB;
UPDATE workflow_executions SET metrics = '{}'::JSONB;
ALTER TABLE workflow_executions ALTER COLUMN metrics SET NOT NULL;
-- +goose Down
-- SQL in this section is executed when the migration is rolled back.
ALTER TABLE workflow_executions DROP COLUMN metrics;

View File

@@ -0,0 +1,9 @@
-- +goose Up
-- SQL in this section is executed when the migration is applied.
UPDATE workflow_executions SET metrics = '[]'::JSONB
WHERE metrics = '{}'::JSONB;
-- +goose Down
-- SQL in this section is executed when the migration is rolled back.
UPDATE workflow_executions SET metrics = '{}'::JSONB
WHERE metrics = '[]'::JSONB;

View File

@@ -0,0 +1,147 @@
# Workspace arguments
arguments:
parameters:
- name: sync-directory
displayName: Directory to sync raw input and training output
value: workflow-data
hint: Location to sync raw input, models and checkpoints from default object storage. Note that this will be relative to the current namespace.
containers:
- name: cvat-db
image: postgres:10-alpine
env:
- name: POSTGRES_USER
value: root
- name: POSTGRES_DB
value: cvat
- name: POSTGRES_HOST_AUTH_METHOD
value: trust
- name: PGDATA
value: /var/lib/psql/data
ports:
- containerPort: 5432
name: tcp
volumeMounts:
- name: db
mountPath: /var/lib/psql
- name: cvat-redis
image: redis:4.0-alpine
ports:
- containerPort: 6379
name: tcp
- name: cvat
image: onepanel/cvat:0.14.0_cvat.1.0.0
env:
- name: DJANGO_MODWSGI_EXTRA_ARGS
value: ""
- name: ALLOWED_HOSTS
value: '*'
- name: CVAT_REDIS_HOST
value: localhost
- name: CVAT_POSTGRES_HOST
value: localhost
- name: CVAT_SHARE_URL
value: /home/django/data
- name: ONEPANEL_SYNC_DIRECTORY
value: '{{workspace.parameters.sync-directory}}'
- name: NVIDIA_VISIBLE_DEVICES
value: all
- name: NVIDIA_DRIVER_CAPABILITIES
value: compute,utility
- name: NVIDIA_REQUIRE_CUDA
value: "cuda>=10.0 brand=tesla,driver>=384,driver<385 brand=tesla,driver>=410,driver<411"
ports:
- containerPort: 8080
name: http
volumeMounts:
- name: data
mountPath: /home/django/data
- name: keys
mountPath: /home/django/keys
- name: logs
mountPath: /home/django/logs
- name: models
mountPath: /home/django/models
- name: share
mountPath: /home/django/share
- name: sys-namespace-config
mountPath: /etc/onepanel
readOnly: true
- name: cvat-ui
image: onepanel/cvat-ui:0.14.0_cvat.1.0.0
ports:
- containerPort: 80
name: http
# You can add multiple FileSyncer sidecar containers if needed
- name: filesyncer
image: onepanel/filesyncer:{{.ArtifactRepositoryType}}
imagePullPolicy: Always
args:
- download
- -server-prefix=/sys/filesyncer
env:
- name: FS_PATH
value: /mnt/share
- name: FS_PREFIX
value: '{{workflow.namespace}}/{{workspace.parameters.sync-directory}}'
volumeMounts:
- name: share
mountPath: /mnt/share
- name: sys-namespace-config
mountPath: /etc/onepanel
readOnly: true
ports:
- name: cvat-ui
port: 80
protocol: TCP
targetPort: 80
- name: cvat
port: 8080
protocol: TCP
targetPort: 8080
- name: fs
port: 8888
protocol: TCP
targetPort: 8888
routes:
- match:
- uri:
prefix: /sys/filesyncer
route:
- destination:
port:
number: 8888
- match:
- uri:
regex: /api/.*|/git/.*|/tensorflow/.*|/onepanelio/.*|/tracking/.*|/auto_annotation/.*|/analytics/.*|/static/.*|/admin/.*|/documentation/.*|/dextr/.*|/reid/.*
- queryParams:
id:
regex: \d+.*
route:
- destination:
port:
number: 8080
- match:
- uri:
prefix: /
route:
- destination:
port:
number: 80
# DAG Workflow to be executed once a Workspace action completes (optional)
# Uncomment the lines below if you want to send Slack notifications
#postExecutionWorkflow:
# entrypoint: main
# templates:
# - name: main
# dag:
# tasks:
# - name: slack-notify
# template: slack-notify
# - name: slack-notify
# container:
# image: technosophos/slack-notify
# args:
# - SLACK_USERNAME=onepanel SLACK_TITLE="Your workspace is ready" SLACK_ICON=https://www.gravatar.com/avatar/5c4478592fe00878f62f0027be59c1bd SLACK_MESSAGE="Your workspace is now running" ./slack-notify
# command:
# - sh
# - -c

View File

@@ -0,0 +1,159 @@
# Workspace arguments
arguments:
parameters:
- name: sync-directory
displayName: Directory to sync raw input and training output
value: workflow-data
hint: Location (relative to current namespace) to sync raw input, models and checkpoints from default object storage to '/share'.
containers:
- name: cvat-db
image: postgres:10-alpine
env:
- name: POSTGRES_USER
value: root
- name: POSTGRES_DB
value: cvat
- name: POSTGRES_HOST_AUTH_METHOD
value: trust
- name: PGDATA
value: /var/lib/psql/data
ports:
- containerPort: 5432
name: tcp
volumeMounts:
- name: db
mountPath: /var/lib/psql
- name: cvat-redis
image: redis:4.0-alpine
ports:
- containerPort: 6379
name: tcp
- name: cvat
image: onepanel/cvat:0.15.0_cvat.1.0.0
env:
- name: DJANGO_MODWSGI_EXTRA_ARGS
value: ""
- name: ALLOWED_HOSTS
value: '*'
- name: CVAT_REDIS_HOST
value: localhost
- name: CVAT_POSTGRES_HOST
value: localhost
- name: CVAT_SHARE_URL
value: /cvat/data
- name: CVAT_SHARE_DIR
value: /share
- name: CVAT_KEYS_DIR
value: /cvat/keys
- name: CVAT_DATA_DIR
value: /cvat/data
- name: CVAT_MODELS_DIR
value: /cvat/models
- name: CVAT_LOGS_DIR
value: /cvat/logs
- name: ONEPANEL_SYNC_DIRECTORY
value: '{{workspace.parameters.sync-directory}}'
- name: NVIDIA_VISIBLE_DEVICES
value: all
- name: NVIDIA_DRIVER_CAPABILITIES
value: compute,utility
- name: NVIDIA_REQUIRE_CUDA
value: "cuda>=10.0 brand=tesla,driver>=384,driver<385 brand=tesla,driver>=410,driver<411"
ports:
- containerPort: 8080
name: http
volumeMounts:
- name: cvat-data
mountPath: /cvat
- name: share
mountPath: /share
- name: sys-namespace-config
mountPath: /etc/onepanel
readOnly: true
- name: cvat-ui
image: onepanel/cvat-ui:0.15.0_cvat.1.0.0
ports:
- containerPort: 80
name: http
# You can add multiple FileSyncer sidecar containers if needed
- name: filesyncer
image: onepanel/filesyncer:s3
imagePullPolicy: Always
args:
- download
- -server-prefix=/sys/filesyncer
env:
- name: FS_PATH
value: /mnt/share
- name: FS_PREFIX
value: '{{workflow.namespace}}/{{workspace.parameters.sync-directory}}'
volumeMounts:
- name: share
mountPath: /mnt/share
- name: sys-namespace-config
mountPath: /etc/onepanel
readOnly: true
ports:
- name: cvat-ui
port: 80
protocol: TCP
targetPort: 80
- name: cvat
port: 8080
protocol: TCP
targetPort: 8080
- name: fs
port: 8888
protocol: TCP
targetPort: 8888
routes:
- match:
- uri:
prefix: /sys/filesyncer
route:
- destination:
port:
number: 8888
- match:
- uri:
regex: /api/.*|/git/.*|/tensorflow/.*|/onepanelio/.*|/tracking/.*|/auto_annotation/.*|/analytics/.*|/static/.*|/admin/.*|/documentation/.*|/dextr/.*|/reid/.*
- queryParams:
id:
regex: \d+.*
route:
- destination:
port:
number: 8080
- match:
- uri:
prefix: /
route:
- destination:
port:
number: 80
volumeClaimTemplates:
- metadata:
name: db
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 20Gi
# DAG Workflow to be executed once a Workspace action completes (optional)
# Uncomment the lines below if you want to send Slack notifications
#postExecutionWorkflow:
# entrypoint: main
# templates:
# - name: main
# dag:
# tasks:
# - name: slack-notify
# template: slack-notify
# - name: slack-notify
# container:
# image: technosophos/slack-notify
# args:
# - SLACK_USERNAME=onepanel SLACK_TITLE="Your workspace is ready" SLACK_ICON=https://www.gravatar.com/avatar/5c4478592fe00878f62f0027be59c1bd SLACK_MESSAGE="Your workspace is now running" ./slack-notify
# command:
# - sh
# - -c

View File

@@ -0,0 +1,159 @@
# Workspace arguments
arguments:
parameters:
- name: sync-directory
displayName: Directory to sync raw input and training output
value: workflow-data
hint: Location (relative to current namespace) to sync raw input, models and checkpoints from default object storage to '/share'.
containers:
- name: cvat-db
image: postgres:10-alpine
env:
- name: POSTGRES_USER
value: root
- name: POSTGRES_DB
value: cvat
- name: POSTGRES_HOST_AUTH_METHOD
value: trust
- name: PGDATA
value: /var/lib/psql/data
ports:
- containerPort: 5432
name: tcp
volumeMounts:
- name: db
mountPath: /var/lib/psql
- name: cvat-redis
image: redis:4.0-alpine
ports:
- containerPort: 6379
name: tcp
- name: cvat
image: onepanel/cvat:0.16.0_cvat.1.0.0
env:
- name: DJANGO_MODWSGI_EXTRA_ARGS
value: ""
- name: ALLOWED_HOSTS
value: '*'
- name: CVAT_REDIS_HOST
value: localhost
- name: CVAT_POSTGRES_HOST
value: localhost
- name: CVAT_SHARE_URL
value: /cvat/data
- name: CVAT_SHARE_DIR
value: /share
- name: CVAT_KEYS_DIR
value: /cvat/keys
- name: CVAT_DATA_DIR
value: /cvat/data
- name: CVAT_MODELS_DIR
value: /cvat/models
- name: CVAT_LOGS_DIR
value: /cvat/logs
- name: ONEPANEL_SYNC_DIRECTORY
value: '{{workspace.parameters.sync-directory}}'
- name: NVIDIA_VISIBLE_DEVICES
value: all
- name: NVIDIA_DRIVER_CAPABILITIES
value: compute,utility
- name: NVIDIA_REQUIRE_CUDA
value: "cuda>=10.0 brand=tesla,driver>=384,driver<385 brand=tesla,driver>=410,driver<411"
ports:
- containerPort: 8080
name: http
volumeMounts:
- name: cvat-data
mountPath: /cvat
- name: share
mountPath: /share
- name: sys-namespace-config
mountPath: /etc/onepanel
readOnly: true
- name: cvat-ui
image: onepanel/cvat-ui:0.16.0_cvat.1.0.0
ports:
- containerPort: 80
name: http
# You can add multiple FileSyncer sidecar containers if needed
- name: filesyncer
image: onepanel/filesyncer:s3
imagePullPolicy: Always
args:
- download
- -server-prefix=/sys/filesyncer
env:
- name: FS_PATH
value: /mnt/share
- name: FS_PREFIX
value: '{{workflow.namespace}}/{{workspace.parameters.sync-directory}}'
volumeMounts:
- name: share
mountPath: /mnt/share
- name: sys-namespace-config
mountPath: /etc/onepanel
readOnly: true
ports:
- name: cvat-ui
port: 80
protocol: TCP
targetPort: 80
- name: cvat
port: 8080
protocol: TCP
targetPort: 8080
- name: fs
port: 8888
protocol: TCP
targetPort: 8888
routes:
- match:
- uri:
prefix: /sys/filesyncer
route:
- destination:
port:
number: 8888
- match:
- uri:
regex: /api/.*|/git/.*|/tensorflow/.*|/onepanelio/.*|/tracking/.*|/auto_annotation/.*|/analytics/.*|/static/.*|/admin/.*|/documentation/.*|/dextr/.*|/reid/.*
- queryParams:
id:
regex: \d+.*
route:
- destination:
port:
number: 8080
- match:
- uri:
prefix: /
route:
- destination:
port:
number: 80
volumeClaimTemplates:
- metadata:
name: db
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 20Gi
# DAG Workflow to be executed once a Workspace action completes (optional)
# Uncomment the lines below if you want to send Slack notifications
#postExecutionWorkflow:
# entrypoint: main
# templates:
# - name: main
# dag:
# tasks:
# - name: slack-notify
# template: slack-notify
# - name: slack-notify
# container:
# image: technosophos/slack-notify
# args:
# - SLACK_USERNAME=onepanel SLACK_TITLE="Your workspace is ready" SLACK_ICON=https://www.gravatar.com/avatar/5c4478592fe00878f62f0027be59c1bd SLACK_MESSAGE="Your workspace is now running" ./slack-notify
# command:
# - sh
# - -c

View File

@@ -0,0 +1,161 @@
# Workspace arguments
arguments:
parameters:
- name: sync-directory
displayName: Directory to sync raw input and training output
value: workflow-data
hint: Location (relative to current namespace) to sync raw input, models and checkpoints from default object storage to '/share'.
containers:
- name: cvat-db
image: postgres:10-alpine
env:
- name: POSTGRES_USER
value: root
- name: POSTGRES_DB
value: cvat
- name: POSTGRES_HOST_AUTH_METHOD
value: trust
- name: PGDATA
value: /var/lib/psql/data
ports:
- containerPort: 5432
name: tcp
volumeMounts:
- name: db
mountPath: /var/lib/psql
- name: cvat-redis
image: redis:4.0-alpine
ports:
- containerPort: 6379
name: tcp
- name: cvat
image: onepanel/cvat:0.16.0_cvat.1.0.0
env:
- name: DJANGO_MODWSGI_EXTRA_ARGS
value: ""
- name: ALLOWED_HOSTS
value: '*'
- name: CVAT_REDIS_HOST
value: localhost
- name: CVAT_POSTGRES_HOST
value: localhost
- name: CVAT_SHARE_URL
value: /cvat/data
- name: CVAT_SHARE_DIR
value: /share
- name: CVAT_DATA_DIR
value: /cvat/data
- name: CVAT_MEDIA_DATA_DIR
value: /cvat/data/data
- name: CVAT_KEYS_DIR
value: /cvat/data/keys
- name: CVAT_MODELS_DIR
value: /cvat/data/models
- name: CVAT_LOGS_DIR
value: /cvat/logs
- name: ONEPANEL_SYNC_DIRECTORY
value: '{{workspace.parameters.sync-directory}}'
- name: NVIDIA_VISIBLE_DEVICES
value: all
- name: NVIDIA_DRIVER_CAPABILITIES
value: compute,utility
- name: NVIDIA_REQUIRE_CUDA
value: "cuda>=10.0 brand=tesla,driver>=384,driver<385 brand=tesla,driver>=410,driver<411"
ports:
- containerPort: 8080
name: http
volumeMounts:
- name: cvat-data
mountPath: /cvat
- name: share
mountPath: /share
- name: sys-namespace-config
mountPath: /etc/onepanel
readOnly: true
- name: cvat-ui
image: onepanel/cvat-ui:0.16.0_cvat.1.0.0
ports:
- containerPort: 80
name: http
# You can add multiple FileSyncer sidecar containers if needed
- name: filesyncer
image: onepanel/filesyncer:s3
imagePullPolicy: Always
args:
- download
- -server-prefix=/sys/filesyncer
env:
- name: FS_PATH
value: /mnt/share
- name: FS_PREFIX
value: '{{workflow.namespace}}/{{workspace.parameters.sync-directory}}'
volumeMounts:
- name: share
mountPath: /mnt/share
- name: sys-namespace-config
mountPath: /etc/onepanel
readOnly: true
ports:
- name: cvat-ui
port: 80
protocol: TCP
targetPort: 80
- name: cvat
port: 8080
protocol: TCP
targetPort: 8080
- name: fs
port: 8888
protocol: TCP
targetPort: 8888
routes:
- match:
- uri:
prefix: /sys/filesyncer
route:
- destination:
port:
number: 8888
- match:
- uri:
regex: /api/.*|/git/.*|/tensorflow/.*|/onepanelio/.*|/tracking/.*|/auto_annotation/.*|/analytics/.*|/static/.*|/admin/.*|/documentation/.*|/dextr/.*|/reid/.*
- queryParams:
id:
regex: \d+.*
route:
- destination:
port:
number: 8080
- match:
- uri:
prefix: /
route:
- destination:
port:
number: 80
volumeClaimTemplates:
- metadata:
name: db
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 20Gi
# DAG Workflow to be executed once a Workspace action completes (optional)
# Uncomment the lines below if you want to send Slack notifications
#postExecutionWorkflow:
# entrypoint: main
# templates:
# - name: main
# dag:
# tasks:
# - name: slack-notify
# template: slack-notify
# - name: slack-notify
# container:
# image: technosophos/slack-notify
# args:
# - SLACK_USERNAME=onepanel SLACK_TITLE="Your workspace is ready" SLACK_ICON=https://www.gravatar.com/avatar/5c4478592fe00878f62f0027be59c1bd SLACK_MESSAGE="Your workspace is now running" ./slack-notify
# command:
# - sh
# - -c

View File

@@ -0,0 +1,163 @@
# Workspace arguments
arguments:
parameters:
- name: sync-directory
displayName: Directory to sync raw input and training output
value: workflow-data
hint: Location (relative to current namespace) to sync raw input, models and checkpoints from default object storage to '/share'.
containers:
- name: cvat-db
image: postgres:10-alpine
env:
- name: POSTGRES_USER
value: root
- name: POSTGRES_DB
value: cvat
- name: POSTGRES_HOST_AUTH_METHOD
value: trust
- name: PGDATA
value: /var/lib/psql/data
ports:
- containerPort: 5432
name: tcp
volumeMounts:
- name: db
mountPath: /var/lib/psql
- name: cvat-redis
image: redis:4.0-alpine
ports:
- containerPort: 6379
name: tcp
- name: cvat
image: onepanel/cvat:0.16.0_cvat.1.0.0
env:
- name: DJANGO_MODWSGI_EXTRA_ARGS
value: ""
- name: ALLOWED_HOSTS
value: '*'
- name: CVAT_REDIS_HOST
value: localhost
- name: CVAT_POSTGRES_HOST
value: localhost
- name: CVAT_SHARE_URL
value: /cvat/data
- name: CVAT_SHARE_DIR
value: /share
- name: CVAT_DATA_DIR
value: /cvat/data
- name: CVAT_MEDIA_DATA_DIR
value: /cvat/data/data
- name: CVAT_KEYS_DIR
value: /cvat/data/keys
- name: CVAT_MODELS_DIR
value: /cvat/data/models
- name: CVAT_LOGS_DIR
value: /cvat/logs
- name: ONEPANEL_SYNC_DIRECTORY
value: '{{workspace.parameters.sync-directory}}'
- name: NVIDIA_VISIBLE_DEVICES
value: all
- name: NVIDIA_DRIVER_CAPABILITIES
value: compute,utility
- name: NVIDIA_REQUIRE_CUDA
value: "cuda>=10.0 brand=tesla,driver>=384,driver<385 brand=tesla,driver>=410,driver<411"
- name: ONEPANEL_MAIN_CONTAINER
value: 'true'
ports:
- containerPort: 8080
name: http
volumeMounts:
- name: cvat-data
mountPath: /cvat
- name: share
mountPath: /share
- name: sys-namespace-config
mountPath: /etc/onepanel
readOnly: true
- name: cvat-ui
image: onepanel/cvat-ui:0.16.0_cvat.1.0.0
ports:
- containerPort: 80
name: http
# You can add multiple FileSyncer sidecar containers if needed
- name: filesyncer
image: onepanel/filesyncer:s3
imagePullPolicy: Always
args:
- download
- -server-prefix=/sys/filesyncer
env:
- name: FS_PATH
value: /mnt/share
- name: FS_PREFIX
value: '{{workflow.namespace}}/{{workspace.parameters.sync-directory}}'
volumeMounts:
- name: share
mountPath: /mnt/share
- name: sys-namespace-config
mountPath: /etc/onepanel
readOnly: true
ports:
- name: cvat-ui
port: 80
protocol: TCP
targetPort: 80
- name: cvat
port: 8080
protocol: TCP
targetPort: 8080
- name: fs
port: 8888
protocol: TCP
targetPort: 8888
routes:
- match:
- uri:
prefix: /sys/filesyncer
route:
- destination:
port:
number: 8888
- match:
- uri:
regex: /api/.*|/git/.*|/tensorflow/.*|/onepanelio/.*|/tracking/.*|/auto_annotation/.*|/analytics/.*|/static/.*|/admin/.*|/documentation/.*|/dextr/.*|/reid/.*
- queryParams:
id:
regex: \d+.*
route:
- destination:
port:
number: 8080
- match:
- uri:
prefix: /
route:
- destination:
port:
number: 80
volumeClaimTemplates:
- metadata:
name: db
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 20Gi
# DAG Workflow to be executed once a Workspace action completes (optional)
# Uncomment the lines below if you want to send Slack notifications
#postExecutionWorkflow:
# entrypoint: main
# templates:
# - name: main
# dag:
# tasks:
# - name: slack-notify
# template: slack-notify
# - name: slack-notify
# container:
# image: technosophos/slack-notify
# args:
# - SLACK_USERNAME=onepanel SLACK_TITLE="Your workspace is ready" SLACK_ICON=https://www.gravatar.com/avatar/5c4478592fe00878f62f0027be59c1bd SLACK_MESSAGE="Your workspace is now running" ./slack-notify
# command:
# - sh
# - -c

View File

@@ -0,0 +1,58 @@
# Docker containers that are part of the Workspace
containers:
- name: jupyterlab-tensorflow
image: onepanel/jupyterlab:1.0.1
command: ["/bin/bash", "-c", "pip install onepanel-sdk && start.sh jupyter lab --LabApp.token='' --LabApp.allow_remote_access=True --LabApp.allow_origin=\"*\" --LabApp.disable_check_xsrf=True --LabApp.trust_xheaders=True --LabApp.base_url=/ --LabApp.tornado_settings='{\"headers\":{\"Content-Security-Policy\":\"frame-ancestors * \'self\'\"}}' --notebook-dir='/data' --allow-root"]
env:
- name: tornado
value: "'{'headers':{'Content-Security-Policy':\"frame-ancestors\ *\ \'self'\"}}'"
args:
ports:
- containerPort: 8888
name: jupyterlab
- containerPort: 6006
name: tensorboard
volumeMounts:
- name: data
mountPath: /data
ports:
- name: jupyterlab
port: 80
protocol: TCP
targetPort: 8888
- name: tensorboard
port: 6006
protocol: TCP
targetPort: 6006
routes:
- match:
- uri:
prefix: /tensorboard
route:
- destination:
port:
number: 6006
- match:
- uri:
prefix: / #jupyter runs at the default route
route:
- destination:
port:
number: 80
# DAG Workflow to be executed once a Workspace action completes (optional)
#postExecutionWorkflow:
# entrypoint: main
# templates:
# - name: main
# dag:
# tasks:
# - name: slack-notify
# template: slack-notify
# - name: slack-notify
# container:
# image: technosophos/slack-notify
# args:
# - SLACK_USERNAME=onepanel SLACK_TITLE="Your workspace is ready" SLACK_ICON=https://www.gravatar.com/avatar/5c4478592fe00878f62f0027be59c1bd SLACK_MESSAGE="Your workspace is now running" ./slack-notify
# command:
# - sh
# - -c

View File

@@ -0,0 +1,77 @@
# Docker containers that are part of the Workspace
containers:
- name: jupyterlab
image: onepanel/jupyterlab:1.0.1
command: ["/bin/bash", "-c", "pip install onepanel-sdk && start.sh jupyter lab --LabApp.token='' --LabApp.allow_remote_access=True --LabApp.allow_origin=\"*\" --LabApp.disable_check_xsrf=True --LabApp.trust_xheaders=True --LabApp.base_url=/ --LabApp.tornado_settings='{\"headers\":{\"Content-Security-Policy\":\"frame-ancestors * \'self\'\"}}' --notebook-dir='/data' --allow-root"]
env:
- name: tornado
value: "'{'headers':{'Content-Security-Policy':\"frame-ancestors\ *\ \'self'\"}}'"
ports:
- containerPort: 8888
name: jupyterlab
- containerPort: 6006
name: tensorboard
volumeMounts:
- name: data
mountPath: /data
lifecycle:
postStart:
exec:
command:
- /bin/sh
- -c
- >
condayml="/data/.environment.yml";
jupytertxt="/data/.jupexported.txt";
if [ -f "$condayml" ]; then conda env update -f $condayml; fi;
if [ -f "$jupytertxt" ]; then cat $jupytertxt | xargs -n 1 jupyter labextension install --no-build && jupyter lab build --minimize=False; fi;
preStop:
exec:
command:
- /bin/sh
- -c
- >
conda env export > /data/.environment.yml -n base;
jupyter labextension list 1>/dev/null 2> /data/.jup.txt;
cat /data/.jup.txt | sed -n '2,$p' | awk 'sub(/v/,"@", $2){print $1$2}' > /data/.jupexported.txt;
ports:
- name: jupyterlab
port: 80
protocol: TCP
targetPort: 8888
- name: tensorboard
port: 6006
protocol: TCP
targetPort: 6006
routes:
- match:
- uri:
prefix: /tensorboard
route:
- destination:
port:
number: 6006
- match:
- uri:
prefix: / #jupyter runs at the default route
route:
- destination:
port:
number: 80
# DAG Workflow to be executed once a Workspace action completes (optional)
#postExecutionWorkflow:
# entrypoint: main
# templates:
# - name: main
# dag:
# tasks:
# - name: slack-notify
# template: slack-notify
# - name: slack-notify
# container:
# image: technosophos/slack-notify
# args:
# - SLACK_USERNAME=onepanel SLACK_TITLE="Your workspace is ready" SLACK_ICON=https://www.gravatar.com/avatar/5c4478592fe00878f62f0027be59c1bd SLACK_MESSAGE="Your workspace is now running" ./slack-notify
# command:
# - sh
# - -c

View File

@@ -0,0 +1,79 @@
# Docker containers that are part of the Workspace
containers:
- name: jupyterlab
image: onepanel/jupyterlab:1.0.1
command: ["/bin/bash", "-c", "pip install onepanel-sdk && start.sh jupyter lab --LabApp.token='' --LabApp.allow_remote_access=True --LabApp.allow_origin=\"*\" --LabApp.disable_check_xsrf=True --LabApp.trust_xheaders=True --LabApp.base_url=/ --LabApp.tornado_settings='{\"headers\":{\"Content-Security-Policy\":\"frame-ancestors * \'self\'\"}}' --notebook-dir='/data' --allow-root"]
env:
- name: tornado
value: "'{'headers':{'Content-Security-Policy':\"frame-ancestors\ *\ \'self'\"}}'"
- name: TENSORBOARD_PROXY_URL
value: '//$(ONEPANEL_RESOURCE_UID)--$(ONEPANEL_RESOURCE_NAMESPACE).$(ONEPANEL_DOMAIN)/tensorboard'
ports:
- containerPort: 8888
name: jupyterlab
- containerPort: 6006
name: tensorboard
volumeMounts:
- name: data
mountPath: /data
lifecycle:
postStart:
exec:
command:
- /bin/sh
- -c
- >
condayml="/data/.environment.yml";
jupytertxt="/data/.jupexported.txt";
if [ -f "$condayml" ]; then conda env update -f $condayml; fi;
if [ -f "$jupytertxt" ]; then cat $jupytertxt | xargs -n 1 jupyter labextension install --no-build && jupyter lab build --minimize=False; fi;
preStop:
exec:
command:
- /bin/sh
- -c
- >
conda env export > /data/.environment.yml -n base;
jupyter labextension list 1>/dev/null 2> /data/.jup.txt;
cat /data/.jup.txt | sed -n '2,$p' | awk 'sub(/v/,"@", $2){print $1$2}' > /data/.jupexported.txt;
ports:
- name: jupyterlab
port: 80
protocol: TCP
targetPort: 8888
- name: tensorboard
port: 6006
protocol: TCP
targetPort: 6006
routes:
- match:
- uri:
prefix: /tensorboard
route:
- destination:
port:
number: 6006
- match:
- uri:
prefix: / #jupyter runs at the default route
route:
- destination:
port:
number: 80
# DAG Workflow to be executed once a Workspace action completes (optional)
#postExecutionWorkflow:
# entrypoint: main
# templates:
# - name: main
# dag:
# tasks:
# - name: slack-notify
# template: slack-notify
# - name: slack-notify
# container:
# image: technosophos/slack-notify
# args:
# - SLACK_USERNAME=onepanel SLACK_TITLE="Your workspace is ready" SLACK_ICON=https://www.gravatar.com/avatar/5c4478592fe00878f62f0027be59c1bd SLACK_MESSAGE="Your workspace is now running" ./slack-notify
# command:
# - sh
# - -c

View File

@@ -0,0 +1,80 @@
# Docker containers that are part of the Workspace
containers:
- name: jupyterlab
image: onepanel/jupyterlab:1.0.1
command: ["/bin/bash", "-c", "pip install onepanel-sdk && start.sh LD_LIBRARY_PATH=/usr/local/nvidia/lib:/usr/local/nvidia/lib64 jupyter lab --LabApp.token='' --LabApp.allow_remote_access=True --LabApp.allow_origin=\"*\" --LabApp.disable_check_xsrf=True --LabApp.trust_xheaders=True --LabApp.base_url=/ --LabApp.tornado_settings='{\"headers\":{\"Content-Security-Policy\":\"frame-ancestors * \'self\'\"}}' --notebook-dir='/data' --allow-root"]
workingDir: /data
env:
- name: tornado
value: "'{'headers':{'Content-Security-Policy':\"frame-ancestors\ *\ \'self'\"}}'"
- name: TENSORBOARD_PROXY_URL
value: '//$(ONEPANEL_RESOURCE_UID)--$(ONEPANEL_RESOURCE_NAMESPACE).$(ONEPANEL_DOMAIN)/tensorboard'
ports:
- containerPort: 8888
name: jupyterlab
- containerPort: 6006
name: tensorboard
volumeMounts:
- name: data
mountPath: /data
lifecycle:
postStart:
exec:
command:
- /bin/sh
- -c
- >
condayml="/data/.environment.yml";
jupytertxt="/data/.jupexported.txt";
if [ -f "$condayml" ]; then conda env update -f $condayml; fi;
if [ -f "$jupytertxt" ]; then cat $jupytertxt | xargs -n 1 jupyter labextension install --no-build && jupyter lab build --minimize=False; fi;
preStop:
exec:
command:
- /bin/sh
- -c
- >
conda env export > /data/.environment.yml -n base;
jupyter labextension list 1>/dev/null 2> /data/.jup.txt;
cat /data/.jup.txt | sed -n '2,$p' | awk 'sub(/v/,"@", $2){print $1$2}' > /data/.jupexported.txt;
ports:
- name: jupyterlab
port: 80
protocol: TCP
targetPort: 8888
- name: tensorboard
port: 6006
protocol: TCP
targetPort: 6006
routes:
- match:
- uri:
prefix: /tensorboard
route:
- destination:
port:
number: 6006
- match:
- uri:
prefix: / #jupyter runs at the default route
route:
- destination:
port:
number: 80
# DAG Workflow to be executed once a Workspace action completes (optional)
#postExecutionWorkflow:
# entrypoint: main
# templates:
# - name: main
# dag:
# tasks:
# - name: slack-notify
# template: slack-notify
# - name: slack-notify
# container:
# image: technosophos/slack-notify
# args:
# - SLACK_USERNAME=onepanel SLACK_TITLE="Your workspace is ready" SLACK_ICON=https://www.gravatar.com/avatar/5c4478592fe00878f62f0027be59c1bd SLACK_MESSAGE="Your workspace is now running" ./slack-notify
# command:
# - sh
# - -c

View File

@@ -0,0 +1,190 @@
entrypoint: main
arguments:
parameters:
- name: source
value: https://github.com/onepanelio/Mask_RCNN.git
displayName: Model source code
type: hidden
visibility: private
- name: cvat-annotation-path
value: annotation-dump/sample_dataset
hint: Path to annotated data in default object storage (i.e S3). In CVAT, this parameter will be pre-populated.
displayName: Dataset path
visibility: private
- name: cvat-output-path
value: workflow-data/output/sample_output
hint: Path to store output artifacts in default object storage (i.e s3). In CVAT, this parameter will be pre-populated.
displayName: Workflow output path
visibility: private
- name: cvat-finetune-checkpoint
value: ''
hint: Select the last fine-tune checkpoint for this model. It may take up to 5 minutes for a recent checkpoint show here. Leave empty if this is the first time you're training this model.
displayName: Checkpoint path
visibility: public
- name: cvat-num-classes
displayName: Number of classes
hint: Number of classes (i.e in CVAT taks) + 1 for background
value: '81'
visibility: private
- name: hyperparameters
displayName: Hyperparameters
visibility: public
type: textarea.textarea
value: |-
stage-1-epochs=1 # Epochs for network heads
stage-2-epochs=2 # Epochs for finetune layers
stage-3-epochs=3 # Epochs for all layers
hint: "Please refer to our <a href='https://docs.onepanel.ai/docs/getting-started/use-cases/computervision/annotation/cvat/cvat_annotation_model#arguments-optional' target='_blank'>documentation</a> for more information on parameters. Number of classes will be automatically populated if you had 'sys-num-classes' parameter in a workflow."
- name: dump-format
value: cvat_coco
displayName: CVAT dump format
visibility: public
- name: tf-image
visibility: public
value: tensorflow/tensorflow:1.13.1-py3
type: select.select
displayName: Select TensorFlow image
hint: Select the GPU image if you are running on a GPU node pool
options:
- name: 'TensorFlow 1.13.1 CPU Image'
value: 'tensorflow/tensorflow:1.13.1-py3'
- name: 'TensorFlow 1.13.1 GPU Image'
value: 'tensorflow/tensorflow:1.13.1-gpu-py3'
- displayName: Node pool
hint: Name of node pool or group to run this workflow task
type: select.select
visibility: public
name: sys-node-pool
value: Standard_D4s_v3
required: true
options:
- name: 'CPU: 2, RAM: 8GB'
value: Standard_D2s_v3
- name: 'CPU: 4, RAM: 16GB'
value: Standard_D4s_v3
- name: 'GPU: 1xK80, CPU: 6, RAM: 56GB'
value: Standard_NC6
templates:
- name: main
dag:
tasks:
- name: train-model
template: tensorflow
# Uncomment the lines below if you want to send Slack notifications
# - arguments:
# artifacts:
# - from: '{{tasks.train-model.outputs.artifacts.sys-metrics}}'
# name: metrics
# parameters:
# - name: status
# value: '{{tasks.train-model.status}}'
# dependencies:
# - train-model
# name: notify-in-slack
# template: slack-notify-success
- name: tensorflow
container:
args:
- |
apt-get update \
&& apt-get install -y git wget libglib2.0-0 libsm6 libxext6 libxrender-dev \
&& pip install -r requirements.txt \
&& pip install boto3 pyyaml google-cloud-storage \
&& git clone https://github.com/waleedka/coco \
&& cd coco/PythonAPI \
&& python setup.py build_ext install \
&& rm -rf build \
&& cd ../../ \
&& wget https://github.com/matterport/Mask_RCNN/releases/download/v2.0/mask_rcnn_coco.h5 \
&& python setup.py install && ls \
&& python samples/coco/cvat.py train --dataset=/mnt/data/datasets \
--model=workflow_maskrcnn \
--extras="{{workflow.parameters.hyperparameters}}" \
--ref_model_path="{{workflow.parameters.cvat-finetune-checkpoint}}" \
--num_classes="{{workflow.parameters.cvat-num-classes}}" \
&& cd /mnt/src/ \
&& python prepare_dataset.py /mnt/data/datasets/annotations/instances_default.json
command:
- sh
- -c
image: '{{workflow.parameters.tf-image}}'
volumeMounts:
- mountPath: /mnt/data
name: data
- mountPath: /mnt/output
name: output
workingDir: /mnt/src
nodeSelector:
beta.kubernetes.io/instance-type: '{{workflow.parameters.sys-node-pool}}'
sidecars:
- name: tensorboard
image: tensorflow/tensorflow:2.3.0
command: [sh, -c]
tty: true
args: ["tensorboard --logdir /mnt/output/"]
ports:
- containerPort: 6006
name: tensorboard
inputs:
artifacts:
- name: data
path: /mnt/data/datasets/
{{.ArtifactRepositoryType}}:
key: '{{workflow.namespace}}/{{workflow.parameters.cvat-annotation-path}}'
- git:
repo: '{{workflow.parameters.source}}'
revision: "no-boto"
name: src
path: /mnt/src
outputs:
artifacts:
- name: model
optional: true
path: /mnt/output
{{.ArtifactRepositoryType}}:
key: '{{workflow.namespace}}/{{workflow.parameters.cvat-output-path}}/{{workflow.name}}'
# Uncomment the lines below if you want to send Slack notifications
#- container:
# args:
# - SLACK_USERNAME=Onepanel SLACK_TITLE="{{workflow.name}} {{inputs.parameters.status}}"
# SLACK_ICON=https://www.gravatar.com/avatar/5c4478592fe00878f62f0027be59c1bd
# SLACK_MESSAGE=$(cat /tmp/metrics.json)} ./slack-notify
# command:
# - sh
# - -c
# image: technosophos/slack-notify
# inputs:
# artifacts:
# - name: metrics
# optional: true
# path: /tmp/metrics.json
# parameters:
# - name: status
# name: slack-notify-success
volumeClaimTemplates:
- metadata:
creationTimestamp: null
name: data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 200Gi
- metadata:
creationTimestamp: null
name: output
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 200Gi

View File

@@ -0,0 +1,192 @@
entrypoint: main
arguments:
parameters:
- name: source
value: https://github.com/onepanelio/Mask_RCNN.git
displayName: Model source code
type: hidden
visibility: private
- name: cvat-annotation-path
value: annotation-dump/sample_dataset
hint: Path to annotated data in default object storage (i.e S3). In CVAT, this parameter will be pre-populated.
displayName: Dataset path
visibility: private
- name: cvat-output-path
value: workflow-data/output/sample_output
hint: Path to store output artifacts in default object storage (i.e s3). In CVAT, this parameter will be pre-populated.
displayName: Workflow output path
visibility: private
- name: cvat-finetune-checkpoint
value: ''
hint: Select the last fine-tune checkpoint for this model. It may take up to 5 minutes for a recent checkpoint show here. Leave empty if this is the first time you're training this model.
displayName: Checkpoint path
visibility: public
- name: cvat-num-classes
displayName: Number of classes
hint: Number of classes (i.e in CVAT taks) + 1 for background
value: '81'
visibility: private
- name: hyperparameters
displayName: Hyperparameters
visibility: public
type: textarea.textarea
value: |-
stage-1-epochs=1 # Epochs for network heads
stage-2-epochs=2 # Epochs for finetune layers
stage-3-epochs=3 # Epochs for all layers
hint: "Please refer to our <a href='https://docs.onepanel.ai/docs/getting-started/use-cases/computervision/annotation/cvat/cvat_annotation_model#arguments-optional' target='_blank'>documentation</a> for more information on parameters. Number of classes will be automatically populated if you had 'sys-num-classes' parameter in a workflow."
- name: dump-format
value: cvat_coco
displayName: CVAT dump format
visibility: public
- name: tf-image
visibility: public
value: tensorflow/tensorflow:1.13.1-py3
type: select.select
displayName: Select TensorFlow image
hint: Select the GPU image if you are running on a GPU node pool
options:
- name: 'TensorFlow 1.13.1 CPU Image'
value: 'tensorflow/tensorflow:1.13.1-py3'
- name: 'TensorFlow 1.13.1 GPU Image'
value: 'tensorflow/tensorflow:1.13.1-gpu-py3'
- displayName: Node pool
hint: Name of node pool or group to run this workflow task
type: select.select
visibility: public
name: sys-node-pool
value: Standard_D4s_v3
required: true
options:
- name: 'CPU: 2, RAM: 8GB'
value: Standard_D2s_v3
- name: 'CPU: 4, RAM: 16GB'
value: Standard_D4s_v3
- name: 'GPU: 1xK80, CPU: 6, RAM: 56GB'
value: Standard_NC6
templates:
- name: main
dag:
tasks:
- name: train-model
template: tensorflow
# Uncomment the lines below if you want to send Slack notifications
# - arguments:
# artifacts:
# - from: '{{tasks.train-model.outputs.artifacts.sys-metrics}}'
# name: metrics
# parameters:
# - name: status
# value: '{{tasks.train-model.status}}'
# dependencies:
# - train-model
# name: notify-in-slack
# template: slack-notify-success
- name: tensorflow
container:
args:
- |
apt-get update \
&& apt-get install -y git wget libglib2.0-0 libsm6 libxext6 libxrender-dev \
&& pip install -r requirements.txt \
&& pip install boto3 pyyaml google-cloud-storage \
&& git clone https://github.com/waleedka/coco \
&& cd coco/PythonAPI \
&& python setup.py build_ext install \
&& rm -rf build \
&& cd ../../ \
&& wget https://github.com/matterport/Mask_RCNN/releases/download/v2.0/mask_rcnn_coco.h5 \
&& python setup.py install && ls \
&& python samples/coco/cvat.py train --dataset=/mnt/data/datasets \
--model=workflow_maskrcnn \
--extras="{{workflow.parameters.hyperparameters}}" \
--ref_model_path="{{workflow.parameters.cvat-finetune-checkpoint}}" \
--num_classes="{{workflow.parameters.cvat-num-classes}}" \
&& cd /mnt/src/ \
&& python prepare_dataset.py /mnt/data/datasets/annotations/instances_default.json
command:
- sh
- -c
image: '{{workflow.parameters.tf-image}}'
volumeMounts:
- mountPath: /mnt/data
name: data
- mountPath: /mnt/output
name: output
workingDir: /mnt/src
nodeSelector:
beta.kubernetes.io/instance-type: '{{workflow.parameters.sys-node-pool}}'
sidecars:
- name: tensorboard
image: tensorflow/tensorflow:2.3.0
command: [sh, -c]
env:
- name: ONEPANEL_INTERACTIVE_SIDECAR
value: 'true'
args: ["tensorboard --logdir /mnt/output/"]
ports:
- containerPort: 6006
name: tensorboard
inputs:
artifacts:
- name: data
path: /mnt/data/datasets/
{{.ArtifactRepositoryType}}:
key: '{{workflow.namespace}}/{{workflow.parameters.cvat-annotation-path}}'
- git:
repo: '{{workflow.parameters.source}}'
revision: "no-boto"
name: src
path: /mnt/src
outputs:
artifacts:
- name: model
optional: true
path: /mnt/output
{{.ArtifactRepositoryType}}:
key: '{{workflow.namespace}}/{{workflow.parameters.cvat-output-path}}/{{workflow.name}}'
# Uncomment the lines below if you want to send Slack notifications
#- container:
# args:
# - SLACK_USERNAME=Onepanel SLACK_TITLE="{{workflow.name}} {{inputs.parameters.status}}"
# SLACK_ICON=https://www.gravatar.com/avatar/5c4478592fe00878f62f0027be59c1bd
# SLACK_MESSAGE=$(cat /tmp/metrics.json)} ./slack-notify
# command:
# - sh
# - -c
# image: technosophos/slack-notify
# inputs:
# artifacts:
# - name: metrics
# optional: true
# path: /tmp/metrics.json
# parameters:
# - name: status
# name: slack-notify-success
volumeClaimTemplates:
- metadata:
creationTimestamp: null
name: data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 200Gi
- metadata:
creationTimestamp: null
name: output
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 200Gi

View File

@@ -0,0 +1,75 @@
entrypoint: main
arguments:
parameters:
- name: source
value: https://github.com/onepanelio/tensorflow-examples.git
- name: command
value: "python mnist/main.py --epochs=5"
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 2Gi
- metadata:
name: output
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 2Gi
templates:
- name: main
dag:
tasks:
- name: train-model
template: pytorch
# Uncomment section below to send metrics to Slack
# - name: notify-in-slack
# dependencies: [train-model]
# template: slack-notify-success
# arguments:
# parameters:
# - name: status
# value: "{{tasks.train-model.status}}"
# artifacts:
# - name: metrics
# from: "{{tasks.train-model.outputs.artifacts.sys-metrics}}"
- name: pytorch
inputs:
artifacts:
- name: src
path: /mnt/src
git:
repo: "{{workflow.parameters.source}}"
outputs:
artifacts:
- name: model
path: /mnt/output
optional: true
archive:
none: {}
container:
image: tensorflow/tensorflow:latest
command: [sh,-c]
args: ["{{workflow.parameters.command}}"]
workingDir: /mnt/src
volumeMounts:
- name: data
mountPath: /mnt/data
- name: output
mountPath: /mnt/output
- name: slack-notify-success
container:
image: technosophos/slack-notify
command: [sh,-c]
args: ['SLACK_USERNAME=Worker SLACK_TITLE="{{workflow.name}} {{inputs.parameters.status}}" SLACK_ICON=https://www.gravatar.com/avatar/5c4478592fe00878f62f0027be59c1bd SLACK_MESSAGE=$(cat /tmp/metrics.json)} ./slack-notify']
inputs:
parameters:
- name: status
artifacts:
- name: metrics
path: /tmp/metrics.json
optional: true

View File

@@ -0,0 +1,70 @@
arguments:
parameters:
- name: epochs
value: '10'
entrypoint: main
templates:
- name: main
dag:
tasks:
- name: train-model
template: tf-dense
- name: tf-dense
script:
image: tensorflow/tensorflow:2.3.0
command:
- python
- '-u'
source: |
import tensorflow as tf
import datetime
mnist = tf.keras.datasets.mnist
(x_train, y_train),(x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
def create_model():
return tf.keras.models.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28)),
tf.keras.layers.Dense(512, activation='relu'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(10, activation='softmax')
])
model = create_model()
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
# Write logs to /mnt/output
log_dir = "/mnt/output/logs/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir, histogram_freq=1)
history = model.fit(x=x_train,
y=y_train,
epochs={{workflow.parameters.epochs}},
validation_data=(x_test, y_test),
callbacks=[tensorboard_callback])
volumeMounts:
# TensorBoard sidecar will automatically mount this volume
- name: output
mountPath: /mnt/output
sidecars:
- name: tensorboard
image: 'tensorflow/tensorflow:2.3.0'
command:
- sh
- '-c'
env:
- name: ONEPANEL_INTERACTIVE_SIDECAR
value: 'true'
args:
# Read logs from /mnt/output - this directory is auto-mounted from volumeMounts
- tensorboard --logdir /mnt/output/
ports:
- containerPort: 6006
name: tensorboard
volumeClaimTemplates:
# Provision a volume that can be shared between main container and TensorBoard side car
- metadata:
name: output
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 2Gi

View File

@@ -0,0 +1,221 @@
entrypoint: main
arguments:
parameters:
- name: source
value: https://github.com/tensorflow/models.git
displayName: Model source code
type: hidden
visibility: private
- name: trainingsource
value: https://github.com/onepanelio/cvat-training.git
type: hidden
visibility: private
- name: revision
value: v1.13.0
type: hidden
visibility: private
- name: cvat-annotation-path
value: annotation-dump/sample_dataset
displayName: Dataset path
hint: Path to annotated data in default object storage (i.e S3). In CVAT, this parameter will be pre-populated.
visibility: private
- name: cvat-output-path
value: workflow-data/output/sample_output
hint: Path to store output artifacts in default object storage (i.e s3). In CVAT, this parameter will be pre-populated.
displayName: Workflow output path
visibility: private
- name: cvat-model
value: frcnn-res50-coco
displayName: Model
hint: TF Detection API's model to use for training.
type: select.select
visibility: public
options:
- name: 'Faster RCNN-ResNet 101-COCO'
value: frcnn-res101-coco
- name: 'Faster RCNN-ResNet 101-Low Proposal-COCO'
value: frcnn-res101-low
- name: 'Faster RCNN-ResNet 50-COCO'
value: frcnn-res50-coco
- name: 'Faster RCNN-NAS-COCO'
value: frcnn-nas-coco
- name: 'SSD MobileNet V1-COCO'
value: ssd-mobilenet-v1-coco2
- name: 'SSD MobileNet V2-COCO'
value: ssd-mobilenet-v2-coco
- name: 'SSDLite MobileNet-COCO'
value: ssdlite-mobilenet-coco
- name: hyperparameters
value: |-
num-steps=10000
displayName: Hyperparameters
visibility: public
type: textarea.textarea
hint: "Please refer to our <a href='https://docs.onepanel.ai/docs/getting-started/use-cases/computervision/annotation/cvat/cvat_annotation_model#arguments-optional' target='_blank'>documentation</a> for more information on parameters. Number of classes will be automatically populated if you had 'sys-num-classes' parameter in a workflow."
- name: cvat-finetune-checkpoint
value: ''
hint: Select the last fine-tune checkpoint for this model. It may take up to 5 minutes for a recent checkpoint show here. Leave empty if this is the first time you're training this model.
displayName: Checkpoint path
visibility: public
- name: cvat-num-classes
value: '81'
hint: Number of classes
displayName: Number of classes
visibility: private
- name: tf-image
value: tensorflow/tensorflow:1.13.1-py3
type: select.select
displayName: Select TensorFlow image
visibility: public
hint: Select the GPU image if you are running on a GPU node pool
options:
- name: 'TensorFlow 1.13.1 CPU Image'
value: 'tensorflow/tensorflow:1.13.1-py3'
- name: 'TensorFlow 1.13.1 GPU Image'
value: 'tensorflow/tensorflow:1.13.1-gpu-py3'
- displayName: Node pool
hint: Name of node pool or group to run this workflow task
type: select.select
name: sys-node-pool
value: Standard_D4s_v3
visibility: public
required: true
options:
- name: 'CPU: 2, RAM: 8GB'
value: Standard_D2s_v3
- name: 'CPU: 4, RAM: 16GB'
value: Standard_D4s_v3
- name: 'GPU: 1xK80, CPU: 6, RAM: 56GB'
value: Standard_NC6
- name: dump-format
value: cvat_tfrecord
visibility: public
templates:
- name: main
dag:
tasks:
- name: train-model
template: tensorflow
# Uncomment the lines below if you want to send Slack notifications
# - arguments:
# artifacts:
# - from: '{{tasks.train-model.outputs.artifacts.sys-metrics}}'
# name: metrics
# parameters:
# - name: status
# value: '{{tasks.train-model.status}}'
# dependencies:
# - train-model
# name: notify-in-slack
# template: slack-notify-success
- name: tensorflow
container:
args:
- |
apt-get update && \
apt-get install -y python3-pip git wget unzip libglib2.0-0 libsm6 libxext6 libxrender-dev && \
pip install pillow lxml Cython contextlib2 jupyter matplotlib numpy scipy boto3 pycocotools pyyaml google-cloud-storage && \
cd /mnt/src/tf/research && \
export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim && \
cd /mnt/src/train && \
python convert_workflow.py \
--extras="{{workflow.parameters.hyperparameters}}" \
--model="{{workflow.parameters.cvat-model}}" \
--num_classes="{{workflow.parameters.cvat-num-classes}}" \
--sys_finetune_checkpoint={{workflow.parameters.cvat-finetune-checkpoint}}
command:
- sh
- -c
image: '{{workflow.parameters.tf-image}}'
volumeMounts:
- mountPath: /mnt/data
name: data
- mountPath: /mnt/output
name: output
workingDir: /mnt/src
nodeSelector:
beta.kubernetes.io/instance-type: '{{workflow.parameters.sys-node-pool}}'
sidecars:
- name: tensorboard
image: tensorflow/tensorflow:2.3.0
command: [sh, -c]
tty: true
args: ["tensorboard --logdir /mnt/output/"]
ports:
- containerPort: 6006
name: tensorboard
inputs:
artifacts:
- name: data
path: /mnt/data/datasets/
{{.ArtifactRepositoryType}}:
key: '{{workflow.namespace}}/{{workflow.parameters.cvat-annotation-path}}'
- name: models
path: /mnt/data/models/
optional: true
{{.ArtifactRepositoryType}}:
key: '{{workflow.namespace}}/{{workflow.parameters.cvat-finetune-checkpoint}}'
- git:
repo: '{{workflow.parameters.source}}'
revision: '{{workflow.parameters.revision}}'
name: src
path: /mnt/src/tf
- git:
repo: '{{workflow.parameters.trainingsource}}'
revision: 'optional-artifacts'
name: tsrc
path: /mnt/src/train
outputs:
artifacts:
- name: model
optional: true
path: /mnt/output
{{.ArtifactRepositoryType}}:
key: '{{workflow.namespace}}/{{workflow.parameters.cvat-output-path}}/{{workflow.name}}'
# Uncomment the lines below if you want to send Slack notifications
#- container:
# args:
# - SLACK_USERNAME=Onepanel SLACK_TITLE="{{workflow.name}} {{inputs.parameters.status}}"
# SLACK_ICON=https://www.gravatar.com/avatar/5c4478592fe00878f62f0027be59c1bd
# SLACK_MESSAGE=$(cat /tmp/metrics.json)} ./slack-notify
# command:
# - sh
# - -c
# image: technosophos/slack-notify
# inputs:
# artifacts:
# - name: metrics
# optional: true
# path: /tmp/metrics.json
# parameters:
# - name: status
# name: slack-notify-success
volumeClaimTemplates:
- metadata:
creationTimestamp: null
name: data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 200Gi
- metadata:
creationTimestamp: null
name: output
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 200Gi

View File

@@ -0,0 +1,221 @@
entrypoint: main
arguments:
parameters:
- name: source
value: https://github.com/tensorflow/models.git
displayName: Model source code
type: hidden
visibility: private
- name: trainingsource
value: https://github.com/onepanelio/cvat-training.git
type: hidden
visibility: private
- name: revision
value: v1.13.0
type: hidden
visibility: private
- name: cvat-annotation-path
value: annotation-dump/sample_dataset
displayName: Dataset path
hint: Path to annotated data in default object storage (i.e S3). In CVAT, this parameter will be pre-populated.
visibility: private
- name: cvat-output-path
value: workflow-data/output/sample_output
hint: Path to store output artifacts in default object storage (i.e s3). In CVAT, this parameter will be pre-populated.
displayName: Workflow output path
visibility: private
- name: cvat-model
value: frcnn-res50-coco
displayName: Model
hint: TF Detection API's model to use for training.
type: select.select
visibility: public
options:
- name: 'Faster RCNN-ResNet 101-COCO'
value: frcnn-res101-coco
- name: 'Faster RCNN-ResNet 101-Low Proposal-COCO'
value: frcnn-res101-low
- name: 'Faster RCNN-ResNet 50-COCO'
value: frcnn-res50-coco
- name: 'Faster RCNN-NAS-COCO'
value: frcnn-nas-coco
- name: 'SSD MobileNet V1-COCO'
value: ssd-mobilenet-v1-coco2
- name: 'SSD MobileNet V2-COCO'
value: ssd-mobilenet-v2-coco
- name: 'SSDLite MobileNet-COCO'
value: ssdlite-mobilenet-coco
- name: hyperparameters
value: |-
num-steps=10000
displayName: Hyperparameters
visibility: public
type: textarea.textarea
hint: "Please refer to our <a href='https://docs.onepanel.ai/docs/getting-started/use-cases/computervision/annotation/cvat/cvat_annotation_model#arguments-optional' target='_blank'>documentation</a> for more information on parameters. Number of classes will be automatically populated if you had 'sys-num-classes' parameter in a workflow."
- name: cvat-finetune-checkpoint
value: ''
hint: Select the last fine-tune checkpoint for this model. It may take up to 5 minutes for a recent checkpoint show here. Leave empty if this is the first time you're training this model.
displayName: Checkpoint path
visibility: public
- name: cvat-num-classes
value: '81'
hint: Number of classes
displayName: Number of classes
visibility: private
- name: tf-image
value: tensorflow/tensorflow:1.13.1-py3
type: select.select
displayName: Select TensorFlow image
visibility: public
hint: Select the GPU image if you are running on a GPU node pool
options:
- name: 'TensorFlow 1.13.1 CPU Image'
value: 'tensorflow/tensorflow:1.13.1-py3'
- name: 'TensorFlow 1.13.1 GPU Image'
value: 'tensorflow/tensorflow:1.13.1-gpu-py3'
- displayName: Node pool
hint: Name of node pool or group to run this workflow task
type: select.select
name: sys-node-pool
value: Standard_D4s_v3
visibility: public
required: true
options:
- name: 'CPU: 2, RAM: 8GB'
value: Standard_D2s_v3
- name: 'CPU: 4, RAM: 16GB'
value: Standard_D4s_v3
- name: 'GPU: 1xK80, CPU: 6, RAM: 56GB'
value: Standard_NC6
- name: dump-format
value: cvat_tfrecord
visibility: public
templates:
- name: main
dag:
tasks:
- name: train-model
template: tensorflow
# Uncomment the lines below if you want to send Slack notifications
# - arguments:
# artifacts:
# - from: '{{tasks.train-model.outputs.artifacts.sys-metrics}}'
# name: metrics
# parameters:
# - name: status
# value: '{{tasks.train-model.status}}'
# dependencies:
# - train-model
# name: notify-in-slack
# template: slack-notify-success
- name: tensorflow
container:
args:
- |
apt-get update && \
apt-get install -y python3-pip git wget unzip libglib2.0-0 libsm6 libxext6 libxrender-dev && \
pip install pillow lxml Cython contextlib2 jupyter matplotlib numpy scipy boto3 pycocotools pyyaml google-cloud-storage && \
cd /mnt/src/tf/research && \
export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim && \
cd /mnt/src/train && \
python convert_workflow.py \
--extras="{{workflow.parameters.hyperparameters}}" \
--model="{{workflow.parameters.cvat-model}}" \
--num_classes="{{workflow.parameters.cvat-num-classes}}" \
--sys_finetune_checkpoint={{workflow.parameters.cvat-finetune-checkpoint}}
command:
- sh
- -c
image: '{{workflow.parameters.tf-image}}'
volumeMounts:
- mountPath: /mnt/data
name: data
- mountPath: /mnt/output
name: output
workingDir: /mnt/src
nodeSelector:
beta.kubernetes.io/instance-type: '{{workflow.parameters.sys-node-pool}}'
sidecars:
- name: tensorboard
image: tensorflow/tensorflow:2.3.0
command: [sh, -c]
tty: true
args: ["tensorboard --logdir /mnt/output/"]
ports:
- containerPort: 6006
name: tensorboard
inputs:
artifacts:
- name: data
path: /mnt/data/datasets/
{{.ArtifactRepositoryType}}:
key: '{{workflow.namespace}}/{{workflow.parameters.cvat-annotation-path}}'
- name: models
path: /mnt/data/models/
optional: true
{{.ArtifactRepositoryType}}:
key: '{{workflow.parameters.cvat-finetune-checkpoint}}'
- git:
repo: '{{workflow.parameters.source}}'
revision: '{{workflow.parameters.revision}}'
name: src
path: /mnt/src/tf
- git:
repo: '{{workflow.parameters.trainingsource}}'
revision: 'optional-artifacts'
name: tsrc
path: /mnt/src/train
outputs:
artifacts:
- name: model
optional: true
path: /mnt/output
{{.ArtifactRepositoryType}}:
key: '{{workflow.namespace}}/{{workflow.parameters.cvat-output-path}}/{{workflow.name}}'
# Uncomment the lines below if you want to send Slack notifications
#- container:
# args:
# - SLACK_USERNAME=Onepanel SLACK_TITLE="{{workflow.name}} {{inputs.parameters.status}}"
# SLACK_ICON=https://www.gravatar.com/avatar/5c4478592fe00878f62f0027be59c1bd
# SLACK_MESSAGE=$(cat /tmp/metrics.json)} ./slack-notify
# command:
# - sh
# - -c
# image: technosophos/slack-notify
# inputs:
# artifacts:
# - name: metrics
# optional: true
# path: /tmp/metrics.json
# parameters:
# - name: status
# name: slack-notify-success
volumeClaimTemplates:
- metadata:
creationTimestamp: null
name: data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 200Gi
- metadata:
creationTimestamp: null
name: output
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 200Gi

View File

@@ -0,0 +1,223 @@
entrypoint: main
arguments:
parameters:
- name: source
value: https://github.com/tensorflow/models.git
displayName: Model source code
type: hidden
visibility: private
- name: trainingsource
value: https://github.com/onepanelio/cvat-training.git
type: hidden
visibility: private
- name: revision
value: v1.13.0
type: hidden
visibility: private
- name: cvat-annotation-path
value: annotation-dump/sample_dataset
displayName: Dataset path
hint: Path to annotated data in default object storage (i.e S3). In CVAT, this parameter will be pre-populated.
visibility: private
- name: cvat-output-path
value: workflow-data/output/sample_output
hint: Path to store output artifacts in default object storage (i.e s3). In CVAT, this parameter will be pre-populated.
displayName: Workflow output path
visibility: private
- name: cvat-model
value: frcnn-res50-coco
displayName: Model
hint: TF Detection API's model to use for training.
type: select.select
visibility: public
options:
- name: 'Faster RCNN-ResNet 101-COCO'
value: frcnn-res101-coco
- name: 'Faster RCNN-ResNet 101-Low Proposal-COCO'
value: frcnn-res101-low
- name: 'Faster RCNN-ResNet 50-COCO'
value: frcnn-res50-coco
- name: 'Faster RCNN-NAS-COCO'
value: frcnn-nas-coco
- name: 'SSD MobileNet V1-COCO'
value: ssd-mobilenet-v1-coco2
- name: 'SSD MobileNet V2-COCO'
value: ssd-mobilenet-v2-coco
- name: 'SSDLite MobileNet-COCO'
value: ssdlite-mobilenet-coco
- name: hyperparameters
value: |-
num-steps=10000
displayName: Hyperparameters
visibility: public
type: textarea.textarea
hint: "Please refer to our <a href='https://docs.onepanel.ai/docs/getting-started/use-cases/computervision/annotation/cvat/cvat_annotation_model#arguments-optional' target='_blank'>documentation</a> for more information on parameters. Number of classes will be automatically populated if you had 'sys-num-classes' parameter in a workflow."
- name: cvat-finetune-checkpoint
value: ''
hint: Select the last fine-tune checkpoint for this model. It may take up to 5 minutes for a recent checkpoint show here. Leave empty if this is the first time you're training this model.
displayName: Checkpoint path
visibility: public
- name: cvat-num-classes
value: '81'
hint: Number of classes
displayName: Number of classes
visibility: private
- name: tf-image
value: tensorflow/tensorflow:1.13.1-py3
type: select.select
displayName: Select TensorFlow image
visibility: public
hint: Select the GPU image if you are running on a GPU node pool
options:
- name: 'TensorFlow 1.13.1 CPU Image'
value: 'tensorflow/tensorflow:1.13.1-py3'
- name: 'TensorFlow 1.13.1 GPU Image'
value: 'tensorflow/tensorflow:1.13.1-gpu-py3'
- displayName: Node pool
hint: Name of node pool or group to run this workflow task
type: select.select
name: sys-node-pool
value: Standard_D4s_v3
visibility: public
required: true
options:
- name: 'CPU: 2, RAM: 8GB'
value: Standard_D2s_v3
- name: 'CPU: 4, RAM: 16GB'
value: Standard_D4s_v3
- name: 'GPU: 1xK80, CPU: 6, RAM: 56GB'
value: Standard_NC6
- name: dump-format
value: cvat_tfrecord
visibility: public
templates:
- name: main
dag:
tasks:
- name: train-model
template: tensorflow
# Uncomment the lines below if you want to send Slack notifications
# - arguments:
# artifacts:
# - from: '{{tasks.train-model.outputs.artifacts.sys-metrics}}'
# name: metrics
# parameters:
# - name: status
# value: '{{tasks.train-model.status}}'
# dependencies:
# - train-model
# name: notify-in-slack
# template: slack-notify-success
- name: tensorflow
container:
args:
- |
apt-get update && \
apt-get install -y python3-pip git wget unzip libglib2.0-0 libsm6 libxext6 libxrender-dev && \
pip install pillow lxml Cython contextlib2 jupyter matplotlib numpy scipy boto3 pycocotools pyyaml google-cloud-storage && \
cd /mnt/src/tf/research && \
export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim && \
cd /mnt/src/train && \
python convert_workflow.py \
--extras="{{workflow.parameters.hyperparameters}}" \
--model="{{workflow.parameters.cvat-model}}" \
--num_classes="{{workflow.parameters.cvat-num-classes}}" \
--sys_finetune_checkpoint={{workflow.parameters.cvat-finetune-checkpoint}}
command:
- sh
- -c
image: '{{workflow.parameters.tf-image}}'
volumeMounts:
- mountPath: /mnt/data
name: data
- mountPath: /mnt/output
name: output
workingDir: /mnt/src
nodeSelector:
beta.kubernetes.io/instance-type: '{{workflow.parameters.sys-node-pool}}'
sidecars:
- name: tensorboard
image: tensorflow/tensorflow:2.3.0
command: [sh, -c]
env:
- name: ONEPANEL_INTERACTIVE_SIDECAR
value: 'true'
args: ["tensorboard --logdir /mnt/output/"]
ports:
- containerPort: 6006
name: tensorboard
inputs:
artifacts:
- name: data
path: /mnt/data/datasets/
{{.ArtifactRepositoryType}}:
key: '{{workflow.namespace}}/{{workflow.parameters.cvat-annotation-path}}'
- name: models
path: /mnt/data/models/
optional: true
{{.ArtifactRepositoryType}}:
key: '{{workflow.parameters.cvat-finetune-checkpoint}}'
- git:
repo: '{{workflow.parameters.source}}'
revision: '{{workflow.parameters.revision}}'
name: src
path: /mnt/src/tf
- git:
repo: '{{workflow.parameters.trainingsource}}'
revision: 'optional-artifacts'
name: tsrc
path: /mnt/src/train
outputs:
artifacts:
- name: model
optional: true
path: /mnt/output
{{.ArtifactRepositoryType}}:
key: '{{workflow.namespace}}/{{workflow.parameters.cvat-output-path}}/{{workflow.name}}'
# Uncomment the lines below if you want to send Slack notifications
#- container:
# args:
# - SLACK_USERNAME=Onepanel SLACK_TITLE="{{workflow.name}} {{inputs.parameters.status}}"
# SLACK_ICON=https://www.gravatar.com/avatar/5c4478592fe00878f62f0027be59c1bd
# SLACK_MESSAGE=$(cat /tmp/metrics.json)} ./slack-notify
# command:
# - sh
# - -c
# image: technosophos/slack-notify
# inputs:
# artifacts:
# - name: metrics
# optional: true
# path: /tmp/metrics.json
# parameters:
# - name: status
# name: slack-notify-success
volumeClaimTemplates:
- metadata:
creationTimestamp: null
name: data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 200Gi
- metadata:
creationTimestamp: null
name: output
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 200Gi

View File

@@ -0,0 +1,41 @@
# Docker containers that are part of the Workspace
containers:
- name: vscode
image: onepanel/vscode:1.0.0
command: ["/bin/bash", "-c", "pip install onepanel-sdk && /usr/bin/entrypoint.sh --bind-addr 0.0.0.0:8080 --auth none ."]
ports:
- containerPort: 8080
name: vscode
volumeMounts:
- name: data
mountPath: /data
ports:
- name: vscode
port: 8080
protocol: TCP
targetPort: 8080
routes:
- match:
- uri:
prefix: / #vscode runs at the default route
route:
- destination:
port:
number: 8080
# DAG Workflow to be executed once a Workspace action completes (optional)
#postExecutionWorkflow:
# entrypoint: main
# templates:
# - name: main
# dag:
# tasks:
# - name: slack-notify
# template: slack-notify
# - name: slack-notify
# container:
# image: technosophos/slack-notify
# args:
# - SLACK_USERNAME=onepanel SLACK_TITLE="Your workspace is ready" SLACK_ICON=https://www.gravatar.com/avatar/5c4478592fe00878f62f0027be59c1bd SLACK_MESSAGE="Your workspace is now running" ./slack-notify
# command:
# - sh
# - -c

View File

@@ -0,0 +1,60 @@
# Docker containers that are part of the Workspace
containers:
- name: vscode
image: onepanel/vscode:1.0.0
command: ["/bin/bash", "-c", "pip install onepanel-sdk && /usr/bin/entrypoint.sh --bind-addr 0.0.0.0:8080 --auth none ."]
ports:
- containerPort: 8080
name: vscode
volumeMounts:
- name: data
mountPath: /data
lifecycle:
postStart:
exec:
command:
- /bin/sh
- -c
- >
condayml="/data/.environment.yml";
vscodetxt="/data/.vscode-extensions.txt";
if [ -f "$condayml" ]; then conda env update -f $condayml; fi;
if [ -f "$vscodetxt" ]; then cat $vscodetxt | xargs -n 1 code-server --install-extension; fi;
preStop:
exec:
command:
- /bin/sh
- -c
- >
conda env export > /data/.environment.yml -n base;
code-server --list-extensions | tail -n +2 > /data/.vscode-extensions.txt;
ports:
- name: vscode
port: 8080
protocol: TCP
targetPort: 8080
routes:
- match:
- uri:
prefix: / #vscode runs at the default route
route:
- destination:
port:
number: 8080
# DAG Workflow to be executed once a Workspace action completes (optional)
#postExecutionWorkflow:
# entrypoint: main
# templates:
# - name: main
# dag:
# tasks:
# - name: slack-notify
# template: slack-notify
# - name: slack-notify
# container:
# image: technosophos/slack-notify
# args:
# - SLACK_USERNAME=onepanel SLACK_TITLE="Your workspace is ready" SLACK_ICON=https://www.gravatar.com/avatar/5c4478592fe00878f62f0027be59c1bd SLACK_MESSAGE="Your workspace is now running" ./slack-notify
# command:
# - sh
# - -c

View File

@@ -0,0 +1,46 @@
# Background
A user may install pip packages, conda packages, jupyterlab extensions,
or vscode extensions.
To improve the user experience, we should save these packages
when the user pauses and resumes the workspace.
- And when the user changes the workspace machine.
To achieve this end, were using lifecycle hooks for containers, via Kubernetes.
Well add these hooks to workspace templates, to VSCode and JupyterLab.
Note: We're not supporting CVAT Workspace persistence.
- User does not have access to the terminal through the UI.
# Problem(s)
Originally, we attempted to tar up the packages of conda, vscode, and jupyter.
This worked, but ate non-trivial amount of space. Roughly ~2 GB with a clean workspace,
using our dockerfile image.
- So we'd need to warn the user to have enough space for their volume mounts
- We'd also have to warn the user that if there is not enough space, the packages
may not persist.
The other problem was we needed to extend the terminationGracePeriodSeconds of the
pod.
- K8s sets 30 seconds by default
We use the preStop hook to do the back-up.
- This operation runs for 2-3 minutes on a clean workspace image
- For a user with more packages, it would take longer.
- k8s will grant a 2 second increase once, if preStop is not done.
Otherwise, k8s kills the preStop hook and the container.
We thought about exposing the terminationGracePeriodSeconds to the user,
allow them to change this value as needed.
And lastly, k8s will wait the entire grace period.
- Even if the preStop hook finishes early, k8s will wait to kill the container.
- In testing, k8s waited 20 minutes before terminating the container
So we decided to export the list of installed packages, as a text file.
- Then, we re-install on workspace start-up with postStart hook.
# References
- https://github.com/onepanelio/core/issues/623

3
go.mod
View File

@@ -15,6 +15,7 @@ require (
github.com/ghodss/yaml v1.0.0
github.com/go-sql-driver/mysql v1.5.0 // indirect
github.com/golang/protobuf v1.4.1
github.com/google/uuid v1.1.2
github.com/gorilla/handlers v1.4.2
github.com/grpc-ecosystem/go-grpc-middleware v1.2.0
github.com/grpc-ecosystem/grpc-gateway v1.14.4
@@ -43,4 +44,4 @@ require (
k8s.io/apimachinery v0.16.7-beta.0
k8s.io/client-go v0.16.4
sigs.k8s.io/yaml v1.2.0
)
)

4
go.sum
View File

@@ -221,6 +221,8 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
@@ -766,4 +768,4 @@ sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:w
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
upper.io/db.v3 v3.6.3+incompatible/go.mod h1:FgTdD24eBjJAbPKsQSiHUNgXjOR4Lub3u1UMHSIh82Y=
upper.io/db.v3 v3.6.3+incompatible/go.mod h1:FgTdD24eBjJAbPKsQSiHUNgXjOR4Lub3u1UMHSIh82Y=

BIN
img/onepanel.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 MiB

27
main.go
View File

@@ -4,20 +4,6 @@ import (
"context"
"flag"
"fmt"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
corev1 "k8s.io/api/core/v1"
apiv1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
k8runtime "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/tools/cache"
"math"
"net"
"net/http"
"path/filepath"
"strings"
"github.com/gorilla/handlers"
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
grpc_logrus "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus"
@@ -34,6 +20,19 @@ import (
log "github.com/sirupsen/logrus"
"github.com/tmc/grpc-websocket-proxy/wsproxy"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
corev1 "k8s.io/api/core/v1"
apiv1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
k8runtime "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/tools/cache"
"math"
"net"
"net/http"
"path/filepath"
"strings"
)
var (

View File

@@ -4,6 +4,8 @@ import (
"fmt"
sq "github.com/Masterminds/squirrel"
argoprojv1alpha1 "github.com/argoproj/argo/pkg/client/clientset/versioned/typed/workflow/v1alpha1"
"github.com/jmoiron/sqlx"
"github.com/onepanelio/core/pkg/util/env"
"github.com/onepanelio/core/pkg/util/gcs"
"github.com/onepanelio/core/pkg/util/router"
"github.com/onepanelio/core/pkg/util/s3"
@@ -11,6 +13,8 @@ import (
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"strconv"
"time"
)
type Config = rest.Config
@@ -18,6 +22,7 @@ type Config = rest.Config
var sb = sq.StatementBuilder.PlaceholderFormat(sq.Dollar)
type Client struct {
Token string
kubernetes.Interface
argoprojV1alpha1 argoprojv1alpha1.ArgoprojV1alpha1Interface
*DB
@@ -38,6 +43,37 @@ func NewConfig() (config *Config) {
return
}
// GetDefaultClient loads a default k8s client
func GetDefaultClient() (*Client, error) {
kubeConfig := NewConfig()
client, err := NewClient(kubeConfig, nil, nil)
if err != nil {
return nil, err
}
config, err := client.GetSystemConfig()
if err != nil {
return nil, err
}
dbDriverName, dbDataSourceName := config.DatabaseConnection()
client.DB = NewDB(sqlx.MustConnect(dbDriverName, dbDataSourceName))
return client, nil
}
// GetDefaultClientWithDB loads a default k8s client with an existing DB
func GetDefaultClientWithDB(db *DB) (*Client, error) {
kubeConfig := NewConfig()
client, err := NewClient(kubeConfig, nil, nil)
if err != nil {
return nil, err
}
client.DB = db
return client, nil
}
// NewClient creates a client to interact with the Onepanel system.
// It includes access to the database, kubernetes, argo, and configuration.
func NewClient(config *Config, db *DB, systemConfig SystemConfig) (client *Client, err error) {
@@ -49,6 +85,8 @@ func NewClient(config *Config, db *DB, systemConfig SystemConfig) (client *Clien
config.CertFile = ""
}
config.Timeout = getKubernetesTimeout()
kubeClient, err := kubernetes.NewForConfig(config)
if err != nil {
return
@@ -113,3 +151,18 @@ func (c *Client) GetWebRouter() (router.Web, error) {
return webRouter, err
}
// getKubernetesTimeout returns the timeout for kubernetes requests.
// It uses the KUBERNETES_TIMEOUT environment variable and defaults to 60 seconds if not found or an error occurs
// parsing the set timeout.
func getKubernetesTimeout() time.Duration {
timeoutSeconds := env.Get("KUBERNETES_TIMEOUT", "60")
timeout, err := strconv.Atoi(timeoutSeconds)
if err != nil {
log.Warn("Unable to parse KUBERNETES_TIMEOUT environment variable. Defaulting to 60 seconds")
return 60 * time.Second
}
return time.Duration(timeout) * time.Second
}

View File

@@ -3,13 +3,12 @@ package v1
import (
"encoding/base64"
"fmt"
"strings"
"github.com/onepanelio/core/pkg/util/ptr"
log "github.com/sirupsen/logrus"
"gopkg.in/yaml.v3"
corev1 "k8s.io/api/core/v1"
k8yaml "sigs.k8s.io/yaml"
"strings"
)
// SystemConfig is configuration loaded from kubernetes config and secrets that includes information about the
@@ -38,6 +37,12 @@ func NewSystemConfig(configMap *ConfigMap, secret *Secret) (config SystemConfig,
}
config["databasePassword"] = string(databasePassword)
hmac, err := base64.StdEncoding.DecodeString(secret.Data["hmac"])
if err != nil {
return
}
config["hmac"] = string(hmac)
return
}
@@ -183,6 +188,16 @@ func (s SystemConfig) UpdateNodePoolOptions(parameters []Parameter) ([]Parameter
return result, nil
}
// HMACKey gets the HMAC value, or nil.
func (s SystemConfig) HMACKey() []byte {
hmac := s.GetValue("hmac")
if hmac == nil {
return []byte{}
}
return []byte(*hmac)
}
// ArtifactRepositoryS3Provider is meant to be used
// by the CLI. CLI will marshal this struct into the correct
// YAML structure for k8s configmap / secret.

View File

@@ -22,7 +22,7 @@ func ApplyLabelSelectQuery(labelSelector string, sb sq.SelectBuilder, filter Lab
return sb, err
}
sb = sb.Where("%v @> ?", labelSelector, labelsJSON)
sb = sb.Where(labelSelector+" @> ?", labelsJSON)
return sb, nil
}

View File

@@ -8,8 +8,65 @@ import (
"github.com/onepanelio/core/pkg/util/mapping"
"github.com/onepanelio/core/pkg/util/types"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"strings"
)
// SelectLabelsQuery represents the options available to filter a select labels query
type SelectLabelsQuery struct {
Table string
Alias string
Namespace string
KeyLike string
Skip []string
}
// SkipKeysFromString parses keys encoded in a string and returns an array of keys
// The separator is ";"
func SkipKeysFromString(keys string) []string {
results := make([]string, 0)
for _, key := range strings.Split(keys, ";") {
if key == "" {
continue
}
results = append(results, key)
}
return results
}
// SelectLabels returns a SelectBuilder that selects key, value columns from the criteria specified in query
func SelectLabels(query *SelectLabelsQuery) sq.SelectBuilder {
// Sample query
// SELECT DISTINCT labels.*
// FROM workflow_executions w,
// jsonb_each_text(w.labels) labels
// WHERE labels.key LIKE 'ca%'
// AND labels.key NOT IN ('catdog')
// AND namespace = 'onepanel'
// AND labels != 'null'::jsonb
fromTable := fmt.Sprintf("%s %s", query.Table, query.Alias)
fromJsonb := fmt.Sprintf("jsonb_each_text(%s.labels) labels", query.Alias)
bld := sb.Select("key", "value").
Distinct().
From(fromTable + ", " + fromJsonb).
Where("labels != 'null'::jsonb")
if query.Namespace != "" {
bld = bld.Where(sq.Eq{query.Alias + ".namespace": query.Namespace})
}
if query.KeyLike != "" {
bld = bld.Where(sq.Like{"labels.key": query.KeyLike})
}
if len(query.Skip) != 0 {
bld = bld.Where(sq.NotEq{"labels.key": query.Skip})
}
return bld
}
func (c *Client) ListLabels(resource string, uid string) (labels []*Label, err error) {
sb := sb.Select("labels").
From(TypeToTableName(resource))
@@ -49,6 +106,22 @@ func (c *Client) ListLabels(resource string, uid string) (labels []*Label, err e
return
}
// ListAvailableLabels lists the labels available for the resource specified by the query
func (c *Client) ListAvailableLabels(query *SelectLabelsQuery) (result []*Label, err error) {
selectLabelsBuilder := SelectLabels(query)
// Don't select labels from Terminated workspaces.
if query.Table == "workspaces" {
selectLabelsBuilder = selectLabelsBuilder.Where(sq.NotEq{
"l.phase": "Terminated",
})
}
err = c.Selectx(&result, selectLabelsBuilder)
return
}
func (c *Client) AddLabels(namespace, resource, uid string, keyValues map[string]string) error {
source, meta, err := c.GetK8sLabelResource(namespace, resource, uid)
if err != nil {

View File

@@ -1,6 +1,9 @@
package v1
import (
"database/sql/driver"
"encoding/json"
"errors"
"time"
wfv1 "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1"
@@ -133,3 +136,81 @@ func WorkflowTemplatesToVersionIDs(workflowTemplates []*WorkflowTemplate) (ids [
return
}
// Metrics is a convenience type to work with multiple Metric(s)
type Metrics []*Metric
// Add adds the new metric to the metrics.
// If there is already metrics with the same name, and override is true
// the existing metrics will all be updated to the input value. Otherwise, they will be left unchanged.
func (m *Metrics) Add(input *Metric, override bool) {
foundExisting := false
for _, metric := range *m {
if metric.Name == input.Name && override {
foundExisting = true
metric.Value = input.Value
metric.Format = input.Format
}
}
if !foundExisting {
*m = append(*m, input)
}
}
// Merge merges the metrics with other metrics
// If there is already metrics with the same name and override is true
// the existing metrics will all be updated to the input value. Otherwise they will be left unchanged.
func (m *Metrics) Merge(input Metrics, override bool) {
for _, item := range input {
m.Add(item, override)
}
}
// Unmarshal unmarshal's the json in m to v, as in json.Unmarshal.
// This is to support Metrics working with JSONB column types in sql
func (m *Metrics) Unmarshal(v interface{}) error {
if len(*m) == 0 {
*m = make([]*Metric, 0)
}
v = m
return nil
}
// Value returns j as a value. This does a validating unmarshal into another
// RawMessage. If j is invalid json, it returns an error.
// Note that nil values will return "[]" - empty JSON.
// This is to support Metrics working with JSONB column types in sql
func (m Metrics) Value() (driver.Value, error) {
if m == nil {
return json.Marshal(make([]*Metric, 0))
}
return json.Marshal(m)
}
// Scan stores the src in m. No validation is done.
// This is to support Metrics working with JSONB column types in sql
func (m *Metrics) Scan(src interface{}) error {
var source []byte
switch t := src.(type) {
case string:
source = []byte(t)
case []byte:
if len(t) == 0 {
source = []byte("[]")
} else {
source = t
}
case nil:
*m = make([]*Metric, 0)
default:
return errors.New("incompatible type for Metrics")
}
return json.Unmarshal(source, m)
}

72
pkg/types_test.go Normal file
View File

@@ -0,0 +1,72 @@
package v1
import (
"github.com/stretchr/testify/assert"
"testing"
)
// TestMetrics_Add tests the Add method of the Metrics type
func TestMetrics_Add(t *testing.T) {
var initial Metrics = []*Metric{{
Name: "accuracy",
Value: 0.98,
Format: "",
}}
initial.Add(&Metric{
Name: "success",
Value: 1.0,
Format: "%",
}, false)
assert.Len(t, initial, 2)
initial.Add(&Metric{
Name: "accuracy",
Value: 0.99,
Format: "%",
}, false)
assert.Len(t, initial, 3)
initial.Add(&Metric{
Name: "accuracy",
Value: 0.99,
Format: "%",
}, true)
assert.Len(t, initial, 3)
assert.True(t, initial[0].Value == 0.99)
}
// TestMetrics_Merge tests the Merge method of the Metrics Type
func TestMetrics_Merge(t *testing.T) {
var initial Metrics = []*Metric{{
Name: "accuracy",
Value: 0.98,
Format: "",
}, {
Name: "success",
Value: 1.0,
Format: "%",
}}
var toMerge Metrics = []*Metric{{
Name: "accuracy",
Value: 0.00,
Format: "",
}, {
Name: "success",
Value: 1.0,
Format: "%",
}, {
Name: "test",
Value: 0.5,
Format: "",
}}
initial.Merge(toMerge, true)
assert.Len(t, initial, 3)
assert.True(t, initial[0].Value == 0.00)
}

10
pkg/util/env/env.go vendored
View File

@@ -10,6 +10,8 @@ const (
DefaultEnvironmentVariableSecret = "onepanel-default-env"
)
// GetEnv gets the environment variable value, or returns fallback if the environment variable does not exist
// Deprecated: use Get instead
func GetEnv(key, fallback string) string {
if value, ok := os.LookupEnv(key); ok {
return value
@@ -17,6 +19,14 @@ func GetEnv(key, fallback string) string {
return fallback
}
// Get gets the environment variable value, or returns fallback if the environment variable does not exist
func Get(key, fallback string) string {
if value, ok := os.LookupEnv(key); ok {
return value
}
return fallback
}
func PrependEnvVarToContainer(container *corev1.Container, name, value string) {
for _, e := range container.Env {
if e.Name == name {

View File

@@ -1,6 +1,8 @@
package sql
import "fmt"
import (
"fmt"
)
// FormatColumnSelect returns a list of column names to be used in a SQL Select modified with optional alias and destination.
//

View File

@@ -21,7 +21,12 @@ func (l *JSONLabels) Unmarshal(v interface{}) error {
// Value returns j as a value. This does a validating unmarshal into another
// RawMessage. If j is invalid json, it returns an error.
// Note that nil values will return "{}" - empty JSON.
func (l JSONLabels) Value() (driver.Value, error) {
if l == nil {
return json.Marshal(make(map[string]string))
}
return json.Marshal(l)
}

View File

@@ -8,6 +8,7 @@ import (
"errors"
"fmt"
sq "github.com/Masterminds/squirrel"
"github.com/google/uuid"
"github.com/onepanelio/core/pkg/util/gcs"
"github.com/onepanelio/core/pkg/util/label"
"github.com/onepanelio/core/pkg/util/ptr"
@@ -18,9 +19,11 @@ import (
"gopkg.in/yaml.v2"
"io"
"io/ioutil"
"k8s.io/apimachinery/pkg/api/resource"
networking "istio.io/api/networking/v1alpha3"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/apimachinery/pkg/watch"
"net/http"
yaml2 "sigs.k8s.io/yaml"
"strconv"
"strings"
"time"
@@ -48,6 +51,32 @@ var (
workflowTemplateVersionLabelKey = "onepanel.io/workflow-template-version"
)
// envVarValueInSidecars returns true if any of the sidecars contain an environment variable with the input name and value
// false otherwise
func envVarValueInSidecars(sidecars []wfv1.UserContainer, name, value string) bool {
for _, s := range sidecars {
for _, e := range s.Env {
if e.Name == name && e.Value == value {
return true
}
}
}
return false
}
// hasEnvVarValue returns true if any of the env vars have the given name and value
// false otherwise
func hasEnvVarValue(envVars []corev1.EnvVar, name, value string) bool {
for _, e := range envVars {
if e.Name == name && e.Value == value {
return true
}
}
return false
}
func typeWorkflow(wf *wfv1.Workflow) (workflow *WorkflowExecution) {
manifest, err := json.Marshal(wf)
if err != nil {
@@ -197,71 +226,48 @@ func injectArtifactRepositoryConfig(artifact *wfv1.Artifact, namespaceConfig *Na
}
}
// injectContainerResourceQuotas adds resource requests and limits if they exist
// Code grabs the resource request information from the nodeSelector, compared against running nodes.
// If the running node is not present, no resource information is retrieved.
func (c *Client) injectContainerResourceQuotas(wf *wfv1.Workflow, template *wfv1.Template, systemConfig SystemConfig) error {
// injectHostPortAndResourcesToContainer adds a hostPort to the template container, if a nodeSelector is present.
// Kubernetes will ensure that multiple containers with the same hostPort do not share the same node.
func (c *Client) injectHostPortAndResourcesToContainer(template *wfv1.Template, opts *WorkflowExecutionOptions, config SystemConfig) error {
if template.NodeSelector == nil {
return nil
}
supportedNodePoolLabels := []string{"beta.kubernetes.io/instance-type", "node.kubernetes.io/instance-type"}
nodePoolLabel := ""
var value string
for k, v := range template.NodeSelector {
for _, supportedNodePoolLabel := range supportedNodePoolLabels {
if k == supportedNodePoolLabel {
nodePoolLabel = k
value = v
break
}
}
}
if value == "" {
return nil
}
if strings.Contains(value, "{{workflow.") {
parts := strings.Split(strings.Replace(value, "}}", "", -1), ".")
paramName := parts[len(parts)-1]
for _, param := range wf.Spec.Arguments.Parameters {
if param.Name == paramName && param.Value != nil {
value = *param.Value
break
}
}
ports := []corev1.ContainerPort{
{Name: "node-capturer", HostPort: 80, ContainerPort: 80},
}
runningNodes, err := c.Interface.CoreV1().Nodes().List(ListOptions{})
if err != nil {
return err
// Add resource limits for GPUs
nodePoolVal := ""
for _, v := range template.NodeSelector {
nodePoolVal = v
break
}
for _, node := range runningNodes.Items {
if node.Labels[nodePoolLabel] == value {
cpu, memory, gpu, gpuManufacturer := CalculateResourceRequirements(node, nodePoolLabel, value)
if cpu != "" && memory != "" {
resourceList := corev1.ResourceRequirements{
Limits: nil,
Requests: map[corev1.ResourceName]resource.Quantity{
corev1.ResourceCPU: resource.MustParse(cpu),
corev1.ResourceMemory: resource.MustParse(memory),
},
}
if gpu > 0 {
stringGpu := strconv.FormatInt(gpu, 10)
resourceList.Limits = make(map[corev1.ResourceName]resource.Quantity)
resourceList.Limits[corev1.ResourceName(gpuManufacturer)] = resource.MustParse(stringGpu)
}
if template.Container != nil {
template.Container.Resources = resourceList
}
if template.Script != nil {
template.Script.Container.Resources = resourceList
}
//process only one node
return nil
if strings.Contains(nodePoolVal, "{{workflow.") {
parts := strings.Split(strings.Replace(nodePoolVal, "}}", "", -1), ".")
paramName := parts[len(parts)-1]
for _, parameter := range opts.Parameters {
if parameter.Name == paramName {
nodePoolVal = *parameter.Value
}
}
}
n, err := config.NodePoolOptionByValue(nodePoolVal)
if err != nil {
return nil
}
if template.Container != nil {
template.Container.Ports = ports
if n != nil && n.Resources.Limits != nil {
template.Container.Resources = n.Resources
}
}
if template.Script != nil {
template.Script.Container.Ports = ports
if n != nil && n.Resources.Limits != nil {
template.Script.Container.Resources = n.Resources
}
}
return nil
}
@@ -324,7 +330,14 @@ func (c *Client) injectAutomatedFields(namespace string, wf *wfv1.Workflow, opts
if template.Metadata.Annotations == nil {
template.Metadata.Annotations = make(map[string]string)
}
template.Metadata.Annotations["sidecar.istio.io/inject"] = "false"
//For workflows with accessible sidecars, we need istio
//Istio does not prevent the main container from stopping
if envVarValueInSidecars(template.Sidecars, "ONEPANEL_INTERACTIVE_SIDECAR", "true") {
template.Metadata.Annotations["sidecar.istio.io/inject"] = "true"
} else {
template.Metadata.Annotations["sidecar.istio.io/inject"] = "false"
}
if template.Container != nil {
// Mount dev/shm
@@ -332,7 +345,7 @@ func (c *Client) injectAutomatedFields(namespace string, wf *wfv1.Workflow, opts
Name: "sys-dshm",
MountPath: "/dev/shm",
})
err = c.injectContainerResourceQuotas(wf, template, systemConfig)
err = c.injectHostPortAndResourcesToContainer(template, opts, systemConfig)
if err != nil {
return err
}
@@ -340,7 +353,7 @@ func (c *Client) injectAutomatedFields(namespace string, wf *wfv1.Workflow, opts
}
if template.Script != nil {
err = c.injectContainerResourceQuotas(wf, template, systemConfig)
err = c.injectHostPortAndResourcesToContainer(template, opts, systemConfig)
if err != nil {
return err
}
@@ -458,6 +471,11 @@ func (c *Client) createWorkflow(namespace string, workflowTemplateID uint64, wor
return nil, err
}
newTemplateOrder, err := c.injectAccessForSidecars(namespace, wf)
if err != nil {
return nil, err
}
wf.Spec.Templates = newTemplateOrder
createdArgoWorkflow, err := c.ArgoprojV1alpha1().Workflows(namespace).Create(wf)
if err != nil {
return nil, err
@@ -487,49 +505,260 @@ func (c *Client) createWorkflow(namespace string, workflowTemplateID uint64, wor
return
}
func ensureWorkflowRunsOnDedicatedNode(wf *wfv1.Workflow, config SystemConfig) (*wfv1.Workflow, error) {
antiAffinityLabelKey := "onepanel.io/reserves-instance-type"
nodeSelectorVal := ""
addPodAffinity := false
for i := range wf.Spec.Templates {
template := &wf.Spec.Templates[i]
if template.NodeSelector == nil {
continue
}
func (c *Client) injectAccessForSidecars(namespace string, wf *wfv1.Workflow) ([]wfv1.Template, error) {
var newTemplateOrder []wfv1.Template
taskSysSendStatusName := "sys-send-status"
taskSysSendExitStats := "sys-send-exit-stats"
for tIdx, t := range wf.Spec.Templates {
//Inject services, virtual routes
for si, s := range t.Sidecars {
//If ONEPANEL_INTERACTIVE_SIDECAR is true, sidecar needs to be accessible by HTTP
//Otherwise, we skip the sidecar
hasInjectIstio := hasEnvVarValue(s.Env, "ONEPANEL_INTERACTIVE_SIDECAR", "true")
if !hasInjectIstio {
continue
}
for _, v := range template.NodeSelector {
if strings.Contains(v, "{{workflow.") {
parts := strings.Split(strings.Replace(v, "}}", "", -1), ".")
paramName := parts[len(parts)-1]
for _, param := range wf.Spec.Arguments.Parameters {
if param.Name == paramName && param.Value != nil {
nodeSelectorVal = *param.Value
break
if len(s.Ports) == 0 {
msg := fmt.Sprintf("sidecar %s must have at least one port.", s.Name)
return nil, util.NewUserError(codes.InvalidArgument, msg)
}
t.Sidecars[si].MirrorVolumeMounts = ptr.Bool(true)
serviceNameUID := "s" + uuid.New().String() + "--" + namespace
serviceNameUIDDNSCompliant, err := uid2.GenerateUID(serviceNameUID, 63)
if err != nil {
return nil, util.NewUserError(codes.InvalidArgument, err.Error())
}
serviceName := serviceNameUIDDNSCompliant + "." + *c.systemConfig.Domain()
serviceTemplateName := uuid.New().String()
serviceTemplateNameAdd := "sys-k8s-service-template-add-" + serviceTemplateName
serviceTemplateNameDelete := "sys-k8s-service-template-delete-" + serviceTemplateName
serviceTaskName := "service-" + uuid.New().String()
serviceAddTaskName := "sys-add-" + serviceTaskName
serviceDeleteTaskName := "sys-delete-" + serviceTaskName
virtualServiceTemplateName := uuid.New().String()
virtualServiceTemplateNameAdd := "sys-k8s-virtual-service-template-add-" + virtualServiceTemplateName
virtualServiceTemplateNameDelete := "sys-k8s-virtual-service-template-delete-" + virtualServiceTemplateName
virtualServiceTaskName := "virtual-service-" + uuid.New().String()
virtualServiceAddTaskName := "sys-add-" + virtualServiceTaskName
virtualServiceDeleteTaskName := "sys-delete-" + virtualServiceTaskName
var servicePorts []corev1.ServicePort
var routes []*networking.HTTPRoute
for _, port := range s.Ports {
servicePort := corev1.ServicePort{
Name: port.Name,
Protocol: port.Protocol,
Port: port.ContainerPort,
TargetPort: intstr.FromInt(int(port.ContainerPort)),
}
servicePorts = append(servicePorts, servicePort)
route := networking.HTTPRoute{
Match: []*networking.HTTPMatchRequest{
{
Uri: &networking.StringMatch{
MatchType: &networking.StringMatch_Prefix{
Prefix: "/"},
},
},
},
Route: []*networking.HTTPRouteDestination{
{
Destination: &networking.Destination{
Host: serviceNameUIDDNSCompliant,
Port: &networking.PortSelector{
Number: uint32(port.ContainerPort),
},
},
},
},
}
routes = append(routes, &route)
}
service := corev1.Service{
TypeMeta: metav1.TypeMeta{
APIVersion: "v1",
Kind: "Service",
},
ObjectMeta: metav1.ObjectMeta{
Name: serviceNameUIDDNSCompliant,
},
Spec: corev1.ServiceSpec{
Ports: servicePorts,
Selector: map[string]string{
serviceTaskName: serviceNameUIDDNSCompliant,
},
},
}
//Istio needs to know which pod to setup the route to
if wf.Spec.Templates[tIdx].Metadata.Labels == nil {
wf.Spec.Templates[tIdx].Metadata.Labels = make(map[string]string)
}
wf.Spec.Templates[tIdx].Metadata.Labels[serviceTaskName] = serviceNameUIDDNSCompliant
serviceManifestBytes, err := yaml2.Marshal(service)
if err != nil {
return nil, err
}
serviceManifest := string(serviceManifestBytes)
templateServiceResource := wfv1.Template{
Name: serviceTemplateNameAdd,
Metadata: wfv1.Metadata{
Annotations: map[string]string{
"sidecar.istio.io/inject": "false",
},
},
Resource: &wfv1.ResourceTemplate{
Action: "create",
Manifest: serviceManifest,
},
}
newTemplateOrder = append(newTemplateOrder, templateServiceResource)
//routes
virtualServiceNameUUID := "vs-" + uuid.New().String()
hosts := []string{serviceName}
wf.Spec.Templates[tIdx].Outputs.Parameters = append(wf.Spec.Templates[tIdx].Outputs.Parameters,
wfv1.Parameter{Name: "sys-sidecar-url--" + s.Name, Value: &serviceName},
)
virtualService := map[string]interface{}{
"apiVersion": "networking.istio.io/v1alpha3",
"kind": "VirtualService",
"metadata": metav1.ObjectMeta{
Name: virtualServiceNameUUID,
},
"spec": networking.VirtualService{
Http: routes,
Gateways: []string{"istio-system/ingressgateway"},
Hosts: hosts,
},
}
virtualServiceManifestBytes, err := yaml2.Marshal(virtualService)
if err != nil {
return nil, err
}
virtualServiceManifest := string(virtualServiceManifestBytes)
templateRouteResource := wfv1.Template{
Name: virtualServiceTemplateNameAdd,
Metadata: wfv1.Metadata{
Annotations: map[string]string{
"sidecar.istio.io/inject": "false",
},
},
Resource: &wfv1.ResourceTemplate{
Action: "create",
Manifest: virtualServiceManifest,
},
}
newTemplateOrder = append(newTemplateOrder, templateRouteResource)
for i2, t2 := range wf.Spec.Templates {
if t2.Name == wf.Spec.Entrypoint {
if t2.DAG != nil {
tasks := wf.Spec.Templates[i2].DAG.Tasks
t := tasks[0]
sysDepFound := false
for _, d := range t.Dependencies {
if d == taskSysSendStatusName {
sysDepFound = true
wf.Spec.Templates[i2].DAG.Tasks[0].Dependencies =
[]string{virtualServiceAddTaskName}
}
}
if sysDepFound == false {
wf.Spec.Templates[i2].DAG.Tasks[0].Dependencies = append(wf.Spec.Templates[i2].DAG.Tasks[0].Dependencies, virtualServiceAddTaskName)
}
wf.Spec.Templates[i2].DAG.Tasks = append(tasks, []wfv1.DAGTask{
{
Name: serviceAddTaskName,
Template: serviceTemplateNameAdd,
Dependencies: []string{taskSysSendStatusName},
},
{
Name: virtualServiceAddTaskName,
Template: virtualServiceTemplateNameAdd,
Dependencies: []string{serviceAddTaskName},
},
}...)
}
}
}
break
}
template.Metadata.Labels = map[string]string{antiAffinityLabelKey: nodeSelectorVal}
addPodAffinity = true
}
if addPodAffinity {
wf.Spec.Affinity = &corev1.Affinity{
PodAntiAffinity: &corev1.PodAntiAffinity{
RequiredDuringSchedulingIgnoredDuringExecution: []corev1.PodAffinityTerm{
{
LabelSelector: &metav1.LabelSelector{
MatchExpressions: []metav1.LabelSelectorRequirement{
{Key: antiAffinityLabelKey, Operator: "In", Values: []string{nodeSelectorVal}},
},
},
TopologyKey: "kubernetes.io/hostname",
//Inject clean-up for service and virtualservice
templateServiceDeleteResource := wfv1.Template{
Name: serviceTemplateNameDelete,
Metadata: wfv1.Metadata{
Annotations: map[string]string{
"sidecar.istio.io/inject": "false",
},
},
},
Resource: &wfv1.ResourceTemplate{
Action: "delete",
Manifest: serviceManifest,
},
}
newTemplateOrder = append(newTemplateOrder, templateServiceDeleteResource)
templateRouteDeleteResource := wfv1.Template{
Name: virtualServiceTemplateNameDelete,
Metadata: wfv1.Metadata{
Annotations: map[string]string{
"sidecar.istio.io/inject": "false",
},
},
Resource: &wfv1.ResourceTemplate{
Action: "delete",
Manifest: virtualServiceManifest,
},
}
newTemplateOrder = append(newTemplateOrder, templateRouteDeleteResource)
dagTasks := []wfv1.DAGTask{
{
Name: serviceDeleteTaskName,
Template: serviceTemplateNameDelete,
},
{
Name: virtualServiceDeleteTaskName,
Template: virtualServiceTemplateNameDelete,
Dependencies: []string{serviceDeleteTaskName},
},
}
if wf.Spec.OnExit != "" {
for _, t := range wf.Spec.Templates {
if t.Name == wf.Spec.OnExit {
t.DAG.Tasks = append(t.DAG.Tasks, dagTasks...)
sysExitDepFound := false
for dti, dt := range t.DAG.Tasks {
if dt.Name == taskSysSendExitStats {
sysExitDepFound = true
t.DAG.Tasks[dti].Dependencies = append(t.DAG.Tasks[dti].Dependencies, virtualServiceDeleteTaskName)
}
}
if sysExitDepFound == false {
t.DAG.Tasks[0].Dependencies = append(t.DAG.Tasks[0].Dependencies, virtualServiceDeleteTaskName)
}
break
}
}
} else {
exitHandlerDAG := wfv1.Template{
Name: "exit-handler",
DAG: &wfv1.DAGTemplate{
Tasks: dagTasks,
},
}
wf.Spec.OnExit = "exit-handler"
wf.Spec.Templates = append(wf.Spec.Templates, exitHandlerDAG)
}
}
newTemplateOrder = append(newTemplateOrder, wf.Spec.Templates[tIdx])
}
return wf, nil
return newTemplateOrder, nil
}
func (c *Client) ValidateWorkflowExecution(namespace string, manifest []byte) (err error) {
@@ -674,6 +903,7 @@ func (c *Client) createWorkflowExecutionDB(namespace string, workflowExecution *
"parameters": string(parametersJSON),
"is_archived": false,
"labels": workflowExecution.Labels,
"metrics": workflowExecution.Metrics,
}).
Suffix("RETURNING id").
RunWith(c.DB).
@@ -683,7 +913,7 @@ func (c *Client) createWorkflowExecutionDB(namespace string, workflowExecution *
return
}
func (c *Client) FinishWorkflowExecutionStatisticViaExitHandler(namespace, name string, workflowTemplateID int64, phase wfv1.NodePhase, startedAt time.Time) (err error) {
func (c *Client) FinishWorkflowExecutionStatisticViaExitHandler(namespace, name string, phase wfv1.NodePhase, startedAt time.Time) (err error) {
_, err = sb.Update("workflow_executions").
SetMap(sq.Eq{
"started_at": startedAt.UTC(),
@@ -692,7 +922,10 @@ func (c *Client) FinishWorkflowExecutionStatisticViaExitHandler(namespace, name
"finished_at": time.Now().UTC(),
"phase": phase,
}).
Where(sq.Eq{"name": name}).
Where(sq.And{
sq.Eq{"name": name},
sq.NotEq{"phase": "Terminated"},
}).
RunWith(c.DB).
Exec()
@@ -734,6 +967,7 @@ func (c *Client) CronStartWorkflowExecutionStatisticInsert(namespace, uid string
"cron_workflow_id": cronWorkflow.ID,
"parameters": string(parametersJSON),
"labels": cronWorkflow.Labels,
"metrics": Metrics{},
}).
Suffix("RETURNING id").
RunWith(c.DB).
@@ -1302,7 +1536,7 @@ func (c *Client) TerminateWorkflowExecution(namespace, uid string) (err error) {
return err
}
err = argoutil.TerminateWorkflow(c.ArgoprojV1alpha1().Workflows(namespace), uid)
err = argoutil.StopWorkflow(c.ArgoprojV1alpha1().Workflows(namespace), uid, "", "")
return
}
@@ -1390,7 +1624,7 @@ func (c *Client) ListFiles(namespace, key string) (files []*File, err error) {
doneCh := make(chan struct{})
defer close(doneCh)
for objInfo := range s3Client.ListObjectsV2(config.ArtifactRepository.S3.Bucket, key, false, doneCh) {
for objInfo := range s3Client.ListObjects(config.ArtifactRepository.S3.Bucket, key, false, doneCh) {
if objInfo.Key == key {
continue
}
@@ -1732,17 +1966,18 @@ with statistics about the workflow that was just executed.
func getCURLNodeTemplate(name, curlMethod, curlPath, curlBody string, inputs wfv1.Inputs) (template *wfv1.Template, err error) {
host := "onepanel-core.onepanel.svc.cluster.local"
endpoint := fmt.Sprintf("http://%s%s", host, curlPath)
template = &wfv1.Template{
Name: name,
Inputs: inputs,
Container: &corev1.Container{
Name: "curl",
Image: "curlimages/curl",
Image: "curlimages/curl:7.73.0",
Command: []string{"sh", "-c"},
Args: []string{
"SERVICE_ACCOUNT_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) " +
"&& curl -X " + curlMethod + " -s -o /dev/null -w '%{http_code}' " +
"--connect-timeout 10 --retry 5 --retry-delay 5 " +
"--connect-timeout 10 --retry 10 --retry-delay 5 --retry-all-errors --fail " +
"'" + endpoint + "' -H \"Content-Type: application/json\" -H 'Connection: keep-alive' -H 'Accept: application/json' " +
"-H 'Authorization: Bearer '\"$SERVICE_ACCOUNT_TOKEN\"'' " +
"--data '" + curlBody + "' --compressed",
@@ -1858,13 +2093,13 @@ func injectWorkflowExecutionStatusCaller(wf *wfv1.Workflow, phase wfv1.NodePhase
for j, task := range t.DAG.Tasks {
if task.Dependencies == nil {
wf.Spec.Templates[i].DAG.Tasks[j].Dependencies = []string{containerTemplate.Name}
wf.Spec.Templates[i].DAG.Tasks = append(t.DAG.Tasks, wfv1.DAGTask{
Name: containerTemplate.Name,
Template: containerTemplate.Name,
})
}
}
}
wf.Spec.Templates[i].DAG.Tasks = append(t.DAG.Tasks, wfv1.DAGTask{
Name: containerTemplate.Name,
Template: containerTemplate.Name,
})
break
}
}
@@ -1901,14 +2136,14 @@ func workflowExecutionsSelectBuilderNoColumns(namespace, workflowTemplateUID, wo
func workflowExecutionsSelectBuilder(namespace, workflowTemplateUID, workflowTemplateVersion string, includeSystem bool) sq.SelectBuilder {
sb := workflowExecutionsSelectBuilderNoColumns(namespace, workflowTemplateUID, workflowTemplateVersion, includeSystem)
sb = sb.Columns(getWorkflowExecutionColumns("we", "")...).
sb = sb.Columns(getWorkflowExecutionColumns("we")...).
Columns(`wtv.version "workflow_template.version"`, `wtv.created_at "workflow_template.created_at"`, `wt.name "workflow_template.name"`, `wt.uid "workflow_template.uid"`)
return sb
}
func (c *Client) getWorkflowExecutionAndTemplate(namespace string, uid string) (workflow *WorkflowExecution, err error) {
sb := sb.Select(getWorkflowExecutionColumns("we", "")...).
sb := sb.Select(getWorkflowExecutionColumns("we")...).
Columns(getWorkflowTemplateColumns("wt", "workflow_template")...).
Columns(`wtv.manifest "workflow_template.manifest"`, `wtv.version "workflow_template.version"`).
From("workflow_executions we").
@@ -1958,3 +2193,57 @@ func (c *Client) UpdateWorkflowExecutionStatus(namespace, uid string, status *Wo
return
}
// AddWorkflowExecutionMetrics merges the metrics provided with the ones present in the workflow execution identified by (namespace, uid)
func (c *Client) AddWorkflowExecutionMetrics(namespace, uid string, metrics Metrics, override bool) (workflowExecution *WorkflowExecution, err error) {
workflowExecution, err = c.GetWorkflowExecution(namespace, uid)
if err != nil {
return nil, err
}
if workflowExecution == nil {
return nil, util.NewUserError(codes.NotFound, "Workflow execution not found")
}
workflowExecution.Metrics.Merge(metrics, override)
_, err = sb.Update("workflow_executions").
Set("metrics", workflowExecution.Metrics).
Where(sq.Eq{
"namespace": namespace,
"uid": uid,
}).
RunWith(c.DB).
Exec()
if err != nil {
return nil, util.NewUserError(codes.Internal, "Error updating metrics.")
}
return
}
// UpdateWorkflowExecutionMetrics replaces the metrics of a workflow execution identified by (namespace, uid) with the input metrics.
func (c *Client) UpdateWorkflowExecutionMetrics(namespace, uid string, metrics Metrics) (workflowExecution *WorkflowExecution, err error) {
workflowExecution, err = c.GetWorkflowExecution(namespace, uid)
if err != nil {
return nil, err
}
if workflowExecution == nil {
return nil, util.NewUserError(codes.NotFound, "Workflow execution not found")
}
workflowExecution.Metrics = metrics
_, err = sb.Update("workflow_executions").
Set("metrics", workflowExecution.Metrics).
Where(sq.Eq{
"namespace": namespace,
"uid": uid,
}).
RunWith(c.DB).
Exec()
if err != nil {
return nil, util.NewUserError(codes.Internal, "Error updating metrics.")
}
return
}

View File

@@ -25,6 +25,7 @@ type WorkflowExecution struct {
FinishedAt *time.Time `db:"finished_at"`
WorkflowTemplate *WorkflowTemplate `db:"workflow_template"`
Labels types.JSONLabels
Metrics Metrics
ArgoWorkflow *wfv1.Workflow
}
@@ -105,7 +106,18 @@ func (we *WorkflowExecution) GetParameterValue(name string) *string {
// getWorkflowExecutionColumns returns all of the columns for workflowExecution modified by alias, destination.
// see formatColumnSelect
func getWorkflowExecutionColumns(aliasAndDestination ...string) []string {
columns := []string{"id", "created_at", "uid", "name", "parameters", "phase", "started_at", "finished_at", "labels"}
columns := []string{
"id",
"created_at",
"uid",
"name",
"parameters",
"phase",
"started_at",
"finished_at",
"labels",
"metrics",
}
return sql.FormatColumnSelect(columns, aliasAndDestination...)
}
@@ -119,6 +131,7 @@ func getWorkflowExecutionColumnsMap(camelCase bool) map[string]string {
"parameters": "parameters",
"phase": "phase",
"labels": "labels",
"metrics": "metrics",
}
if camelCase {

View File

@@ -27,22 +27,27 @@ type WorkflowTemplateFilter struct {
Labels []*Label
}
// applyLabelSelectQuery returns a query builder that adds where statements to filter by labels in the request,
// if there are any
func applyLabelSelectQuery(sb sq.SelectBuilder, request *request.Request) sq.SelectBuilder {
if request.Filter != nil {
filter, ok := request.Filter.(WorkflowTemplateFilter)
if ok && len(filter.Labels) > 0 {
labelsJSON, err := LabelsToJSONString(filter.Labels)
if err != nil {
log.Printf("[error] %v", err)
} else {
sb = sb.Where("wt.labels @> ?", labelsJSON)
}
}
// GetLabels returns the labels in the filter
func (wt *WorkflowTemplateFilter) GetLabels() []*Label {
return wt.Labels
}
func applyWorkflowTemplateFilter(sb sq.SelectBuilder, request *request.Request) (sq.SelectBuilder, error) {
if !request.HasFilter() {
return sb, nil
}
return sb
filter, ok := request.Filter.(WorkflowTemplateFilter)
if !ok {
return sb, nil
}
sb, err := ApplyLabelSelectQuery("wt.labels", sb, &filter)
if err != nil {
return sb, err
}
return sb, nil
}
// createWorkflowTemplateVersionDB inserts a record into workflow_template_versions using the current time accurate to nanoseconds
@@ -414,14 +419,18 @@ func (c *Client) listWorkflowTemplateVersions(namespace, uid string) (workflowTe
return
}
func (c *Client) selectWorkflowTemplatesQuery(namespace string, request *request.Request) (sb sq.SelectBuilder) {
func (c *Client) selectWorkflowTemplatesQuery(namespace string, request *request.Request) (sb sq.SelectBuilder, err error) {
sb = c.workflowTemplatesSelectBuilder(namespace).
Column("COUNT(wtv.*) versions, MAX(wtv.id) workflow_template_version_id").
Join("workflow_template_versions wtv ON wtv.workflow_template_id = wt.id").
GroupBy("wt.id", "wt.created_at", "wt.uid", "wt.name", "wt.is_archived").
OrderBy("wt.created_at DESC")
sb = applyLabelSelectQuery(sb, request)
sb, err = applyWorkflowTemplateFilter(sb, request)
if err != nil {
return
}
sb = *request.ApplyPaginationToSelect(&sb)
return
@@ -432,11 +441,15 @@ func (c *Client) selectWorkflowTemplatesQuery(namespace string, request *request
func (c *Client) selectWorkflowTemplatesDB(namespace string, request *request.Request) (workflowTemplates []*WorkflowTemplate, err error) {
workflowTemplates = make([]*WorkflowTemplate, 0)
sb := c.selectWorkflowTemplatesQuery(namespace, request).
Where(sq.Eq{
"wt.is_archived": false,
"wt.is_system": false,
})
sb, err := c.selectWorkflowTemplatesQuery(namespace, request)
if err != nil {
return nil, err
}
sb = sb.Where(sq.Eq{
"wt.is_archived": false,
"wt.is_system": false,
})
err = c.DB.Selectx(&workflowTemplates, sb)
@@ -448,7 +461,11 @@ func (c *Client) selectWorkflowTemplatesDB(namespace string, request *request.Re
func (c *Client) selectAllWorkflowTemplatesDB(namespace string, request *request.Request) (workflowTemplates []*WorkflowTemplate, err error) {
workflowTemplates = make([]*WorkflowTemplate, 0)
sb := c.selectWorkflowTemplatesQuery(namespace, request)
sb, err := c.selectWorkflowTemplatesQuery(namespace, request)
if err != nil {
return nil, err
}
err = c.DB.Selectx(&workflowTemplates, sb)
return
@@ -465,7 +482,10 @@ func (c *Client) CountWorkflowTemplates(namespace string, request *request.Reque
"wt.is_system": false,
})
sb = applyLabelSelectQuery(sb, request)
sb, err = applyWorkflowTemplateFilter(sb, request)
if err != nil {
return 0, err
}
err = sb.RunWith(c.DB).
QueryRow().

View File

@@ -11,12 +11,12 @@ import (
"github.com/ghodss/yaml"
"github.com/lib/pq"
"github.com/onepanelio/core/pkg/util"
"github.com/onepanelio/core/pkg/util/env"
"github.com/onepanelio/core/pkg/util/ptr"
"github.com/onepanelio/core/pkg/util/request"
log "github.com/sirupsen/logrus"
"google.golang.org/grpc/codes"
corev1 "k8s.io/api/core/v1"
"strconv"
"strings"
"time"
)
@@ -122,8 +122,8 @@ func updateWorkspaceStatusBuilder(namespace, uid string, status *WorkspaceStatus
}
// mergeWorkspaceParameters combines two parameter arrays. If a parameter in newParameters is not in
// the existing ones, it is added. If it is, it is ignored.
func mergeWorkspaceParameters(existingParameters, newParameters []Parameter) (parameters []Parameter) {
// the existing ones, it is added. If it is and override is true, it is replaced. Otherwise it is ignored.
func mergeWorkspaceParameters(existingParameters, newParameters []Parameter, override bool) (parameters []Parameter) {
parameterMap := make(map[string]*string, 0)
for _, p := range newParameters {
parameterMap[p.Name] = p.Value
@@ -134,12 +134,14 @@ func mergeWorkspaceParameters(existingParameters, newParameters []Parameter) (pa
}
for _, p := range existingParameters {
_, ok := parameterMap[p.Name]
newValue, ok := parameterMap[p.Name]
if !ok {
parameters = append(parameters, Parameter{
Name: p.Name,
Value: p.Value,
})
} else {
p.Value = newValue
}
}
@@ -169,7 +171,7 @@ func injectWorkspaceSystemParameters(namespace string, workspace *Workspace, wor
Value: ptr.String(host),
},
}
workspace.Parameters = mergeWorkspaceParameters(workspace.Parameters, systemParameters)
workspace.Parameters = mergeWorkspaceParameters(workspace.Parameters, systemParameters, false)
return
}
@@ -225,7 +227,7 @@ func (c *Client) createWorkspace(namespace string, parameters []byte, workspace
templates := argoTemplate.Spec.Templates
for i, t := range templates {
if t.Name == WorkspaceStatefulSetResource {
resultManifest, err := c.addResourceRequestsAndLimitsToWorkspaceTemplate(t, argoTemplate, workspace)
resultManifest, err := c.addRuntimeFieldsToWorkspaceTemplate(t, workspace, systemConfig)
if err != nil {
return nil, err
}
@@ -267,9 +269,9 @@ func (c *Client) createWorkspace(namespace string, parameters []byte, workspace
return workspace, nil
}
// addResourceRequestsAndLimitsToWorkspaceTemplate will take the workspace statefulset resource
// addRuntimeFieldsToWorkspaceTemplate will take the workspace statefulset resource
// and attempt to figure out the resources it requests, based on the Node selected.
func (c *Client) addResourceRequestsAndLimitsToWorkspaceTemplate(t wfv1.Template, argoTemplate *wfv1.WorkflowTemplate, workspace *Workspace) ([]byte, error) {
func (c *Client) addRuntimeFieldsToWorkspaceTemplate(t wfv1.Template, workspace *Workspace, config SystemConfig) ([]byte, error) {
//due to placeholders, we can't unmarshal into a k8s statefulset
statefulSet := map[string]interface{}{}
if err := yaml.Unmarshal([]byte(t.Resource.Manifest), &statefulSet); err != nil {
@@ -287,26 +289,8 @@ func (c *Client) addResourceRequestsAndLimitsToWorkspaceTemplate(t wfv1.Template
if !ok {
return nil, errors.New("unable to type check statefulset manifest")
}
//Get node selected
labelKey := "sys-node-pool-label"
labelKeyVal := ""
for _, parameter := range argoTemplate.Spec.Arguments.Parameters {
if parameter.Name == labelKey {
labelKeyVal = *parameter.Value
}
}
extraContainer := generateNodeCaptureContainer(workspace, config)
nodePoolKey := "sys-node-pool"
nodePoolVal := ""
for _, parameter := range workspace.Parameters {
if parameter.Name == nodePoolKey {
nodePoolVal = *parameter.Value
}
}
extraContainer, err := generateExtraContainerWithResources(c, labelKeyVal, nodePoolVal)
if err != nil {
return nil, err
}
if extraContainer != nil {
containers, ok := templateSpec["containers"].([]interface{})
if !ok {
@@ -315,6 +299,62 @@ func (c *Client) addResourceRequestsAndLimitsToWorkspaceTemplate(t wfv1.Template
templateSpec["containers"] = append([]interface{}{extraContainer}, containers...)
}
containerJSON, err := json.Marshal(templateSpec["containers"])
if err != nil {
return nil, fmt.Errorf("unable to marshal containers from json spec")
}
containers := make([]*corev1.Container, 0)
if err := json.Unmarshal(containerJSON, &containers); err != nil {
return nil, err
}
mainContainerIndex := -1
if len(containers) == 2 {
// It's 1 because we prepend the node capture container and we want the other container to be main
mainContainerIndex = 1
}
for i := range containers {
container := containers[i]
// Main containers must have the ONEPANEL_MAIN_CONTAINER environment variable
for _, envVar := range container.Env {
if envVar.Name == "ONEPANEL_MAIN_CONTAINER" {
mainContainerIndex = i
break
}
}
env.AddDefaultEnvVarsToContainer(container)
env.PrependEnvVarToContainer(container, "ONEPANEL_API_URL", config["ONEPANEL_API_URL"])
env.PrependEnvVarToContainer(container, "ONEPANEL_FQDN", config["ONEPANEL_FQDN"])
env.PrependEnvVarToContainer(container, "ONEPANEL_DOMAIN", config["ONEPANEL_DOMAIN"])
env.PrependEnvVarToContainer(container, "ONEPANEL_PROVIDER", config["ONEPANEL_PROVIDER"])
env.PrependEnvVarToContainer(container, "ONEPANEL_RESOURCE_NAMESPACE", "{{workflow.namespace}}")
env.PrependEnvVarToContainer(container, "ONEPANEL_RESOURCE_UID", "{{workflow.parameters.sys-uid}}")
}
if mainContainerIndex != -1 {
// Add resource limits for GPUs
nodePoolVal := ""
for _, parameter := range workspace.Parameters {
if parameter.Name == "sys-node-pool" {
nodePoolVal = *parameter.Value
}
}
n, err := config.NodePoolOptionByValue(nodePoolVal)
if err != nil {
return nil, err
}
if n != nil && n.Resources.Limits != nil {
containers[mainContainerIndex].Resources = n.Resources
}
}
templateSpec["containers"] = containers
resultManifest, err := yaml.Marshal(statefulSet)
if err != nil {
return nil, err
@@ -322,93 +362,26 @@ func (c *Client) addResourceRequestsAndLimitsToWorkspaceTemplate(t wfv1.Template
return resultManifest, nil
}
// generateExtraContainerWithResources will add an extra container to a workspace.
// The extra container will have the calculated resource request for the node selected by the workspace.
// generateNodeCaptureContainer will add an extra container to a workspace.
// The extra container have a hostPort set. Kubernetes will ensure the hostPort does not get conflict
// between containers, scheduling a new node as needed.
// The container will sleep once started, and generally consume negligible resources.
//
// The node that was selected has to be already running, in order to get the resource request correct.
func generateExtraContainerWithResources(c *Client, labelKeyVal string, nodePoolVal string) (map[string]interface{}, error) {
runningNodes, err := c.Interface.CoreV1().Nodes().List(ListOptions{})
if err != nil {
return nil, err
func generateNodeCaptureContainer(workspace *Workspace, config SystemConfig) map[string]interface{} {
extraContainer := map[string]interface{}{
"image": "alpine:latest",
"name": "node-capturer",
"command": []interface{}{"/bin/sh"},
"args": []interface{}{"-c", "while :; do sleep 2073600; done"},
"ports": []interface{}{
map[string]interface{}{
"name": "node-capturer",
"hostPort": 80,
"containerPort": 80,
},
},
}
for _, node := range runningNodes.Items {
cpu, memory, gpu, gpuManufacturer := CalculateResourceRequirements(node, labelKeyVal, nodePoolVal)
if cpu != "" && memory != "" {
extraContainer := map[string]interface{}{
"image": "alpine:latest",
"name": "resource-requester",
"command": []interface{}{"/bin/sh"},
"args": []interface{}{"-c", "while :; do sleep 2073600; done"},
"resources": map[string]interface{}{
"requests": map[string]interface{}{
"cpu": cpu,
"memory": memory,
},
"limits": map[string]interface{}{},
},
}
if gpu > 0 {
res, ok := extraContainer["resources"].(map[string]interface{})
if !ok {
return nil, errors.New("unable to type check extraContainer")
}
reqs, ok := res["requests"].(map[string]interface{})
if !ok {
return nil, errors.New("unable to type check extraContainer")
}
reqs[gpuManufacturer] = gpu
limits, ok := res["limits"].(map[string]interface{})
if !ok {
return nil, errors.New("unable to type check extraContainer")
}
limits[gpuManufacturer] = gpu
}
//process only one node
return extraContainer, err
}
}
return nil, nil
}
// CalculateResourceRequirements will take the passed in Node and try to figure out the
// allocatable capacity. Once the capacity is discovered, function figures out how to request 90%.
// - We use 90% because manual calculation is error prone and not necessarily reliable.
// Params:
// k8sInstanceTypeLabel - Such as 'beta.kubernetes.io/instance-type'
// nodeSelectorValue - Server/VM Type Name, Such as "Standard_NC6", on Azure.
func CalculateResourceRequirements(node corev1.Node, k8sInstanceTypeLabel string, nodeSelectorValue string) (string, string, int64, string) {
var cpu string
var memory string
var gpu int64
gpuManufacturer := ""
if node.Labels[k8sInstanceTypeLabel] == nodeSelectorValue {
cpuInt := node.Status.Allocatable.Cpu().MilliValue()
cpu = strconv.FormatFloat(float64(cpuInt)*.9, 'f', 0, 64) + "m"
memoryInt := node.Status.Allocatable.Memory().MilliValue()
kiBase := 1024.0
ninetyPerc := float64(memoryInt) * .9
toKi := ninetyPerc / kiBase / kiBase
memory = strconv.FormatFloat(toKi, 'f', 0, 64) + "Ki"
//Check for Nvidia
gpuQuantity := node.Status.Allocatable["nvidia.com/gpu"]
if gpuQuantity.IsZero() == false {
gpu = gpuQuantity.Value()
gpuManufacturer = "nvidia.com/gpu"
}
//Check for AMD
//Source: https://github.com/RadeonOpenCompute/k8s-device-plugin/blob/master/example/pod/alexnet-gpu.yaml
gpuQuantity = node.Status.Allocatable["amd.com/gpu"]
if gpuQuantity.IsZero() == false {
gpu = gpuQuantity.Value()
gpuManufacturer = "amd.com/gpu"
}
}
return cpu, memory, gpu, gpuManufacturer
return extraContainer
}
// startWorkspace starts a workspace and related resources. It assumes a DB record already exists
@@ -462,7 +435,7 @@ func (c *Client) startWorkspace(namespace string, parameters []byte, workspace *
templates := argoTemplate.Spec.Templates
for i, t := range templates {
if t.Name == WorkspaceStatefulSetResource {
resultManifest, err := c.addResourceRequestsAndLimitsToWorkspaceTemplate(t, argoTemplate, workspace)
resultManifest, err := c.addRuntimeFieldsToWorkspaceTemplate(t, workspace, systemConfig)
if err != nil {
return nil, err
}
@@ -790,7 +763,7 @@ func (c *Client) updateWorkspace(namespace, uid, workspaceAction, resourceAction
return
}
workspace.Parameters = mergeWorkspaceParameters(workspace.Parameters, parameters)
workspace.Parameters = mergeWorkspaceParameters(workspace.Parameters, parameters, true)
parametersJSON, err := json.Marshal(workspace.Parameters)
if err != nil {
return
@@ -823,10 +796,9 @@ func (c *Client) updateWorkspace(namespace, uid, workspaceAction, resourceAction
workspace.WorkspaceTemplate = workspaceTemplate
templates := workspace.WorkspaceTemplate.WorkflowTemplate.ArgoWorkflowTemplate.Spec.Templates
argoTemplate := workspace.WorkspaceTemplate.WorkflowTemplate.ArgoWorkflowTemplate
for i, t := range templates {
if t.Name == WorkspaceStatefulSetResource {
resultManifest, err := c.addResourceRequestsAndLimitsToWorkspaceTemplate(t, argoTemplate, workspace)
resultManifest, err := c.addRuntimeFieldsToWorkspaceTemplate(t, workspace, config)
if err != nil {
return err
}
@@ -845,7 +817,7 @@ func (c *Client) updateWorkspace(namespace, uid, workspaceAction, resourceAction
// Update parameters if they are passed in
if len(parameters) != 0 {
sb.Set("parameters", parametersJSON)
sb = sb.Set("parameters", parametersJSON)
}
_, err = sb.RunWith(c.DB).

View File

@@ -9,7 +9,6 @@ import (
wfv1 "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1"
"github.com/asaskevich/govalidator"
"github.com/onepanelio/core/pkg/util"
"github.com/onepanelio/core/pkg/util/env"
"github.com/onepanelio/core/pkg/util/ptr"
"github.com/onepanelio/core/pkg/util/request"
"github.com/onepanelio/core/pkg/util/router"
@@ -352,7 +351,7 @@ func createVirtualServiceManifest(spec *WorkspaceSpec) (virtualServiceManifest s
return
}
func createStatefulSetManifest(spec *WorkspaceSpec, config map[string]string, services []*Service) (statefulSetManifest string, err error) {
func createStatefulSetManifest(spec *WorkspaceSpec) (statefulSetManifest string, err error) {
var volumeClaims []map[string]interface{}
volumeClaimsMapped := make(map[string]bool)
// Add volumeClaims that the user has added first
@@ -395,18 +394,6 @@ func createStatefulSetManifest(spec *WorkspaceSpec, config map[string]string, se
// Automatically map the remaining ones
for i, c := range spec.Containers {
container := &spec.Containers[i]
env.AddDefaultEnvVarsToContainer(container)
env.PrependEnvVarToContainer(container, "ONEPANEL_API_URL", config["ONEPANEL_API_URL"])
env.PrependEnvVarToContainer(container, "ONEPANEL_FQDN", config["ONEPANEL_FQDN"])
env.PrependEnvVarToContainer(container, "ONEPANEL_DOMAIN", config["ONEPANEL_DOMAIN"])
env.PrependEnvVarToContainer(container, "ONEPANEL_PROVIDER", config["ONEPANEL_PROVIDER"])
env.PrependEnvVarToContainer(container, "ONEPANEL_RESOURCE_NAMESPACE", "{{workflow.namespace}}")
env.PrependEnvVarToContainer(container, "ONEPANEL_RESOURCE_UID", "{{workflow.parameters.sys-name}}")
for _, service := range services {
envName := fmt.Sprintf("ONEPANEL_SERVICES_%v_API_URL", strings.ToUpper(service.Name))
env.PrependEnvVarToContainer(container, envName, service.URL)
}
for _, v := range c.VolumeMounts {
if volumeClaimsMapped[v.Name] {
@@ -972,12 +959,7 @@ func (c *Client) generateWorkspaceTemplateWorkflowTemplate(workspaceTemplate *Wo
return nil, err
}
services, err := c.ListServices(workspaceTemplate.Namespace)
if err != nil {
return nil, err
}
statefulSetManifest, err := createStatefulSetManifest(workspaceSpec, config, services)
statefulSetManifest, err := createStatefulSetManifest(workspaceSpec)
if err != nil {
return nil, err
}
@@ -1158,6 +1140,19 @@ func (c *Client) UpdateWorkspaceTemplate(namespace string, workspaceTemplate *Wo
return workspaceTemplate, nil
}
// UpdateWorkspaceTemplateManifest updates a workspace template by creating a new version where the only difference is the manifest
func (c *Client) UpdateWorkspaceTemplateManifest(namespace, uid string, manifest string) (*WorkspaceTemplate, error) {
existingTemplate, err := c.GetWorkspaceTemplate(namespace, uid, 0)
if err != nil {
return nil, err
}
existingTemplate.UID = uid
existingTemplate.Manifest = manifest
return c.UpdateWorkspaceTemplate(namespace, existingTemplate)
}
// ListWorkspaceTemplates returns a list of workspace templates that are not archived, sorted by most recent created first
func (c *Client) ListWorkspaceTemplates(namespace string, request *request.Request) (workspaceTemplates []*WorkspaceTemplate, err error) {
sb := c.workspaceTemplatesSelectBuilder(namespace).

View File

@@ -2,9 +2,14 @@ package auth
import (
"context"
"crypto/md5"
"encoding/hex"
"errors"
"fmt"
"github.com/onepanelio/core/api"
"github.com/onepanelio/core/pkg/util"
log "github.com/sirupsen/logrus"
v12 "k8s.io/apimachinery/pkg/apis/meta/v1"
"net/http"
"strings"
@@ -27,6 +32,9 @@ const (
func getBearerToken(ctx context.Context) (*string, bool) {
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
log.WithFields(log.Fields{
"Method": "getBearerToken",
}).Error("Unable to get metadata from incoming context")
return nil, false
}
@@ -36,6 +44,9 @@ func getBearerToken(ctx context.Context) (*string, bool) {
return nil, false
}
t = strings.ReplaceAll(t, prefix, "")
if t == "null" {
return nil, false
}
return &t, true
}
@@ -55,20 +66,36 @@ func getBearerToken(ctx context.Context) (*string, bool) {
return &t, true
}
log.WithFields(log.Fields{
"Method": "getBearerToken",
}).Error("Unable to get BearerToken:", md)
return nil, false
}
func getClient(ctx context.Context, kubeConfig *v1.Config, db *v1.DB, sysConfig v1.SystemConfig) (context.Context, error) {
if kubeConfig == nil {
return nil, fmt.Errorf("getClient - nil passed in for kubeConfig")
}
if db == nil {
return nil, fmt.Errorf("getClient - nil passed in for db")
}
bearerToken, ok := getBearerToken(ctx)
if !ok {
return nil, status.Error(codes.Unauthenticated, `Missing or invalid "authorization" header.`)
}
if bearerToken == nil {
return nil, status.Error(codes.Unauthenticated, "Bearer token is nil")
}
kubeConfig.BearerToken = *bearerToken
client, err := v1.NewClient(kubeConfig, db, sysConfig)
if err != nil {
return nil, err
}
client.Token = kubeConfig.BearerToken
return context.WithValue(ctx, ContextClientKey, client), nil
}
@@ -98,6 +125,43 @@ func IsAuthorized(c *v1.Client, namespace, verb, group, resource, name string) (
return
}
func verifyLogin(client *v1.Client, tokenRequest *api.GetAccessTokenRequest) (rawToken string, err error) {
accountsList, err := client.CoreV1().ServiceAccounts("onepanel").List(v1.ListOptions{})
if err != nil {
return "", err
}
authTokenSecretName := ""
for _, serviceAccount := range accountsList.Items {
if serviceAccount.Name != tokenRequest.Username {
continue
}
for _, secret := range serviceAccount.Secrets {
if strings.Contains(secret.Name, "-token-") {
authTokenSecretName = secret.Name
break
}
}
}
if authTokenSecretName == "" {
return "", util.NewUserError(codes.InvalidArgument, fmt.Sprintf("unknown service account '%v'", tokenRequest.Username))
}
secret, err := client.CoreV1().Secrets("onepanel").Get(authTokenSecretName, v12.GetOptions{})
if err != nil {
return "", err
}
currentTokenBytes := md5.Sum(secret.Data["token"])
currentTokenString := hex.EncodeToString(currentTokenBytes[:])
if tokenRequest.Token != fmt.Sprintf("%s", currentTokenString) {
return "", util.NewUserError(codes.InvalidArgument, "token doesn't match what's on record")
}
return string(secret.Data["token"]), nil
}
// UnaryInterceptor performs authentication checks.
// The two main cases are:
// 1. Is the token valid? This is used for logging in.
@@ -105,6 +169,41 @@ func IsAuthorized(c *v1.Client, namespace, verb, group, resource, name string) (
func UnaryInterceptor(kubeConfig *v1.Config, db *v1.DB, sysConfig v1.SystemConfig) grpc.UnaryServerInterceptor {
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
// Check if the provided token is valid. This does not require a token in the header.
if info.FullMethod == "/api.AuthService/GetAccessToken" {
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
return resp, errors.New("unable to get metadata from incoming context")
}
getAccessTokenRequest, ok := req.(*api.GetAccessTokenRequest)
if !ok {
return resp, errors.New("invalid request object for GetAccessTokenRequest")
}
defaultClient, err := v1.GetDefaultClientWithDB(db)
if err != nil {
return nil, err
}
rawToken, err := verifyLogin(defaultClient, getAccessTokenRequest)
if err != nil {
return nil, err
}
sysConfig, err := defaultClient.GetSystemConfig()
if err != nil {
return nil, err
}
md.Set("authorization", "Bearer "+rawToken)
ctx, err = getClient(ctx, kubeConfig, db, sysConfig)
if err != nil {
ctx = nil
}
return handler(ctx, req)
}
if info.FullMethod == "/api.AuthService/IsValidToken" {
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
@@ -113,10 +212,29 @@ func UnaryInterceptor(kubeConfig *v1.Config, db *v1.DB, sysConfig v1.SystemConfi
tokenRequest, ok := req.(*api.IsValidTokenRequest)
if !ok {
return resp, errors.New("IsValidToken does not have correct request type")
return resp, errors.New("invalid request object for GetAccessTokenRequest")
}
getAccessTokenRequest := &api.GetAccessTokenRequest{
Username: tokenRequest.Username,
Token: tokenRequest.Token,
}
md.Set("authorization", tokenRequest.Token.Token)
defaultClient, err := v1.GetDefaultClientWithDB(db)
if err != nil {
return nil, err
}
rawToken, err := verifyLogin(defaultClient, getAccessTokenRequest)
if err != nil {
return nil, err
}
sysConfig, err := defaultClient.GetSystemConfig()
if err != nil {
return nil, err
}
md.Set("authorization", "Bearer "+rawToken)
ctx, err = getClient(ctx, kubeConfig, db, sysConfig)
if err != nil {

View File

@@ -50,13 +50,13 @@ func (a *AuthServer) IsAuthorized(ctx context.Context, request *api.IsAuthorized
return res, nil
}
func (a *AuthServer) IsValidToken(ctx context.Context, req *api.IsValidTokenRequest) (res *api.IsValidTokenResponse, err error) {
// GetAccessToken is an alias for IsValidToken. It returns a token given a username and hashed token.
func (a *AuthServer) GetAccessToken(ctx context.Context, req *api.GetAccessTokenRequest) (res *api.GetAccessTokenResponse, err error) {
if ctx == nil {
return nil, status.Error(codes.Unauthenticated, "Unauthenticated.")
return nil, status.Error(codes.Unauthenticated, "unauthenticated")
}
client := getClient(ctx)
err = a.isValidToken(err, client)
if err != nil {
return nil, err
@@ -66,10 +66,51 @@ func (a *AuthServer) IsValidToken(ctx context.Context, req *api.IsValidTokenRequ
if err != nil {
return
}
res = &api.IsValidTokenResponse{}
res.Domain = config["ONEPANEL_DOMAIN"]
return res, nil
domain := config.Domain()
if domain == nil {
return nil, fmt.Errorf("domain is not set")
}
res = &api.GetAccessTokenResponse{
Domain: *domain,
AccessToken: client.Token,
Username: req.Username,
}
return
}
// IsValidToken returns the appropriate token information given an md5 version of the token
// Deprecated: Use GetAccessToken instead
func (a *AuthServer) IsValidToken(ctx context.Context, req *api.IsValidTokenRequest) (res *api.IsValidTokenResponse, err error) {
if ctx == nil {
return nil, status.Error(codes.Unauthenticated, "unauthenticated")
}
client := getClient(ctx)
err = a.isValidToken(err, client)
if err != nil {
return nil, err
}
config, err := client.GetSystemConfig()
if err != nil {
return
}
domain := config.Domain()
if domain == nil {
return nil, fmt.Errorf("domain is not set")
}
res = &api.IsValidTokenResponse{
Domain: *domain,
Token: client.Token,
Username: req.Username,
}
return
}
func (a *AuthServer) isValidToken(err error, client *v1.Client) error {

View File

@@ -37,6 +37,65 @@ func MappingToKeyValue(mapping map[string]string) []*api.KeyValue {
return keyValues
}
// MetricsToAPI converts Metrics to the API version
func MetricsToAPI(metrics v1.Metrics) []*api.Metric {
result := make([]*api.Metric, 0)
for _, metric := range metrics {
newItem := &api.Metric{
Name: metric.Name,
Value: metric.Value,
Format: metric.Format,
}
result = append(result, newItem)
}
return result
}
// APIMetricsToCore converts []*api.Metric to v1.Metrics
func APIMetricsToCore(metrics []*api.Metric) v1.Metrics {
result := v1.Metrics{}
for _, metric := range metrics {
m := v1.Metric{
Name: metric.Name,
Value: metric.Value,
Format: metric.Format,
}
// We don't override anything because we want the input to match how the user entered it
// So if there are entries with the same name, that's fine.
result.Add(&m, false)
}
return result
}
// LabelsToKeyValues converts []*v1.Label to []*api.Label
func LabelsToKeyValues(labels []*v1.Label) []*api.KeyValue {
keyValues := make([]*api.KeyValue, 0)
for _, label := range labels {
keyValues = append(keyValues, LabelToKeyValue(label))
}
sort.Slice(keyValues, func(i, j int) bool {
return keyValues[i].Key < keyValues[j].Key
})
return keyValues
}
// LabelToKeyValue converts a *v1.Label to *api.Label
func LabelToKeyValue(label *v1.Label) *api.KeyValue {
return &api.KeyValue{
Key: label.Key,
Value: label.Value,
}
}
func ParameterOptionToAPI(option *v1.ParameterOption) *api.ParameterOption {
apiOption := &api.ParameterOption{
Name: option.Name,

View File

@@ -5,23 +5,25 @@ import (
"github.com/onepanelio/core/api"
v1 "github.com/onepanelio/core/pkg"
"github.com/onepanelio/core/server/auth"
"github.com/onepanelio/core/server/converter"
)
func resourceIdentifierToArgoResource(identifier string) string {
func getGroupAndResourceByIdentifier(identifier string) (group, resource string) {
group = "argoproj.io"
switch identifier {
case v1.TypeWorkflowTemplate:
return "workflowtemplates"
return group, "workflowtemplates"
case v1.TypeWorkflowTemplateVersion:
return "workflowtemplates"
return group, "workflowtemplates"
case v1.TypeWorkflowExecution:
return "workflows"
return group, "workflows"
case v1.TypeCronWorkflow:
return "cronworkflows"
return group, "cronworkflows"
case v1.TypeWorkspace:
return "statefulset"
return "onepanel.io", "workspaces"
}
return ""
return "", ""
}
func mapLabelsToKeyValue(labels []*v1.Label) []*api.KeyValue {
@@ -54,10 +56,10 @@ func NewLabelServer() *LabelServer {
}
func (s *LabelServer) GetLabels(ctx context.Context, req *api.GetLabelsRequest) (*api.GetLabelsResponse, error) {
argoResource := resourceIdentifierToArgoResource(req.Resource)
group, resource := getGroupAndResourceByIdentifier(req.Resource)
client := getClient(ctx)
allowed, err := auth.IsAuthorized(client, req.Namespace, "get", "argoproj.io", argoResource, "")
allowed, err := auth.IsAuthorized(client, req.Namespace, "get", group, resource, "")
if err != nil || !allowed {
return nil, err
}
@@ -73,10 +75,10 @@ func (s *LabelServer) GetLabels(ctx context.Context, req *api.GetLabelsRequest)
}
func (s *LabelServer) AddLabels(ctx context.Context, req *api.AddLabelsRequest) (*api.GetLabelsResponse, error) {
argoResource := resourceIdentifierToArgoResource(req.Resource)
group, resource := getGroupAndResourceByIdentifier(req.Resource)
client := getClient(ctx)
allowed, err := auth.IsAuthorized(client, req.Namespace, "create", "argoproj.io", argoResource, "")
allowed, err := auth.IsAuthorized(client, req.Namespace, "create", group, resource, "")
if err != nil || !allowed {
return nil, err
}
@@ -97,10 +99,10 @@ func (s *LabelServer) AddLabels(ctx context.Context, req *api.AddLabelsRequest)
}
func (s *LabelServer) ReplaceLabels(ctx context.Context, req *api.ReplaceLabelsRequest) (*api.GetLabelsResponse, error) {
argoResource := resourceIdentifierToArgoResource(req.Resource)
group, resource := getGroupAndResourceByIdentifier(req.Resource)
client := getClient(ctx)
allowed, err := auth.IsAuthorized(client, req.Namespace, "update", "argoproj.io", argoResource, "")
allowed, err := auth.IsAuthorized(client, req.Namespace, "update", group, resource, "")
if err != nil || !allowed {
return nil, err
}
@@ -121,11 +123,11 @@ func (s *LabelServer) ReplaceLabels(ctx context.Context, req *api.ReplaceLabelsR
}
func (s *LabelServer) DeleteLabel(ctx context.Context, req *api.DeleteLabelRequest) (*api.GetLabelsResponse, error) {
argoResource := resourceIdentifierToArgoResource(req.Resource)
group, resource := getGroupAndResourceByIdentifier(req.Resource)
client := getClient(ctx)
// update verb here since we are not deleting the resource, but labels
allowed, err := auth.IsAuthorized(client, req.Namespace, "update", "argoproj.io", argoResource, "")
allowed, err := auth.IsAuthorized(client, req.Namespace, "update", group, resource, "")
if err != nil || !allowed {
return nil, err
}
@@ -146,3 +148,29 @@ func (s *LabelServer) DeleteLabel(ctx context.Context, req *api.DeleteLabelReque
Labels: mapLabelsToKeyValue(labels),
}, nil
}
// GetAvailableLabels returns the labels available for a resource specified by the GetAvailableLabelsRequest
func (s *LabelServer) GetAvailableLabels(ctx context.Context, req *api.GetAvailableLabelsRequest) (*api.GetLabelsResponse, error) {
group, resource := getGroupAndResourceByIdentifier(req.Resource)
client := getClient(ctx)
allowed, err := auth.IsAuthorized(client, req.Namespace, "get", group, resource, "")
if err != nil || !allowed {
return nil, err
}
labels, err := client.ListAvailableLabels(&v1.SelectLabelsQuery{
Table: v1.TypeToTableName(req.Resource),
Alias: "l",
Namespace: req.Namespace,
KeyLike: req.KeyLike + "%",
Skip: v1.SkipKeysFromString(req.SkipKeys),
})
if err != nil {
return nil, err
}
return &api.GetLabelsResponse{
Labels: converter.LabelsToKeyValues(labels),
}, nil
}

View File

@@ -40,6 +40,7 @@ func apiWorkflowExecution(wf *v1.WorkflowExecution, router router.Web) (workflow
Phase: string(wf.Phase),
Manifest: wf.Manifest,
Labels: converter.MappingToKeyValue(wf.Labels),
Metrics: converter.MetricsToAPI(wf.Metrics),
}
if wf.StartedAt != nil && !wf.StartedAt.IsZero() {
@@ -143,8 +144,7 @@ func (s *WorkflowServer) AddWorkflowExecutionStatistics(ctx context.Context, req
return &empty.Empty{}, err
}
err = client.FinishWorkflowExecutionStatisticViaExitHandler(req.Namespace, req.Uid,
req.Statistics.WorkflowTemplateId, phase, workflow.Status.StartedAt.UTC())
err = client.FinishWorkflowExecutionStatisticViaExitHandler(req.Namespace, req.Uid, phase, workflow.Status.StartedAt.UTC())
if err != nil {
return &empty.Empty{}, err
@@ -328,13 +328,19 @@ func (s *WorkflowServer) ListWorkflowExecutions(ctx context.Context, req *api.Li
return nil, err
}
totalCount, err := client.CountWorkflowExecutions(req.Namespace, "", "", req.IncludeSystem, nil)
if err != nil {
return nil, err
}
paginator := resourceRequest.Pagination
return &api.ListWorkflowExecutionsResponse{
Count: int32(len(apiWorkflowExecutions)),
WorkflowExecutions: apiWorkflowExecutions,
Page: int32(paginator.Page),
Pages: paginator.CalculatePages(count),
TotalCount: int32(count),
Count: int32(len(apiWorkflowExecutions)),
WorkflowExecutions: apiWorkflowExecutions,
Page: int32(paginator.Page),
Pages: paginator.CalculatePages(count),
TotalCount: int32(count),
TotalAvailableCount: int32(totalCount),
}, nil
}
@@ -468,3 +474,37 @@ func (s *WorkflowServer) GetWorkflowExecutionStatisticsForNamespace(ctx context.
Stats: converter.WorkflowExecutionStatisticsReportToAPI(report),
}, nil
}
// AddWorkflowExecutionMetrics merges the input metrics for the workflow execution identified by (namespace,uid)
func (s *WorkflowServer) AddWorkflowExecutionMetrics(ctx context.Context, req *api.AddWorkflowExecutionsMetricsRequest) (*api.WorkflowExecutionsMetricsResponse, error) {
client := getClient(ctx)
metrics := converter.APIMetricsToCore(req.Metrics)
workflowExecution, err := client.AddWorkflowExecutionMetrics(req.Namespace, req.Uid, metrics, req.Override)
if err != nil {
return nil, err
}
resp := &api.WorkflowExecutionsMetricsResponse{
Metrics: converter.MetricsToAPI(workflowExecution.Metrics),
}
return resp, nil
}
// UpdateWorkflowExecutionMetrics replaces the metrics with the input metrics for the workflow identified by (namespace, uid)
func (s *WorkflowServer) UpdateWorkflowExecutionMetrics(ctx context.Context, req *api.UpdateWorkflowExecutionsMetricsRequest) (*api.WorkflowExecutionsMetricsResponse, error) {
client := getClient(ctx)
metrics := converter.APIMetricsToCore(req.Metrics)
workflowExecution, err := client.UpdateWorkflowExecutionMetrics(req.Namespace, req.Uid, metrics)
if err != nil {
return nil, err
}
resp := &api.WorkflowExecutionsMetricsResponse{
Metrics: converter.MetricsToAPI(workflowExecution.Metrics),
}
return resp, nil
}

View File

@@ -43,6 +43,7 @@ func apiWorkflowTemplate(wft *v1.WorkflowTemplate) *api.WorkflowTemplate {
return res
}
// CreateWorkflowTemplate creates a workflow template and the initial version
func (s *WorkflowTemplateServer) CreateWorkflowTemplate(ctx context.Context, req *api.CreateWorkflowTemplateRequest) (*api.WorkflowTemplate, error) {
client := getClient(ctx)
allowed, err := auth.IsAuthorized(client, req.Namespace, "create", "argoproj.io", "workflowtemplates", "")
@@ -205,13 +206,19 @@ func (s *WorkflowTemplateServer) ListWorkflowTemplates(ctx context.Context, req
return nil, err
}
totalCount, err := client.CountWorkflowTemplates(req.Namespace, nil)
if err != nil {
return nil, err
}
paginator := resourceRequest.Pagination
return &api.ListWorkflowTemplatesResponse{
Count: int32(len(apiWorkflowTemplates)),
WorkflowTemplates: apiWorkflowTemplates,
Page: int32(paginator.Page),
Pages: paginator.CalculatePages(count),
TotalCount: int32(count),
Count: int32(len(apiWorkflowTemplates)),
WorkflowTemplates: apiWorkflowTemplates,
Page: int32(paginator.Page),
Pages: paginator.CalculatePages(count),
TotalCount: int32(count),
TotalAvailableCount: int32(totalCount),
}, nil
}

View File

@@ -252,13 +252,19 @@ func (s *WorkspaceServer) ListWorkspaces(ctx context.Context, req *api.ListWorks
return nil, err
}
totalCount, err := client.CountWorkspaces(req.Namespace, nil)
if err != nil {
return nil, err
}
paginator := resourceRequest.Pagination
return &api.ListWorkspaceResponse{
Count: int32(len(apiWorkspaces)),
Workspaces: apiWorkspaces,
Page: int32(paginator.Page),
Pages: paginator.CalculatePages(count),
TotalCount: int32(count),
Count: int32(len(apiWorkspaces)),
Workspaces: apiWorkspaces,
Page: int32(paginator.Page),
Pages: paginator.CalculatePages(count),
TotalCount: int32(count),
TotalAvailableCount: int32(totalCount),
}, nil
}
@@ -363,7 +369,7 @@ func (s *WorkspaceServer) RetryLastWorkspaceAction(ctx context.Context, req *api
func (s *WorkspaceServer) GetWorkspaceStatisticsForNamespace(ctx context.Context, req *api.GetWorkspaceStatisticsForNamespaceRequest) (*api.GetWorkspaceStatisticsForNamespaceResponse, error) {
client := getClient(ctx)
allowed, err := auth.IsAuthorized(client, req.Namespace, "list", "argoproj.io", "workspaces", "")
allowed, err := auth.IsAuthorized(client, req.Namespace, "list", "onepanel.io", "workspaces", "")
if err != nil || !allowed {
return nil, err
}