diff --git a/operator/test.yaml b/operator/test.yaml
index 54938655..507a1487 100644
--- a/operator/test.yaml
+++ b/operator/test.yaml
@@ -19,38 +19,38 @@ spec:
limits:
cpu: "200m"
memory: "256Mi"
- # env:
- # - name: "REFLEX_USERNAME"
- # value: "admin"
- # - name: DEBUG
- # value: "true"
+ env:
+ - name: "REFLEX_USERNAME"
+ value: "admin"
+ - name: DEBUG
+ value: "true"
secrets:
- name: "REFLEX_PASSWORD"
value: "admin"
- name: "ANOTHER_SECRET"
value: "122"
- # volumes:
- # - name: "data"
- # mountPath: "/data"
- # size: "2Gi"
- # storageClass: "standard"
+ volumes:
+ - name: "data"
+ mountPath: "/data"
+ size: "2Gi"
+ storageClass: "standard"
interfaces:
- name: "http"
port: 80
- name: "https"
port: 443
- # ingress:
- # ingressClass: "nginx"
- # annotations:
- # nginx.ingress.kubernetes.io/rewrite-target: /
- # nginx.ingress.kubernetes.io/ssl-redirect: "false"
- # rules:
- # - host: "reflex.oneclickapps.dev"
- # path: "/test"
- # tls: false
- # - host: "reflex.oneclickapps.dev"
- # path: "/test"
- # tls: false
+ ingress:
+ ingressClass: "nginx"
+ annotations:
+ nginx.ingress.kubernetes.io/rewrite-target: /
+ nginx.ingress.kubernetes.io/ssl-redirect: "false"
+ rules:
+ - host: "reflex.oneclickapps.dev"
+ path: "/test"
+ tls: false
+ - host: "reflex.oneclickapps.dev"
+ path: "/test"
+ tls: false
# - name: "https"
# port: 8443
# ingress:
diff --git a/ui/frontend/.gitignore b/ui/frontend/.gitignore
index 6635cf55..1e744ba9 100644
--- a/ui/frontend/.gitignore
+++ b/ui/frontend/.gitignore
@@ -8,3 +8,4 @@ node_modules
!.env.example
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
+.node-red.json
diff --git a/ui/frontend/src/lib/components/base/Nav.svelte b/ui/frontend/src/lib/components/base/Nav.svelte
index c7c4f1b9..18a5225d 100644
--- a/ui/frontend/src/lib/components/base/Nav.svelte
+++ b/ui/frontend/src/lib/components/base/Nav.svelte
@@ -51,7 +51,7 @@
-
-
+ {/if}
+
diff --git a/ui/pocketbase/pb_migrations/1701789066_created_manifests.js b/ui/pocketbase/pb_migrations/1701789066_created_manifests.js
new file mode 100644
index 00000000..220c2914
--- /dev/null
+++ b/ui/pocketbase/pb_migrations/1701789066_created_manifests.js
@@ -0,0 +1,37 @@
+///
+migrate((db) => {
+ const collection = new Collection({
+ "id": "a3bwaaqkbj0nfdu",
+ "created": "2023-12-05 15:11:06.505Z",
+ "updated": "2023-12-05 15:11:06.505Z",
+ "name": "manifests",
+ "type": "base",
+ "system": false,
+ "schema": [
+ {
+ "system": false,
+ "id": "qze3nz4j",
+ "name": "json",
+ "type": "json",
+ "required": false,
+ "presentable": false,
+ "unique": false,
+ "options": {}
+ }
+ ],
+ "indexes": [],
+ "listRule": null,
+ "viewRule": null,
+ "createRule": null,
+ "updateRule": null,
+ "deleteRule": null,
+ "options": {}
+ });
+
+ return Dao(db).saveCollection(collection);
+}, (db) => {
+ const dao = new Dao(db);
+ const collection = dao.findCollectionByNameOrId("a3bwaaqkbj0nfdu");
+
+ return dao.deleteCollection(collection);
+})
diff --git a/ui/pocketbase/pb_migrations/1701789139_updated_manifests.js b/ui/pocketbase/pb_migrations/1701789139_updated_manifests.js
new file mode 100644
index 00000000..b860e45a
--- /dev/null
+++ b/ui/pocketbase/pb_migrations/1701789139_updated_manifests.js
@@ -0,0 +1,33 @@
+///
+migrate((db) => {
+ const dao = new Dao(db)
+ const collection = dao.findCollectionByNameOrId("a3bwaaqkbj0nfdu")
+
+ // add
+ collection.schema.addField(new SchemaField({
+ "system": false,
+ "id": "zrqmwzee",
+ "name": "rollout",
+ "type": "relation",
+ "required": false,
+ "presentable": false,
+ "unique": false,
+ "options": {
+ "collectionId": "22k6ts6gvnp46mc",
+ "cascadeDelete": false,
+ "minSelect": null,
+ "maxSelect": 1,
+ "displayFields": null
+ }
+ }))
+
+ return dao.saveCollection(collection)
+}, (db) => {
+ const dao = new Dao(db)
+ const collection = dao.findCollectionByNameOrId("a3bwaaqkbj0nfdu")
+
+ // remove
+ collection.schema.removeField("zrqmwzee")
+
+ return dao.saveCollection(collection)
+})
diff --git a/ui/pocketbase/pb_migrations/1701789200_updated_manifests.js b/ui/pocketbase/pb_migrations/1701789200_updated_manifests.js
new file mode 100644
index 00000000..37f30444
--- /dev/null
+++ b/ui/pocketbase/pb_migrations/1701789200_updated_manifests.js
@@ -0,0 +1,87 @@
+///
+migrate((db) => {
+ const dao = new Dao(db)
+ const collection = dao.findCollectionByNameOrId("a3bwaaqkbj0nfdu")
+
+ // add
+ collection.schema.addField(new SchemaField({
+ "system": false,
+ "id": "e70d5dls",
+ "name": "active",
+ "type": "bool",
+ "required": false,
+ "presentable": false,
+ "unique": false,
+ "options": {}
+ }))
+
+ // update
+ collection.schema.addField(new SchemaField({
+ "system": false,
+ "id": "zrqmwzee",
+ "name": "rollout",
+ "type": "relation",
+ "required": true,
+ "presentable": false,
+ "unique": false,
+ "options": {
+ "collectionId": "22k6ts6gvnp46mc",
+ "cascadeDelete": false,
+ "minSelect": null,
+ "maxSelect": 1,
+ "displayFields": null
+ }
+ }))
+
+ // update
+ collection.schema.addField(new SchemaField({
+ "system": false,
+ "id": "qze3nz4j",
+ "name": "json",
+ "type": "json",
+ "required": true,
+ "presentable": false,
+ "unique": false,
+ "options": {}
+ }))
+
+ return dao.saveCollection(collection)
+}, (db) => {
+ const dao = new Dao(db)
+ const collection = dao.findCollectionByNameOrId("a3bwaaqkbj0nfdu")
+
+ // remove
+ collection.schema.removeField("e70d5dls")
+
+ // update
+ collection.schema.addField(new SchemaField({
+ "system": false,
+ "id": "zrqmwzee",
+ "name": "rollout",
+ "type": "relation",
+ "required": false,
+ "presentable": false,
+ "unique": false,
+ "options": {
+ "collectionId": "22k6ts6gvnp46mc",
+ "cascadeDelete": false,
+ "minSelect": null,
+ "maxSelect": 1,
+ "displayFields": null
+ }
+ }))
+
+ // update
+ collection.schema.addField(new SchemaField({
+ "system": false,
+ "id": "qze3nz4j",
+ "name": "json",
+ "type": "json",
+ "required": false,
+ "presentable": false,
+ "unique": false,
+ "options": {}
+ }))
+
+ return dao.saveCollection(collection)
+})
diff --git a/ui/pocketbase/pb_migrations/1701789274_updated_manifests.js b/ui/pocketbase/pb_migrations/1701789274_updated_manifests.js
new file mode 100644
index 00000000..b7c9358f
--- /dev/null
+++ b/ui/pocketbase/pb_migrations/1701789274_updated_manifests.js
@@ -0,0 +1,63 @@
+///
+migrate((db) => {
+ const dao = new Dao(db)
+ const collection = dao.findCollectionByNameOrId("a3bwaaqkbj0nfdu")
+
+ // remove
+ collection.schema.removeField("e70d5dls")
+
+ // add
+ collection.schema.addField(new SchemaField({
+ "system": false,
+ "id": "nrwdaqpz",
+ "name": "startDate",
+ "type": "date",
+ "required": true,
+ "presentable": false,
+ "unique": false,
+ "options": {
+ "min": "",
+ "max": ""
+ }
+ }))
+
+ // add
+ collection.schema.addField(new SchemaField({
+ "system": false,
+ "id": "grnqhwti",
+ "name": "endDate",
+ "type": "date",
+ "required": false,
+ "presentable": false,
+ "unique": false,
+ "options": {
+ "min": "",
+ "max": ""
+ }
+ }))
+
+ return dao.saveCollection(collection)
+}, (db) => {
+ const dao = new Dao(db)
+ const collection = dao.findCollectionByNameOrId("a3bwaaqkbj0nfdu")
+
+ // add
+ collection.schema.addField(new SchemaField({
+ "system": false,
+ "id": "e70d5dls",
+ "name": "active",
+ "type": "bool",
+ "required": false,
+ "presentable": false,
+ "unique": false,
+ "options": {}
+ }))
+
+ // remove
+ collection.schema.removeField("nrwdaqpz")
+
+ // remove
+ collection.schema.removeField("grnqhwti")
+
+ return dao.saveCollection(collection)
+})
diff --git a/ui/pocketbase/pb_migrations/1701789313_deleted_manifests.js b/ui/pocketbase/pb_migrations/1701789313_deleted_manifests.js
new file mode 100644
index 00000000..29962ddd
--- /dev/null
+++ b/ui/pocketbase/pb_migrations/1701789313_deleted_manifests.js
@@ -0,0 +1,79 @@
+///
+migrate((db) => {
+ const dao = new Dao(db);
+ const collection = dao.findCollectionByNameOrId("a3bwaaqkbj0nfdu");
+
+ return dao.deleteCollection(collection);
+}, (db) => {
+ const collection = new Collection({
+ "id": "a3bwaaqkbj0nfdu",
+ "created": "2023-12-05 15:11:06.505Z",
+ "updated": "2023-12-05 15:14:34.816Z",
+ "name": "manifests",
+ "type": "base",
+ "system": false,
+ "schema": [
+ {
+ "system": false,
+ "id": "zrqmwzee",
+ "name": "rollout",
+ "type": "relation",
+ "required": true,
+ "presentable": false,
+ "unique": false,
+ "options": {
+ "collectionId": "22k6ts6gvnp46mc",
+ "cascadeDelete": false,
+ "minSelect": null,
+ "maxSelect": 1,
+ "displayFields": null
+ }
+ },
+ {
+ "system": false,
+ "id": "qze3nz4j",
+ "name": "json",
+ "type": "json",
+ "required": true,
+ "presentable": false,
+ "unique": false,
+ "options": {}
+ },
+ {
+ "system": false,
+ "id": "nrwdaqpz",
+ "name": "startDate",
+ "type": "date",
+ "required": true,
+ "presentable": false,
+ "unique": false,
+ "options": {
+ "min": "",
+ "max": ""
+ }
+ },
+ {
+ "system": false,
+ "id": "grnqhwti",
+ "name": "endDate",
+ "type": "date",
+ "required": false,
+ "presentable": false,
+ "unique": false,
+ "options": {
+ "min": "",
+ "max": ""
+ }
+ }
+ ],
+ "indexes": [],
+ "listRule": null,
+ "viewRule": null,
+ "createRule": null,
+ "updateRule": null,
+ "deleteRule": null,
+ "options": {}
+ });
+
+ return Dao(db).saveCollection(collection);
+})
diff --git a/ui/pocketbase/pkg/controller/rollouts.go b/ui/pocketbase/pkg/controller/rollouts.go
index 589cfb81..d1cad085 100644
--- a/ui/pocketbase/pkg/controller/rollouts.go
+++ b/ui/pocketbase/pkg/controller/rollouts.go
@@ -56,7 +56,7 @@ func HandleRolloutCreate(e *core.RecordCreateEvent, app *pocketbase.PocketBase)
}
// Delete rollout in k8s
- err = k8s.DeleteRollout(project.Id, running_rollout.Id)
+ err = k8s.DeleteRollout(project.Id, util.StringParser(project.GetString("name")), running_rollout.Id)
if err != nil {
log.Println(err)
return err
@@ -64,7 +64,7 @@ func HandleRolloutCreate(e *core.RecordCreateEvent, app *pocketbase.PocketBase)
}
// Create rollout in k8s
- err = k8s.CreateOrUpdateRollout(rolloutId, user, project.Id, e.Record.GetString("manifest"))
+ err = k8s.CreateOrUpdateRollout(rolloutId, util.StringParser(project.GetString("name")), user, project.Id, e.Record.GetString("manifest"))
if err != nil {
log.Println(err)
return err
@@ -102,7 +102,7 @@ func HandleRolloutUpdate(e *core.RecordUpdateEvent, app *pocketbase.PocketBase)
// Check if endDate is set, if yes, delete rollout
if e.Record.GetString("endDate") != "" {
- err = k8s.DeleteRollout(project.Id, rollout.Id)
+ err = k8s.DeleteRollout(project.Id, util.StringParser(project.GetString("name")), rollout.Id)
if err != nil {
log.Println(err)
return err
@@ -130,7 +130,7 @@ func HandleRolloutUpdate(e *core.RecordUpdateEvent, app *pocketbase.PocketBase)
}
// Delete rollout in k8s
- err = k8s.DeleteRollout(project.Id, running_rollout.Id)
+ err = k8s.DeleteRollout(project.Id, util.StringParser(project.GetString("name")), running_rollout.Id)
if err != nil {
log.Println(err)
return err
@@ -140,7 +140,7 @@ func HandleRolloutUpdate(e *core.RecordUpdateEvent, app *pocketbase.PocketBase)
e.Record.Set("startDate", time.Now().UTC().Format(time.RFC3339))
// If endDate was set before, but is not set anymore, create rollout again
- err = k8s.CreateOrUpdateRollout(rollout.Id, user, project.Id, e.Record.GetString("manifest"))
+ err = k8s.CreateOrUpdateRollout(rollout.Id, util.StringParser(project.GetString("name")), user, project.Id, e.Record.GetString("manifest"))
if err != nil {
log.Println(err)
return err
@@ -151,7 +151,7 @@ func HandleRolloutUpdate(e *core.RecordUpdateEvent, app *pocketbase.PocketBase)
} else {
e.Record.Set("startDate", time.Now().UTC().Format(time.RFC3339))
// Update rollout in k8s
- err = k8s.CreateOrUpdateRollout(rollout.Id, user, project.Id, e.Record.GetString("manifest"))
+ err = k8s.CreateOrUpdateRollout(rollout.Id, util.StringParser(project.GetString("name")), user, project.Id, e.Record.GetString("manifest"))
if err != nil {
log.Println(err)
return err
@@ -177,7 +177,7 @@ func HandleRolloutDelete(e *core.RecordDeleteEvent, app *pocketbase.PocketBase)
// Check if endDate is set, if no, delete rollout
if rollout.GetString("endDate") == "" {
- err = k8s.DeleteRollout(project.Id, rollout.Id)
+ err = k8s.DeleteRollout(project.Id, util.StringParser(project.GetString("name")), rollout.Id)
if err != nil {
log.Println(err)
}
@@ -187,8 +187,14 @@ func HandleRolloutDelete(e *core.RecordDeleteEvent, app *pocketbase.PocketBase)
}
func HandleRolloutStatus(c echo.Context, app *pocketbase.PocketBase, projectId string, rollout string) error {
+ // Get project
+ project, err := app.Dao().FindRecordById("projects", projectId)
+ if err != nil {
+ return err
+ }
+
// Get rollout status
- status, err := k8s.GetRolloutStatus(projectId, rollout)
+ status, err := k8s.GetRolloutStatus(projectId, util.StringParser(project.GetString("name")), rollout)
if err != nil {
log.Println(err)
return err
@@ -198,8 +204,14 @@ func HandleRolloutStatus(c echo.Context, app *pocketbase.PocketBase, projectId s
}
func HandleRolloutMetrics(c echo.Context, app *pocketbase.PocketBase, projectId string, rollout string) error {
+ // Get project
+ project, err := app.Dao().FindRecordById("projects", projectId)
+ if err != nil {
+ return err
+ }
+
// Get rollout metrics
- metrics, err := k8s.GetRolloutMetrics(projectId, rollout)
+ metrics, err := k8s.GetRolloutMetrics(projectId, util.StringParser(project.GetString("name")), rollout)
if err != nil {
log.Println(err)
return err
@@ -209,8 +221,14 @@ func HandleRolloutMetrics(c echo.Context, app *pocketbase.PocketBase, projectId
}
func HandleRolloutEvents(c echo.Context, app *pocketbase.PocketBase, projectId string, rollout string) error {
+ // Get project
+ project, err := app.Dao().FindRecordById("projects", projectId)
+ if err != nil {
+ return err
+ }
+
// Get rollout events
- events, err := k8s.GetRolloutEvents(projectId, rollout)
+ events, err := k8s.GetRolloutEvents(projectId, util.StringParser(project.GetString("name")), rollout)
if err != nil {
log.Println(err)
return err
diff --git a/ui/pocketbase/pkg/k8s/rollout.go b/ui/pocketbase/pkg/k8s/rollout.go
index 927ff4bf..f71dc13f 100644
--- a/ui/pocketbase/pkg/k8s/rollout.go
+++ b/ui/pocketbase/pkg/k8s/rollout.go
@@ -14,7 +14,7 @@ import (
"k8s.io/apimachinery/pkg/runtime/serializer/yaml"
)
-func CreateOrUpdateRollout(rolloutId string, user *pb_models.Record, projectId string, manifest string) error {
+func CreateOrUpdateRollout(rolloutId string, projectName string, user *pb_models.Record, projectId string, manifest string) error {
if rolloutId == "" {
return fmt.Errorf("rolloutId is required")
}
@@ -46,7 +46,7 @@ func CreateOrUpdateRollout(rolloutId string, user *pb_models.Record, projectId s
}
// Set the name and namespace to rolloutId and projectId
- obj.SetName(rolloutId)
+ obj.SetName(projectName)
obj.SetNamespace(projectId)
// Define the GroupVersionResource for the Rollout object
@@ -67,7 +67,7 @@ func CreateOrUpdateRollout(rolloutId string, user *pb_models.Record, projectId s
}
// Try to get the existing Rollout
- existingRollout, err := DynamicClient.Resource(rolloutGVR).Namespace(projectId).Get(Ctx, rolloutId, metav1.GetOptions{})
+ existingRollout, err := DynamicClient.Resource(rolloutGVR).Namespace(projectId).Get(Ctx, projectName, metav1.GetOptions{})
if err != nil {
// If not found, create it
_, err = DynamicClient.Resource(rolloutGVR).Namespace(projectId).Create(Ctx, obj, metav1.CreateOptions{})
@@ -88,7 +88,7 @@ func CreateOrUpdateRollout(rolloutId string, user *pb_models.Record, projectId s
return nil
}
-func DeleteRollout(projectId string, rolloutId string) error {
+func DeleteRollout(projectId string, projectName string, rolloutId string) error {
// Define the GroupVersionResource for the Rollout object
rolloutGVR := schema.GroupVersionResource{
Group: "one-click.io",
@@ -99,7 +99,7 @@ func DeleteRollout(projectId string, rolloutId string) error {
namespace := projectId
// Delete the Rollout
- err := DynamicClient.Resource(rolloutGVR).Namespace(namespace).Delete(Ctx, rolloutId, metav1.DeleteOptions{})
+ err := DynamicClient.Resource(rolloutGVR).Namespace(namespace).Delete(Ctx, projectName, metav1.DeleteOptions{})
if err != nil {
return fmt.Errorf("error deleting Rollout: %w", err)
}
@@ -107,7 +107,7 @@ func DeleteRollout(projectId string, rolloutId string) error {
return nil
}
-func GetRolloutStatus(projectId string, rolloutId string) (*models.RolloutStatus, error) {
+func GetRolloutStatus(projectId string, projectName string, rolloutId string) (*models.RolloutStatus, error) {
// Define the GroupVersionResource for the Rollout object
rolloutGVR := schema.GroupVersionResource{
Group: "one-click.io",
@@ -118,7 +118,7 @@ func GetRolloutStatus(projectId string, rolloutId string) (*models.RolloutStatus
namespace := projectId
// Get the Rollout
- rollout, err := DynamicClient.Resource(rolloutGVR).Namespace(namespace).Get(Ctx, rolloutId, metav1.GetOptions{})
+ rollout, err := DynamicClient.Resource(rolloutGVR).Namespace(namespace).Get(Ctx, projectName, metav1.GetOptions{})
if err != nil {
return nil, fmt.Errorf("error getting Rollout: %w", err)
}
@@ -139,11 +139,11 @@ func GetRolloutStatus(projectId string, rolloutId string) (*models.RolloutStatus
return &rolloutStatus, nil
}
-func GetRolloutMetrics(projectId string, rolloutId string) (*models.PodMetricsResponse, error) {
+func GetRolloutMetrics(projectId string, projectName string, rolloutId string) (*models.PodMetricsResponse, error) {
// List all pods in the projectId namespaced controlled by the rolloutId deployment
pods, err := Clientset.CoreV1().Pods(projectId).List(Ctx, metav1.ListOptions{
- LabelSelector: fmt.Sprintf("rollout.one-click.io/name=%s", rolloutId),
+ LabelSelector: fmt.Sprintf("rollout.one-click.io/name=%s", projectName),
})
if err != nil {
@@ -171,10 +171,10 @@ func GetRolloutMetrics(projectId string, rolloutId string) (*models.PodMetricsRe
return &podMetricsResponse, nil
}
-func GetRolloutEvents(projectId string, rolloutId string) (*models.EventResponse, error) {
+func GetRolloutEvents(projectId string, projectName string, rolloutId string) (*models.EventResponse, error) {
// List all events in the projectId namespaced controlled by the rolloutId deployment
events, err := Clientset.CoreV1().Events(projectId).List(Ctx, metav1.ListOptions{
- FieldSelector: fmt.Sprintf("involvedObject.name=%s", rolloutId),
+ FieldSelector: fmt.Sprintf("involvedObject.name=%s", projectName),
})
if err != nil {