diff --git a/cyctl/internal/create/template_auth_rules.go b/cyctl/internal/create/template_auth_rules.go
index 8da67219..377a3c6c 100644
--- a/cyctl/internal/create/template_auth_rules.go
+++ b/cyctl/internal/create/template_auth_rules.go
@@ -2,6 +2,7 @@ package create
import (
"encoding/json"
+ "errors"
"fmt"
"log"
"strings"
@@ -9,6 +10,7 @@ import (
"github.com/cyclops-ui/cyclops/cyclops-ctrl/api/v1alpha1"
"github.com/cyclops-ui/cyclops/cyclops-ctrl/api/v1alpha1/client"
"github.com/cyclops-ui/cycops-cyctl/internal/kubeconfig"
+ "github.com/manifoldco/promptui"
"github.com/spf13/cobra"
v1Spec "k8s.io/api/core/v1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -28,6 +30,74 @@ var (
password string
)
+func getTemplateAuthRulesFromPrompt() (string, string, string, string, string, error) {
+ RepoPrompt := promptui.Prompt{
+ Label: "repo",
+ }
+ repoValue, err := RepoPrompt.Run()
+ if err != nil {
+ return "", "", "", "", "", err
+ }
+
+ usernameNamePrompt := promptui.Prompt{
+ Label: "Username secret name",
+ Validate: func(input string) error {
+ if input == "" {
+ return errors.New("username secret name cannot be empty")
+ }
+ return nil
+ },
+ }
+ usernameName, err := usernameNamePrompt.Run()
+ if err != nil {
+ return "", "", "", "", "", err
+ }
+
+ usernameKeyPrompt := promptui.Prompt{
+ Label: "Username secret key",
+ Validate: func(input string) error {
+ if input == "" {
+ return errors.New("the username secret key cannot be empty")
+ }
+ return nil
+ },
+ }
+ usernameKey, err := usernameKeyPrompt.Run()
+ if err != nil {
+ return "", "", "", "", "", err
+ }
+
+ passwordNamePrompt := promptui.Prompt{
+ Label: "Password secret name",
+ Validate: func(input string) error {
+ if input == "" {
+ return errors.New("the password secret name cannot be empty")
+ }
+ return nil
+ },
+ }
+ passwordName, err := passwordNamePrompt.Run()
+ if err != nil {
+ return "", "", "", "", "", err
+ }
+
+ passwordKeyPrompt := promptui.Prompt{
+ Label: "Password secret key",
+ Validate: func(input string) error {
+ if input == "" {
+ return errors.New("password secret key cannot be empty")
+ }
+ return nil
+ },
+ }
+ passwordKey, err := passwordKeyPrompt.Run()
+ if err != nil {
+ return "", "", "", "", "", err
+ }
+
+ return usernameName, usernameKey, passwordName, passwordKey, repoValue, nil
+}
+
func validateSecretKeySelector(username, password string) (string, string, string, string, error) {
usernameName, usernameKey := splitNameKey(username)
passwordName, passwordKey := splitNameKey(password)
@@ -50,10 +120,27 @@ func splitNameKey(input string) (string, string) {
// createTemplateAuthRule allows you to create TemplateAuthRule Custom Resource.
func createTemplateAuthRule(clientset *client.CyclopsV1Alpha1Client, templateAuthRuleName string) {
- usernameName, usernameKey, passwordName, passwordKey, err := validateSecretKeySelector(username, password)
- if err != nil {
- fmt.Println(err)
- return
+ var (
+ usernameName string
+ passwordName string
+ usernameKey string
+ passwordKey string
+ )
+
+ if username == "" && password == "" && repo == "" {
+ var err error
+ usernameName, usernameKey, passwordName, passwordKey, repo, err = getTemplateAuthRulesFromPrompt()
+ if err != nil {
+ log.Fatal(err)
+ return
+ }
+ } else {
+ var err error
+ usernameName, usernameKey, passwordName, passwordKey, err = validateSecretKeySelector(username, password)
+ if err != nil {
+ log.Fatal(err)
+ return
+ }
}
var localObjectNameRef, localObjectPasswordRef v1Spec.LocalObjectReference
diff --git a/install/chart/Chart.yaml b/install/chart/Chart.yaml
index 228dec50..770a4689 100644
--- a/install/chart/Chart.yaml
+++ b/install/chart/Chart.yaml
@@ -2,8 +2,8 @@ apiVersion: v2
name: cyclops-chart
description: Cyclops Helm chart
type: application
-version: "0.9.0"
-appVersion: "v0.14.3"
+version: "0.11.0"
+appVersion: "v0.15.2"
home: https://cyclops-ui.com/
keywords:
- Devops
diff --git a/install/chart/values.yaml b/install/chart/values.yaml
index ade53f9a..be638bf4 100644
--- a/install/chart/values.yaml
+++ b/install/chart/values.yaml
@@ -9,64 +9,64 @@ ctrl:
ui:
replicas: 1
-templateStore:
- - name: demo
- repo: https://github.com/cyclops-ui/templates
- path: demo
- version: main
- iconURL: https://github.com/cyclops-ui/cyclops/blob/main/cyclops-ui/src/static/img/default-template-icon.png?raw=true
- sourceType: git
- - name: app-template
- repo: https://github.com/cyclops-ui/templates
- path: app-template
- version: main
- iconURL: https://github.com/cyclops-ui/cyclops/blob/main/cyclops-ui/src/static/img/default-template-icon.png?raw=true
- sourceType: git
- - name: jenkins
- repo: https://github.com/bitnami/charts
- path: bitnami/jenkins
- version: main
- iconURL: https://bitnami.com/assets/stacks/jenkins/img/jenkins-stack-220x234.png
- sourceType: git
- - name: mariadb
- repo: https://github.com/bitnami/charts
- path: bitnami/mariadb
- version: main
- iconURL: https://bitnami.com/assets/stacks/mariadb/img/mariadb-stack-220x234.png
- sourceType: git
- - name: metabase
- repo: https://github.com/cyclops-ui/templates
- path: metabase
- version: main
- iconURL: https://www.metabase.com/images/logo.svg
- sourceType: git
- - name: mysql
- repo: https://github.com/bitnami/charts
- path: bitnami/mysql
- version: main
- iconURL: https://bitnami.com/assets/stacks/mysql/img/mysql-stack-220x234.png
- sourceType: git
- - name: postgresql
- repo: https://github.com/bitnami/charts
- path: bitnami/postgresql
- version: main
- iconURL: https://bitnami.com/assets/stacks/postgresql/img/postgresql-stack-220x234.png
- sourceType: git
- - name: prometheus
- repo: https://github.com/bitnami/charts
- path: bitnami/prometheus
- version: main
- iconURL: https://bitnami.com/assets/stacks/prometheus/img/prometheus-stack-220x234.png
- sourceType: git
- - name: rabbitmq
- repo: https://github.com/bitnami/charts
- path: bitnami/rabbitmq
- version: main
- iconURL: https://bitnami.com/assets/stacks/rabbitmq/img/rabbitmq-stack-220x234.png
- sourceType: git
- - name: redis
- repo: https://github.com/bitnami/charts
- path: bitnami/redis
- version: main
- iconURL: https://bitnami.com/assets/stacks/redis/img/redis-stack-220x234.png
- sourceType: git
+#templateStore:
+# - name: demo
+# repo: https://github.com/cyclops-ui/templates
+# path: demo
+# version: main
+# iconURL: https://github.com/cyclops-ui/cyclops/blob/main/cyclops-ui/src/static/img/default-template-icon.png?raw=true
+# sourceType: git
+# - name: app-template
+# repo: https://github.com/cyclops-ui/templates
+# path: app-template
+# version: main
+# iconURL: https://github.com/cyclops-ui/cyclops/blob/main/cyclops-ui/src/static/img/default-template-icon.png?raw=true
+# sourceType: git
+# - name: jenkins
+# repo: https://github.com/bitnami/charts
+# path: bitnami/jenkins
+# version: main
+# iconURL: https://bitnami.com/assets/stacks/jenkins/img/jenkins-stack-220x234.png
+# sourceType: git
+# - name: mariadb
+# repo: https://github.com/bitnami/charts
+# path: bitnami/mariadb
+# version: main
+# iconURL: https://bitnami.com/assets/stacks/mariadb/img/mariadb-stack-220x234.png
+# sourceType: git
+# - name: metabase
+# repo: https://github.com/cyclops-ui/templates
+# path: metabase
+# version: main
+# iconURL: https://www.metabase.com/images/logo.svg
+# sourceType: git
+# - name: mysql
+# repo: https://github.com/bitnami/charts
+# path: bitnami/mysql
+# version: main
+# iconURL: https://bitnami.com/assets/stacks/mysql/img/mysql-stack-220x234.png
+# sourceType: git
+# - name: postgresql
+# repo: https://github.com/bitnami/charts
+# path: bitnami/postgresql
+# version: main
+# iconURL: https://bitnami.com/assets/stacks/postgresql/img/postgresql-stack-220x234.png
+# sourceType: git
+# - name: prometheus
+# repo: https://github.com/bitnami/charts
+# path: bitnami/prometheus
+# version: main
+# iconURL: https://bitnami.com/assets/stacks/prometheus/img/prometheus-stack-220x234.png
+# sourceType: git
+# - name: rabbitmq
+# repo: https://github.com/bitnami/charts
+# path: bitnami/rabbitmq
+# version: main
+# iconURL: https://bitnami.com/assets/stacks/rabbitmq/img/rabbitmq-stack-220x234.png
+# sourceType: git
+# - name: redis
+# repo: https://github.com/bitnami/charts
+# path: bitnami/redis
+# version: main
+# iconURL: https://bitnami.com/assets/stacks/redis/img/redis-stack-220x234.png
+# sourceType: git
diff --git a/web/docs/installation/configuration.md b/web/docs/installation/configuration.md
index 352d0aff..8a5addf8 100644
--- a/web/docs/installation/configuration.md
+++ b/web/docs/installation/configuration.md
@@ -3,11 +3,19 @@
Following are environment variables you can use to configure your instance of Cyclops. You can set those environment
variables directly on the `cyclops-ui` Kubernetes deployment.
+### Cyclops controller
+
+| Name | Description | Default value |
+|:------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------------------|
+| PORT | Specify a port to expose the controller API | 8080 |
+| DISABLE_TELEMETRY | By default, Cyclops controller emits usage metrics. If this env variable is set to `true`, the usage metrics are not exposed. You can read more about usage metrics [here](https://cyclops-ui.com/docs/usage_metrics/) | false |
+| WATCH_NAMESPACE | Kubernetes namespace used for all Cyclops custom resources like `Modules`, `TemplateStores` and `TemplateAuthRules`. Cyclops is aware only of the custom resources in this namespace. Cyclops controller will not react to changes on Modules on other namespaces | cyclops |
+| MODULE_TARGET_NAMESPACE | By default, Cyclops can manage resources created from Modules in the whole cluster. If this environment variable is set, Cyclops can manage Module child resources only in the namespace specified in the variable | - (empty means cluster scope) |
+| WATCH_NAMESPACE_HELM | By default, Cyclops can list, get and upgrade Helm releases in the whole cluster. If this environment variable is set, Cyclops can manage releases and their resources only in the namespace specified in the variable | - (empty means cluster scope) |
+
### Cyclops UI
-| Name | Description | Default value |
-| :--------------------------------- | :------------------------------------------------------------------------ | :-------------------- |
-| REACT_APP_CYCLOPS_CTRL_HOST | Content | http://localhost:8080 |
-| REACT_APP_DEFAULT_TEMPLATE_REPO | Default template repo (E.g. https://github.com/cyclops-ui/templates) | - |
-| REACT_APP_DEFAULT_TEMPLATE_PATH | Default template path (E.g. `demo`) | - |
-| REACT_APP_DEFAULT_TEMPLATE_VERSION | Default template version
Can be a commit hash, a tag or a branch name | - |
+| Name | Description | Default value |
+|:----------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------|
+| REACT_APP_CYCLOPS_CTRL_HOST | Host of your Cyclops controller | http://cyclops-ctrl.cyclops:8080 |
+| REACT_APP_ENABLE_STREAMING | Configures whether the Cyclops UI will subscribe to resource status SSE stream from cyclops controller. If `false`, resource status is polled each 15 seconds | true |
diff --git a/web/docs/installation/namespace-scope.md b/web/docs/installation/namespace-scope.md
new file mode 100644
index 00000000..f8319b26
--- /dev/null
+++ b/web/docs/installation/namespace-scope.md
@@ -0,0 +1,117 @@
+# Namespace scoped installation
+
+By default, Cyclops allows you to manage your Kubernetes resources in your whole cluster. However, you can restrict Cyclops to resources in a single namespace to limit permissions needed for your Cyclops installation.
+
+The next sections on permissions and configuration will discuss what changes need to be made to scope Cyclops to a namespace, and a section after that will explain how to do it in practice.
+
+### Permissions
+
+Since Cyclops queries Kubernetes resources on the Cluster scope, full cluster permissions are needed. In the [install manifest](https://github.com/cyclops-ui/cyclops/blob/main/install/cyclops-install.yaml), the `cyclops-ctrl` deployment uses a service account with a [ClusterRole](https://github.com/cyclops-ui/cyclops/blob/0da1cc5894512223ce08042ee766638c56a520a5/install/cyclops-install.yaml#L328) that allows all actions on all resources.
+
+To limit permissions to a single namespace, you will need to replace the ClusterRole and ClusterRoleBinding with a Role and a RoleBinding, respectively, which will limit service account permissions to a single namespace.
+
+### Cyclops controller configuration
+
+By default, the Cyclops controller uses the cluster scope permissions for all resources and queries the Kubernetes API on the cluster level. If you limit its permissions to a single namespace, it will have insufficient rights, and calls to the Kubernetes API will fail.
+
+Since version `v0.15.2`, Cyclops controller introduces environment variables that limit its querying capabilities to work within a single namespace instead of the whole cluster. These environment variables are used by the `cyclops-ctrl` deployment.
+
+- `WATCH_NAMESPACE` - Kubernetes namespace used for all Cyclops custom resources like `Modules`, `TemplateStores` and `TemplateAuthRules`. Cyclops is aware only of the custom resources in this namespace. Cyclops controller will not react to changes on Modules in other namespaces
+- `MODULE_TARGET_NAMESPACE` - By default, Cyclops can manage resources created from Modules in the whole cluster. If this environment variable is set, Cyclops can manage Module child resources only in the namespace specified in the variable
+- `WATCH_NAMESPACE_HELM` - By default, Cyclops can list, get and upgrade Helm releases in the whole cluster. If this environment variable is set, Cyclops can manage releases and their resources only in the namespace specified in the variable
+
+If you want to limit your Cyclops installation to a single namespace, you need to set the name of your namespace to all three of these environment variables. This will prevent Cyclops from querying on cluster scope and query only within the specified namespace.
+
+## Updating Cyclops installation
+
+You can change your installation resources manually by editing the [installation manifest](https://github.com/cyclops-ui/cyclops/blob/main/install/cyclops-install.yaml) or using our Helm chart.
+
+You can generate all resources for a Cyclops installation with the following command and edit your Cyclops configuration manually from there:
+
+```bash
+helm template cyclops oci://registry-1.docker.io/cyclopsui/cyclops-chart \
+--namespace \
+--include-crds \
+--set global.singleNamespaceScope.enabled=true \
+--set global.singleNamespaceScope.namespace=
+```
+
+Alternatively, you can install Cyclops with `helm install`, but be aware that the Cyclops Helm release will be visible in the Cyclops UI under the Helm releases tab, which is something you might want to avoid. Because of this, we encourage you to generate resources using the `helm template` and apply them without using `helm install`.
+
+:::info
+If `global.singleNamespaceScope.enabled` is set to `true`, `global.singleNamespaceScope.namespace` needs to be set as well
+:::
+
+The `helm template` command will produce a YAML manifest similar to the one in the installation manifest but with a couple of differences:
+
+- All resources have the namespace set to the one you provided as ``
+- Instead of ClusterRole and ClusterRoleBindings, you can find a Role and a RoleBinding. The Role has all of the permissions but only within that namespace.
+
+ ```yaml
+ apiVersion: rbac.authorization.k8s.io/v1
+ kind: Role
+ metadata:
+ labels:
+ app.kubernetes.io/component: ctrl
+ app.kubernetes.io/name: cyclops-ctrl
+ app.kubernetes.io/part-of: cyclops
+ name: cyclops-ctrl
+ namespace: "my-namespace"
+ rules:
+ - apiGroups:
+ - '*'
+ resources:
+ - '*'
+ verbs:
+ - '*'
+ ---
+ apiVersion: rbac.authorization.k8s.io/v1
+ kind: RoleBinding
+ metadata:
+ labels:
+ app.kubernetes.io/component: ctrl
+ app.kubernetes.io/name: cyclops-ctrl
+ app.kubernetes.io/part-of: cyclops
+ name: cyclops-ctrl
+ namespace: "my-namespace"
+ roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: Role
+ name: cyclops-ctrl
+ subjects:
+ - kind: ServiceAccount
+ name: cyclops-ctrl
+ namespace: "my-namespace"
+ ```
+
+- `cyclops-ctrl` deployment has all three of the mentioned environment variables set to ``
+
+ ```yaml
+ ...
+ - name: cyclops-ctrl
+ image: cyclopsui/cyclops-ctrl:v0.15.2
+ ports:
+ - containerPort: 8080
+ env:
+ - name: PORT
+ value: "8080"
+ - name: WATCH_NAMESPACE
+ value: "my-namespace"
+ - name: MODULE_TARGET_NAMESPACE
+ value: "my-namespace"
+ - name: WATCH_NAMESPACE_HELM
+ value: "my-namespace"
+ ...
+ ```
+
+With the setup mentioned above, you can manage a single namespace through Cyclops, allowing for fewer permissions for your installation.
+
+:::warning
+**Non namespaced resources are not visible when Cyclops is installed with namespace scope!**
+
+Currently, when Cyclops is scoped to a single namespace, it does not have permissions to resources that are not namespaced, such as Persistent volumes, Nodes, …
+
+Because of that, once you set a namespace scoped installation and you go to the nodes tab, it will show an error saying it has insufficient permissions.
+
+With a namespaced scoped installation, when editing Modules and Releases, Cyclops will fail creating/editing/deleting any non-namespaced resources.
+:::
diff --git a/web/sidebars.js b/web/sidebars.js
index 8875d7aa..7eb803a0 100644
--- a/web/sidebars.js
+++ b/web/sidebars.js
@@ -66,6 +66,7 @@ const sidebars = {
"installation/demo/feedback",
],
},
+ "installation/namespace-scope",
],
},
{