README
¶
UI Operator
A Kubernetes operator for managing micro-frontend applications and UI components in a declarative way.
Overview
The UI Operator enables organizations to deploy and manage complex web applications built with micro-frontend architecture. It provides a declarative approach to:
- Deploy UI applications: Manage main UI shell applications that host micro-frontends
- Orchestrate UI components: Deploy and configure individual micro-frontend components
- Configure runtime exposure: Set up routing, authentication, and runtime configuration for components
- Handle dependencies: Automatically manage relationships between UI applications and their components
Architecture
The operator manages three Custom Resource Definitions (CRDs):
ScalityUI
(cluster-scoped): Defines the main UI application with global configurationScalityUIComponent
(namespaced): Represents individual micro-frontend componentsScalityUIComponentExposer
(namespaced): Configures how components are exposed and integrated
Note: The architecture diagram below uses Mermaid syntax which may not render in all Markdown viewers. A static image version is available here.
graph TD
subgraph ControlPlane["Config & Orchestration Layer"]
User(["User/Admin"])
Operator["UI Operator<br/>(Reconciliation Loop)"]
K8sAPI["Kubernetes API"]
CRDs["Custom Resource Definitions"]
subgraph CustomResources["Custom Resources"]
ScalityUI["ScalityUI<br/>(Main Shell Config)"]
ScalityUIComp["ScalityUIComponent<br/>(Remote Module)"]
ScalityUIExp["ScalityUIComponentExposer<br/>(Integration Config)"]
end
K8sResources["K8s Resources<br/>(Deployments, Services, etc.)"]
Status["Status & Events"]
end
subgraph DataPlane["Application Layer"]
Pods["Running Pods<br/>(UI Components)"]
Ingress["Ingress/Service<br/>(Exposure)"]
ShellUI["Shell Frontend<br/>(React Application)"]
EndUser(["End User Browser"])
end
User ==>|"Installs"| CRDs
User ==>|"Installs"| Operator
User ==>|"Creates"| ScalityUI
User ==>|"Creates"| ScalityUIComp
User ==>|"Creates"| ScalityUIExp
ScalityUI -.->|"Stored in"| K8sAPI
ScalityUIComp -.->|"Stored in"| K8sAPI
ScalityUIExp -.->|"Stored in"| K8sAPI
K8sAPI ==>|"Watch events"| Operator
Operator ==>|"Creates/Updates"| K8sResources
K8sResources ==>|"Creates"| Pods
Pods ==>|"Exposed via"| Ingress
Operator -.->|"Updates"| Status
Status -.->|"Available via"| K8sAPI
ShellUI ==>|"Loads dynamically"| Ingress
EndUser ==>|"Accesses"| ShellUI
classDef operator fill:#1E88E5,color:white,stroke:none
classDef crd fill:#43A047,color:white,stroke:none
classDef resource fill:#FF8F00,color:white,stroke:none
classDef k8sComponents fill:#FF8F00,color:white,stroke:none
classDef plane fill:#121212,stroke:#424242,stroke-width:1px,color:white
classDef user fill:#9C27B0,color:white,stroke:none
classDef status fill:#F44336,color:white,stroke:none
class Operator operator
class CRDs crd
class ScalityUI,ScalityUIComp,ScalityUIExp,K8sResources resource
class K8sAPI,Ingress,Pods,ShellUI k8sComponents
class Status status
class User,EndUser user
class ControlPlane,DataPlane plane
Table of Contents
- Quick Start
- Installation
- Basic Usage
- Configuration
- API Reference
- Features
- Examples
- Operations
- Development
Quick Start
Prerequisites
- Kubernetes cluster v1.11.3+
- kubectl v1.11.3+
- Cluster admin permissions
Installation
-
Install the operator:
# Using latest stable release (recommended for production) kubectl apply -f https://raw.githubusercontent.com/ui-operator/ui-operator/0.1.0/dist/install.yaml # Using specific version kubectl apply -f https://raw.githubusercontent.com/ui-operator/ui-operator/{version}/dist/install.yaml # Using main branch (not recommended for production) kubectl apply -f https://raw.githubusercontent.com/ui-operator/ui-operator/main/dist/install.yaml
-
Verify installation:
kubectl get pods -n ui-operator-system
-
Check CRDs are installed:
kubectl get crd | grep ui.scality.com
Basic Usage
-
Create a UI application:
apiVersion: ui.scality.com/v1alpha1 kind: ScalityUI metadata: name: my-ui-app spec: image: "my-registry/ui-shell:v1.0.0" productName: "My Application"
-
Deploy a UI component:
apiVersion: ui.scality.com/v1alpha1 kind: ScalityUIComponent metadata: name: dashboard-component namespace: my-app spec: image: "my-registry/dashboard:v1.0.0" mountPath: "/app/config"
-
Expose the component:
apiVersion: ui.scality.com/v1alpha1 kind: ScalityUIComponentExposer metadata: name: dashboard-exposer namespace: my-app spec: scalityUI: "my-ui-app" scalityUIComponent: "dashboard-component" appHistoryBasePath: "/dashboard"
Installation
Method 1: Using Pre-built Manifests (Recommended)
# Using latest stable release (recommended for production)
kubectl apply -f https://raw.githubusercontent.com/ui-operator/ui-operator/0.1.0/dist/install.yaml
# Using specific version
kubectl apply -f https://raw.githubusercontent.com/ui-operator/ui-operator/{version}/dist/install.yaml
# Using main branch (not recommended for production)
kubectl apply -f https://raw.githubusercontent.com/ui-operator/ui-operator/main/dist/install.yaml
Method 2: Using Kustomize
-
Clone the repository:
git clone https://github.com/ui-operator/ui-operator.git cd ui-operator
-
Install CRDs:
make install
-
Deploy the operator:
make deploy IMG=ui-operator/ui-operator:latest
Method 3: Building from Source
-
Build and push the operator image:
make docker-build docker-push IMG=<your-registry>/ui-operator:tag
-
Deploy with your custom image:
make deploy IMG=<your-registry>/ui-operator:tag
Verification
Check that the operator is running:
# Check operator pod
kubectl get pods -n ui-operator-system
# Check CRDs
kubectl get crd | grep ui.scality.com
# Check operator logs
kubectl logs -n ui-operator-system deployment/ui-operator-controller-manager
Configuration
ScalityUI Resource
The ScalityUI
resource defines the main UI application:
apiVersion: ui.scality.com/v1alpha1
kind: ScalityUI
metadata:
name: my-shell-ui-app
spec:
image: "my-registry/ui-shell:v1.0.0"
productName: "My Application"
themes:
light:
type: "core-ui"
name: "light-theme"
logo:
type: "path"
value: "/assets/logo.png"
navbar:
main:
- internal:
kind: "navigation"
view: "dashboard"
icon: "dashboard"
label:
en: "Dashboard"
networks:
ingressClassName: "nginx"
host: "my-app.example.com"
tls:
- secretName: "ui-tls"
hosts:
- "my-app.example.com"
auth:
kind: "OIDC"
providerUrl: "https://auth.example.com"
clientId: "my-ui-app"
scopes: "openid email profile"
ScalityUIComponent Resource
The ScalityUIComponent
resource defines individual micro-frontend components:
apiVersion: ui.scality.com/v1alpha1
kind: ScalityUIComponent
metadata:
name: monitoring-component
namespace: ui
spec:
image: "my-registry/monitoring-ui:v1.2.0"
mountPath: "/app/configs"
imagePullSecrets:
- name: registry-secret
ScalityUIComponentExposer Resource
The ScalityUIComponentExposer
resource configures how components are exposed:
apiVersion: ui.scality.com/v1alpha1
kind: ScalityUIComponentExposer
metadata:
name: monitoring-exposer
namespace: ui
spec:
scalityUI: "my-shell-ui-app"
scalityUIComponent: "monitoring-component"
appHistoryBasePath: "/monitoring"
selfConfiguration:
apiEndpoint: "https://api.example.com/monitoring"
features:
- "metrics"
- "alerts"
API Reference
ScalityUI Fields
Field | Type | Required | Description |
---|---|---|---|
image |
string | Yes | Container image for the main UI shell |
productName |
string | Yes | Product name displayed in the UI |
themes |
object | No | Light and dark theme configurations |
navbar |
object | No | Navigation bar configuration |
networks |
object | No | Networking and ingress configuration |
auth |
object | No | Default authentication configuration |
imagePullSecrets |
array | No | Image pull secrets for private registries |
ScalityUIComponent Fields
Field | Type | Required | Description |
---|---|---|---|
image |
string | Yes | Container image for the UI component |
mountPath |
string | Yes | Path where configuration files are mounted |
imagePullSecrets |
array | No | Image pull secrets for private registries |
ScalityUIComponentExposer Fields
Field | Type | Required | Description |
---|---|---|---|
scalityUI |
string | Yes | Reference to ScalityUI resource |
scalityUIComponent |
string | Yes | Reference to ScalityUIComponent resource |
appHistoryBasePath |
string | Yes | Base path for the component in the URL |
selfConfiguration |
object | No | Runtime configuration for the component |
Features
✅ Core Features
- Micro-frontend Management: Deploy and manage multiple UI components
- Runtime Configuration: Dynamic configuration injection for components
- Authentication Integration: OIDC and other auth providers
- Ingress Management: Automatic routing and exposure
- Dependency Management: Automatic relationship handling
- Rolling Updates: Zero-downtime updates for components
Examples
Basic Setup
# UI Application
apiVersion: ui.scality.com/v1alpha1
kind: ScalityUI
metadata:
name: basic-ui
spec:
image: "nginx:latest"
productName: "Basic App"
---
# UI Component
apiVersion: ui.scality.com/v1alpha1
kind: ScalityUIComponent
metadata:
name: hello-component
namespace: default
spec:
image: "nginx:latest"
mountPath: "/app/config"
---
# Component Exposer
apiVersion: ui.scality.com/v1alpha1
kind: ScalityUIComponentExposer
metadata:
name: hello-exposer
namespace: default
spec:
scalityUI: "basic-ui"
scalityUIComponent: "hello-component"
appHistoryBasePath: "/hello"
With Authentication
apiVersion: ui.scality.com/v1alpha1
kind: ScalityUI
metadata:
name: secure-ui
spec:
image: "my-registry/ui-shell:v1.0.0"
productName: "Secure Application"
auth:
kind: "OIDC"
providerUrl: "https://auth.example.com"
clientId: "secure-ui"
responseType: "code"
scopes: "openid email profile"
providerLogout: true
Multi-Component Setup
# Multiple components with different configurations
apiVersion: ui.scality.com/v1alpha1
kind: ScalityUIComponentExposer
metadata:
name: dashboard-exposer
namespace: default
spec:
scalityUI: "main-ui"
scalityUIComponent: "dashboard-component"
appHistoryBasePath: "/dashboard"
selfConfiguration:
theme: "dark"
refreshInterval: 30
---
apiVersion: ui.scality.com/v1alpha1
kind: ScalityUIComponentExposer
metadata:
name: settings-exposer
namespace: default
spec:
scalityUI: "main-ui"
scalityUIComponent: "settings-component"
appHistoryBasePath: "/settings"
Operations
Monitoring
The operator exposes Prometheus metrics at /metrics
:
# ServiceMonitor for Prometheus
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: ui-operator-metrics
spec:
selector:
matchLabels:
app.kubernetes.io/name: ui-operator
endpoints:
- port: metrics
interval: 30s
path: /metrics
Troubleshooting
Check Resource Status
# Check UI status
kubectl get scalityui my-ui-app -o yaml
# Check component status
kubectl describe scalityuicomponent my-component
# Check exposer status
kubectl get scalityuicomponentexposer my-exposer -o yaml
View Logs
# Operator logs
kubectl logs -n ui-operator-system deployment/ui-operator-controller-manager
# Component logs
kubectl logs deployment/my-component
Common Issues
- Component not starting: Check image pull secrets and registry access
- Configuration not applied: Verify exposer references correct UI and component
- Ingress not working: Check ingress controller and network configuration
Backup and Restore
# Backup all UI resources
kubectl get scalityui,scalityuicomponent,scalityuicomponentexposer -o yaml > ui-backup.yaml
# Restore resources
kubectl apply -f ui-backup.yaml
Upgrading
# Update to latest stable release (recommended)
kubectl apply -f https://raw.githubusercontent.com/ui-operator/ui-operator/0.1.0/dist/install.yaml
# Update to specific version
kubectl apply -f https://raw.githubusercontent.com/ui-operator/ui-operator/{version}/dist/install.yaml
# Update using main branch (not recommended for production)
kubectl apply -f https://raw.githubusercontent.com/ui-operator/ui-operator/main/dist/install.yaml
# Check operator version
kubectl get deployment -n ui-operator-system ui-operator-controller-manager -o jsonpath='{.spec.template.spec.containers[0].image}'
Uninstalling
# Delete all custom resources
kubectl delete scalityui --all
kubectl delete scalityuicomponent --all
kubectl delete scalityuicomponentexposer --all
# Remove operator (use the same version you installed)
kubectl delete -f https://raw.githubusercontent.com/ui-operator/ui-operator/0.1.0/dist/install.yaml
# Remove CRDs (optional)
kubectl delete crd scalityuis.ui.scality.com
kubectl delete crd scalityuicomponents.ui.scality.com
kubectl delete crd scalityuicomponentexposers.ui.scality.com
Security & RBAC
The UI Operator leverages Kubernetes Role-Based Access Control (RBAC) to secure access to resources. When installed, the operator creates several roles and bindings to manage permissions.
Roles Created by the Operator
The following roles are created during installation:
-
Manager Role (ClusterRole):
- Used by the operator to manage resources
- Permissions to manage deployments, services, configmaps, ingresses, etc.
- Full access to the CRDs it manages
-
Editor Roles (ClusterRole):
scalityui-editor-role
: For users who need to create/update/delete ScalityUI resourcesscalityuicomponent-editor-role
: For users who need to create/update/delete ScalityUIComponent resourcesscalityuicomponentexposer-editor-role
: For users who need to create/update/delete ScalityUIComponentExposer resources
-
Viewer Roles (ClusterRole):
scalityui-viewer-role
: For users who only need read access to ScalityUI resourcesscalityuicomponent-viewer-role
: For users who only need read access to ScalityUIComponent resourcesscalityuicomponentexposer-viewer-role
: For users who only need read access to ScalityUIComponentExposer resources
-
Support Roles:
metrics-reader-role
: For accessing Prometheus metricsleader-election-role
: For the operator's leader election mechanism
Required Permissions for Users
Different users require different levels of permissions:
Cluster Administrators
- Need permissions to install the operator and CRDs
- Required permissions:
cluster-admin
or equivalent
Application Operators
- Need permissions to create and manage ScalityUI resources (cluster-scoped)
- Required ClusterRoleBinding:
scalityui-editor-role
Application Developers
- Need permissions to create and manage components in their namespaces
- Required RoleBindings in relevant namespaces:
scalityuicomponent-editor-role
scalityuicomponentexposer-editor-role
Read-only Users
- Need permissions to view but not modify resources
- Required RoleBindings: Viewer roles for respective resource types
Assigning RBAC Permissions
To assign permissions to a user or group:
# Example: Granting a user edit permissions for UI Components
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: developer-ui-component-editor
namespace: my-app-namespace
subjects:
- kind: User
name: developer@example.com
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: scalityuicomponent-editor-role
apiGroup: rbac.authorization.k8s.io
Security Best Practices
-
Follow Least Privilege Principle:
- Assign the minimum necessary permissions
- Use viewer roles for users who only need read access
-
Namespace Isolation:
- Create components and exposers in dedicated namespaces
- Limit access to those namespaces with RoleBindings
-
Audit Role Assignments:
- Regularly review who has access to create/modify resources
- Use
kubectl auth can-i
to verify permissions
-
Secure Access to the Main UI Resource:
- Since ScalityUI is cluster-scoped, carefully control who can create/modify them
Development
Building from Source
# Clone the repository
git clone https://github.com/ui-operator/ui-operator.git
cd ui-operator
# Build the operator
make build
# Run tests
make test
# Build Docker image
make docker-build IMG=<your-registry>/ui-operator:tag
Running Locally
# Install CRDs
make install
# Run operator locally (outside cluster)
make run
Testing
# Run unit tests
make test
# Run tests with coverage
make test-cover
# Run e2e tests
make test-e2e
# Run specific controller tests
go test ./internal/controller/scalityuicomponentexposer -v
Project Structure
├── api/v1alpha1/ # CRD type definitions
├── internal/controller/ # Controller implementations
├── config/ # Kubernetes manifests
├── examples/ # Example configurations
├── test/ # Test files
└── Makefile # Build targets
Directories
¶
Path | Synopsis |
---|---|
api
|
|
v1alpha1
Package v1alpha1 contains API Schema definitions for the ui v1alpha1 API group +kubebuilder:object:generate=true +groupName=ui.scality.com
|
Package v1alpha1 contains API Schema definitions for the ui v1alpha1 API group +kubebuilder:object:generate=true +groupName=ui.scality.com |
internal
|
|
test
|
|