Compare commits

..

25 Commits

Author SHA1 Message Date
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
16 changed files with 309 additions and 117 deletions

View File

@@ -22,7 +22,7 @@ jobs:
- name: Notify Slack Channels
uses: rtCamp/action-slack-notify@v2.0.0
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

View File

@@ -2984,7 +2984,7 @@
"domain": {
"type": "string"
},
"jwtToken": {
"token": {
"type": "string"
},
"username": {

View File

@@ -265,7 +265,7 @@ type IsValidTokenResponse struct {
unknownFields protoimpl.UnknownFields
Domain string `protobuf:"bytes,1,opt,name=domain,proto3" json:"domain,omitempty"`
JwtToken string `protobuf:"bytes,2,opt,name=jwtToken,proto3" json:"jwtToken,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"`
}
@@ -308,9 +308,9 @@ func (x *IsValidTokenResponse) GetDomain() string {
return ""
}
func (x *IsValidTokenResponse) GetJwtToken() string {
func (x *IsValidTokenResponse) GetToken() string {
if x != nil {
return x.JwtToken
return x.Token
}
return ""
}
@@ -352,28 +352,28 @@ var file_auth_proto_rawDesc = []byte{
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, 0x66, 0x0a, 0x14, 0x49, 0x73, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x54,
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, 0x1a, 0x0a, 0x08, 0x6a, 0x77, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e,
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6a, 0x77, 0x74, 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, 0xe6, 0x01, 0x0a,
0x0b, 0x41, 0x75, 0x74, 0x68, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x68, 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, 0x23, 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, 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, 0x49, 0x73, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
0x7a, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x28, 0x82, 0xd3, 0xe4,
0x93, 0x02, 0x22, 0x22, 0x12, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74,
0x61, 0x31, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x3a, 0x0c, 0x69, 0x73, 0x41, 0x75, 0x74, 0x68, 0x6f,
0x72, 0x69, 0x7a, 0x65, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
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, 0x32, 0xe6, 0x01, 0x0a, 0x0b, 0x41, 0x75, 0x74, 0x68, 0x53,
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x68, 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, 0x23, 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, 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, 0x49, 0x73, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x28, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x22, 0x22, 0x12, 0x2f,
0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x75, 0x74,
0x68, 0x3a, 0x0c, 0x69, 0x73, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x62,
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (

View File

@@ -44,6 +44,6 @@ message IsValidTokenRequest {
message IsValidTokenResponse {
string domain = 1;
string jwtToken = 2;
string token = 2;
string username = 3;
}

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: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
# 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,25 @@
package migration
import (
"database/sql"
"github.com/pressly/goose"
)
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("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

@@ -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,7 @@ func Initialize() {
initialize20200929144301()
initialize20200929153931()
initialize20201001070806()
initialize20201016170415()
if err := client.DB.Close(); err != nil {
log.Printf("[error] closing db %v", err)
@@ -128,3 +132,17 @@ func ReplaceArtifactRepositoryType(client *v1.Client, namespace *v1.Namespace, w
return nil
}
// readDataFile returns the contents of a file in the db/data/{name} directory
func readDataFile(name string) (string, error) {
curDir, err := os.Getwd()
if err != nil {
return "", err
}
data, err := ioutil.ReadFile(filepath.Join(curDir, "db", "data", name))
if err != nil {
return "", err
}
return string(data), nil
}

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

@@ -0,0 +1,49 @@
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
}

View File

@@ -4,6 +4,7 @@ import (
"context"
"flag"
"fmt"
migrations "github.com/onepanelio/core/db/go"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
corev1 "k8s.io/api/core/v1"
@@ -25,7 +26,6 @@ import (
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/jmoiron/sqlx"
"github.com/onepanelio/core/api"
migrations "github.com/onepanelio/core/db/go"
v1 "github.com/onepanelio/core/pkg"
"github.com/onepanelio/core/pkg/util/env"
"github.com/onepanelio/core/server"

View File

@@ -57,6 +57,19 @@ func GetDefaultClient() (*Client, error) {
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) {

View File

@@ -1,48 +0,0 @@
package tokens
import (
"fmt"
"github.com/dgrijalva/jwt-go"
)
// TokenContent represents the content we store in a JWT token - the username and k8s token
type TokenContent struct {
Username string
Token string
}
// CreateJWTToken creates a jwt token containing a username and another token using the input secret
func CreateJWTToken(username string, token string, secret []byte) (string, error) {
result := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"username": username,
"token": token,
})
// Sign and get the complete encoded token as a string using the secret
return result.SignedString(secret)
}
// ParseJWTToken parses the token string into a TokenContent
func ParseJWTToken(tokenString string, secret []byte) (content *TokenContent, err error) {
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
// Don't forget to validate the alg is what you expect:
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
}
return secret, nil
})
if err != nil {
return nil, err
}
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
return &TokenContent{
Username: claims["username"].(string),
Token: claims["token"].(string),
}, nil
}
return nil, fmt.Errorf("Unknown error getting token, claim or token is not ok")
}

View File

@@ -1340,7 +1340,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
}
@@ -1851,14 +1851,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").

View File

@@ -401,7 +401,7 @@ func createStatefulSetManifest(spec *WorkspaceSpec, config map[string]string, se
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}}")
env.PrependEnvVarToContainer(container, "ONEPANEL_RESOURCE_UID", "{{workflow.parameters.sys-uid}}")
for _, service := range services {
envName := fmt.Sprintf("ONEPANEL_SERVICES_%v_API_URL", strings.ToUpper(service.Name))

View File

@@ -8,7 +8,6 @@ import (
"fmt"
"github.com/onepanelio/core/api"
"github.com/onepanelio/core/pkg/util"
"github.com/onepanelio/core/pkg/util/tokens"
v12 "k8s.io/apimachinery/pkg/apis/meta/v1"
"net/http"
"strings"
@@ -41,6 +40,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
}
@@ -69,15 +71,11 @@ func getClient(ctx context.Context, kubeConfig *v1.Config, db *v1.DB, sysConfig
return nil, status.Error(codes.Unauthenticated, `Missing or invalid "authorization" header.`)
}
tokenContent, err := tokens.ParseJWTToken(*bearerToken, sysConfig.HMACKey())
if err != nil {
return nil, err
if sysConfig["token"] != *bearerToken {
sysConfig["token"] = *bearerToken
}
sysConfig["jwtToken"] = *bearerToken
sysConfig["jwtUsername"] = tokenContent.Username
kubeConfig.BearerToken = tokenContent.Token
kubeConfig.BearerToken = *bearerToken
client, err := v1.NewClient(kubeConfig, db, sysConfig)
if err != nil {
@@ -167,7 +165,7 @@ func UnaryInterceptor(kubeConfig *v1.Config, db *v1.DB, sysConfig v1.SystemConfi
return resp, errors.New("LogInRequest does not have correct request type")
}
defaultClient, err := v1.GetDefaultClient()
defaultClient, err := v1.GetDefaultClientWithDB(db)
if err != nil {
return nil, err
}
@@ -182,17 +180,7 @@ func UnaryInterceptor(kubeConfig *v1.Config, db *v1.DB, sysConfig v1.SystemConfi
return nil, err
}
hmac := sysConfig.HMACKey()
if len(hmac) == 0 {
return nil, errors.New("HMAC key not found in secrets - this value is required")
}
jwtToken, err := tokens.CreateJWTToken(tokenRequest.Username, rawToken, hmac)
if err != nil {
return nil, err
}
md.Set("onepanel-auth-token", jwtToken)
md.Set("onepanel-auth-token", rawToken)
ctx, err = getClient(ctx, kubeConfig, db, sysConfig)
if err != nil {

View File

@@ -67,9 +67,8 @@ func (a *AuthServer) IsValidToken(ctx context.Context, req *api.IsValidTokenRequ
return
}
res = &api.IsValidTokenResponse{
Domain: config["ONEPANEL_DOMAIN"],
JwtToken: config["jwtToken"],
Username: config["jwtUsername"],
Domain: config["ONEPANEL_DOMAIN"],
Token: config["token"],
}
return res, nil

View File

@@ -7,21 +7,22 @@ import (
"github.com/onepanelio/core/server/auth"
)
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 +55,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 +74,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 +98,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 +122,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
}