{"id":30162958,"url":"https://github.com/scality/ui-operator","last_synced_at":"2026-01-07T15:15:11.230Z","repository":{"id":306439137,"uuid":"974862724","full_name":"scality/ui-operator","owner":"scality","description":null,"archived":false,"fork":false,"pushed_at":"2025-08-04T15:46:39.000Z","size":402,"stargazers_count":0,"open_issues_count":4,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-04T15:49:39.618Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/scality.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-04-29T12:21:39.000Z","updated_at":"2025-08-04T14:13:22.000Z","dependencies_parsed_at":"2025-07-25T20:17:09.863Z","dependency_job_id":"ec6525a2-01da-4721-9e5d-2704908bb795","html_url":"https://github.com/scality/ui-operator","commit_stats":null,"previous_names":["scality/ui-operator"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/scality/ui-operator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scality%2Fui-operator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scality%2Fui-operator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scality%2Fui-operator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scality%2Fui-operator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/scality","download_url":"https://codeload.github.com/scality/ui-operator/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scality%2Fui-operator/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269930151,"owners_count":24498685,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-11T02:00:10.019Z","response_time":75,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-08-11T17:48:14.463Z","updated_at":"2026-01-07T15:15:11.224Z","avatar_url":"https://github.com/scality.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# UI Operator\n\nA Kubernetes operator for managing micro-frontend applications and UI components in a declarative way.\n\n[![Go Report Card](https://goreportcard.com/badge/github.com/ui-operator/ui-operator)](https://goreportcard.com/report/github.com/ui-operator/ui-operator)\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n\n## Overview\n\nThe UI Operator enables organizations to deploy and manage complex web applications built with micro-frontend architecture. It provides a declarative approach to:\n\n- **Deploy UI applications**: Manage main UI shell applications that host micro-frontends\n- **Orchestrate UI components**: Deploy and configure individual micro-frontend components\n- **Configure runtime exposure**: Set up routing, authentication, and runtime configuration for components\n- **Handle dependencies**: Automatically manage relationships between UI applications and their components\n\n### Architecture\n\nThe operator manages three Custom Resource Definitions (CRDs):\n\n- **`ScalityUI`** (cluster-scoped): Defines the main UI application with global configuration\n- **`ScalityUIComponent`** (namespaced): Represents individual micro-frontend components\n- **`ScalityUIComponentExposer`** (namespaced): Configures how components are exposed and integrated\n\n\u003e **Note:** The architecture diagram below uses Mermaid syntax which may not render in all Markdown viewers. A static image version is available [here](https://github.com/scality/ui-operator/blob/main/docs/images/architecture.png).\n\n```mermaid\ngraph TD\n    subgraph ControlPlane[\"Config \u0026 Orchestration Layer\"]\n        User([\"User/Admin\"])\n        Operator[\"UI Operator\u003cbr/\u003e(Reconciliation Loop)\"]\n        K8sAPI[\"Kubernetes API\"]\n        CRDs[\"Custom Resource Definitions\"]\n\n        subgraph CustomResources[\"Custom Resources\"]\n            ScalityUI[\"ScalityUI\u003cbr/\u003e(Main Shell Config)\"]\n            ScalityUIComp[\"ScalityUIComponent\u003cbr/\u003e(Remote Module)\"]\n            ScalityUIExp[\"ScalityUIComponentExposer\u003cbr/\u003e(Integration Config)\"]\n        end\n\n        K8sResources[\"K8s Resources\u003cbr/\u003e(Deployments, Services, etc.)\"]\n        Status[\"Status \u0026 Events\"]\n    end\n\n    subgraph DataPlane[\"Application Layer\"]\n        Pods[\"Running Pods\u003cbr/\u003e(UI Components)\"]\n        Ingress[\"Ingress/Service\u003cbr/\u003e(Exposure)\"]\n        ShellUI[\"Shell Frontend\u003cbr/\u003e(React Application)\"]\n        EndUser([\"End User Browser\"])\n    end\n\n    User ==\u003e|\"Installs\"| CRDs\n    User ==\u003e|\"Installs\"| Operator\n    User ==\u003e|\"Creates\"| ScalityUI\n    User ==\u003e|\"Creates\"| ScalityUIComp\n    User ==\u003e|\"Creates\"| ScalityUIExp\n\n    ScalityUI -.-\u003e|\"Stored in\"| K8sAPI\n    ScalityUIComp -.-\u003e|\"Stored in\"| K8sAPI\n    ScalityUIExp -.-\u003e|\"Stored in\"| K8sAPI\n\n    K8sAPI ==\u003e|\"Watch events\"| Operator\n    Operator ==\u003e|\"Creates/Updates\"| K8sResources\n    K8sResources ==\u003e|\"Creates\"| Pods\n    Pods ==\u003e|\"Exposed via\"| Ingress\n\n    Operator -.-\u003e|\"Updates\"| Status\n    Status -.-\u003e|\"Available via\"| K8sAPI\n\n    ShellUI ==\u003e|\"Loads dynamically\"| Ingress\n    EndUser ==\u003e|\"Accesses\"| ShellUI\n\n    classDef operator fill:#1E88E5,color:white,stroke:none\n    classDef crd fill:#43A047,color:white,stroke:none\n    classDef resource fill:#FF8F00,color:white,stroke:none\n    classDef k8sComponents fill:#FF8F00,color:white,stroke:none\n    classDef plane fill:#121212,stroke:#424242,stroke-width:1px,color:white\n    classDef user fill:#9C27B0,color:white,stroke:none\n    classDef status fill:#F44336,color:white,stroke:none\n\n    class Operator operator\n    class CRDs crd\n    class ScalityUI,ScalityUIComp,ScalityUIExp,K8sResources resource\n    class K8sAPI,Ingress,Pods,ShellUI k8sComponents\n    class Status status\n    class User,EndUser user\n    class ControlPlane,DataPlane plane\n```\n\n## Table of Contents\n\n- [Quick Start](#quick-start)\n- [Installation](#installation)\n- [Basic Usage](#basic-usage)\n- [Configuration](#configuration)\n- [API Reference](#api-reference)\n- [Features](#features)\n- [Examples](#examples)\n- [Operations](#operations)\n- [Development](#development)\n\n## Quick Start\n\n### Prerequisites\n\n- Kubernetes cluster v1.11.3+\n- kubectl v1.11.3+\n- Cluster admin permissions\n\n### Installation\n\n1. **Install the operator:**\n\n   ```bash\n   # Using latest stable release (recommended for production)\n   kubectl apply -f https://raw.githubusercontent.com/ui-operator/ui-operator/0.1.0/dist/install.yaml\n\n   # Using specific version\n   kubectl apply -f https://raw.githubusercontent.com/ui-operator/ui-operator/{version}/dist/install.yaml\n\n   # Using main branch (not recommended for production)\n   kubectl apply -f https://raw.githubusercontent.com/ui-operator/ui-operator/main/dist/install.yaml\n   ```\n\n2. **Verify installation:**\n\n   ```bash\n   kubectl get pods -n ui-operator-system\n   ```\n\n3. **Check CRDs are installed:**\n   ```bash\n   kubectl get crd | grep ui.scality.com\n   ```\n\n### Basic Usage\n\n1. **Create a UI application:**\n\n   ```yaml\n   apiVersion: ui.scality.com/v1alpha1\n   kind: ScalityUI\n   metadata:\n     name: my-ui-app\n   spec:\n     image: \"my-registry/ui-shell:v1.0.0\"\n     productName: \"My Application\"\n   ```\n\n2. **Deploy a UI component:**\n\n   ```yaml\n   apiVersion: ui.scality.com/v1alpha1\n   kind: ScalityUIComponent\n   metadata:\n     name: dashboard-component\n     namespace: my-app\n   spec:\n     image: \"my-registry/dashboard:v1.0.0\"\n     mountPath: \"/app/config\"\n   ```\n\n3. **Expose the component:**\n   ```yaml\n   apiVersion: ui.scality.com/v1alpha1\n   kind: ScalityUIComponentExposer\n   metadata:\n     name: dashboard-exposer\n     namespace: my-app\n   spec:\n     scalityUI: \"my-ui-app\"\n     scalityUIComponent: \"dashboard-component\"\n     appHistoryBasePath: \"/dashboard\"\n   ```\n\n## Installation\n\n### Method 1: Using Pre-built Manifests (Recommended)\n\n```bash\n# Using latest stable release (recommended for production)\nkubectl apply -f https://raw.githubusercontent.com/ui-operator/ui-operator/0.1.0/dist/install.yaml\n\n# Using specific version\nkubectl apply -f https://raw.githubusercontent.com/ui-operator/ui-operator/{version}/dist/install.yaml\n\n# Using main branch (not recommended for production)\nkubectl apply -f https://raw.githubusercontent.com/ui-operator/ui-operator/main/dist/install.yaml\n```\n\n### Method 2: Using Kustomize\n\n1. **Clone the repository:**\n\n   ```bash\n   git clone https://github.com/ui-operator/ui-operator.git\n   cd ui-operator\n   ```\n\n2. **Install CRDs:**\n\n   ```bash\n   make install\n   ```\n\n3. **Deploy the operator:**\n   ```bash\n   make deploy IMG=ui-operator/ui-operator:latest\n   ```\n\n### Method 3: Building from Source\n\n1. **Build and push the operator image:**\n\n   ```bash\n   make docker-build docker-push IMG=\u003cyour-registry\u003e/ui-operator:tag\n   ```\n\n2. **Deploy with your custom image:**\n   ```bash\n   make deploy IMG=\u003cyour-registry\u003e/ui-operator:tag\n   ```\n\n### Verification\n\nCheck that the operator is running:\n\n```bash\n# Check operator pod\nkubectl get pods -n ui-operator-system\n\n# Check CRDs\nkubectl get crd | grep ui.scality.com\n\n# Check operator logs\nkubectl logs -n ui-operator-system deployment/ui-operator-controller-manager\n```\n\n## Configuration\n\n### ScalityUI Resource\n\nThe `ScalityUI` resource defines the main UI application:\n\n```yaml\napiVersion: ui.scality.com/v1alpha1\nkind: ScalityUI\nmetadata:\n  name: my-shell-ui-app\nspec:\n  image: \"my-registry/ui-shell:v1.0.0\"\n  productName: \"My Application\"\n  themes:\n    light:\n      type: \"core-ui\"\n      name: \"light-theme\"\n      logo:\n        type: \"path\"\n        value: \"/assets/logo.png\"\n  navbar:\n    main:\n      - internal:\n          kind: \"navigation\"\n          view: \"dashboard\"\n          icon: \"dashboard\"\n          label:\n            en: \"Dashboard\"\n  networks:\n    ingressClassName: \"nginx\"\n    host: \"my-app.example.com\"\n    tls:\n      - secretName: \"ui-tls\"\n        hosts:\n          - \"my-app.example.com\"\n  auth:\n    kind: \"OIDC\"\n    providerUrl: \"https://auth.example.com\"\n    clientId: \"my-ui-app\"\n    scopes: \"openid email profile\"\n```\n\n### ScalityUIComponent Resource\n\nThe `ScalityUIComponent` resource defines individual micro-frontend components:\n\n```yaml\napiVersion: ui.scality.com/v1alpha1\nkind: ScalityUIComponent\nmetadata:\n  name: monitoring-component\n  namespace: ui\nspec:\n  image: \"my-registry/monitoring-ui:v1.2.0\"\n  mountPath: \"/app/configs\"\n  imagePullSecrets:\n    - name: registry-secret\n```\n\n### ScalityUIComponentExposer Resource\n\nThe `ScalityUIComponentExposer` resource configures how components are exposed:\n\n```yaml\napiVersion: ui.scality.com/v1alpha1\nkind: ScalityUIComponentExposer\nmetadata:\n  name: monitoring-exposer\n  namespace: ui\nspec:\n  scalityUI: \"my-shell-ui-app\"\n  scalityUIComponent: \"monitoring-component\"\n  appHistoryBasePath: \"/monitoring\"\n  selfConfiguration:\n    apiEndpoint: \"https://api.example.com/monitoring\"\n    features:\n      - \"metrics\"\n      - \"alerts\"\n```\n\n## API Reference\n\n### ScalityUI Fields\n\n| Field              | Type   | Required | Description                               |\n| ------------------ | ------ | -------- | ----------------------------------------- |\n| `image`            | string | Yes      | Container image for the main UI shell     |\n| `productName`      | string | Yes      | Product name displayed in the UI          |\n| `themes`           | object | No       | Light and dark theme configurations       |\n| `navbar`           | object | No       | Navigation bar configuration              |\n| `networks`         | object | No       | Networking and ingress configuration      |\n| `auth`             | object | No       | Default authentication configuration      |\n| `imagePullSecrets` | array  | No       | Image pull secrets for private registries |\n\n### ScalityUIComponent Fields\n\n| Field              | Type   | Required | Description                                |\n| ------------------ | ------ | -------- | ------------------------------------------ |\n| `image`            | string | Yes      | Container image for the UI component       |\n| `mountPath`        | string | Yes      | Path where configuration files are mounted |\n| `imagePullSecrets` | array  | No       | Image pull secrets for private registries  |\n\n### ScalityUIComponentExposer Fields\n\n| Field                | Type   | Required | Description                              |\n| -------------------- | ------ | -------- | ---------------------------------------- |\n| `scalityUI`          | string | Yes      | Reference to ScalityUI resource          |\n| `scalityUIComponent` | string | Yes      | Reference to ScalityUIComponent resource |\n| `appHistoryBasePath` | string | Yes      | Base path for the component in the URL   |\n| `selfConfiguration`  | object | No       | Runtime configuration for the component  |\n\n## Features\n\n### ✅ Core Features\n\n- [x] **Micro-frontend Management**: Deploy and manage multiple UI components\n- [x] **Runtime Configuration**: Dynamic configuration injection for components\n- [x] **Authentication Integration**: OIDC and other auth providers\n- [x] **Ingress Management**: Automatic routing and exposure\n- [x] **Dependency Management**: Automatic relationship handling\n- [x] **Rolling Updates**: Zero-downtime updates for components\n\n## Examples\n\n### Basic Setup\n\n```yaml\n# UI Application\napiVersion: ui.scality.com/v1alpha1\nkind: ScalityUI\nmetadata:\n  name: basic-ui\nspec:\n  image: \"nginx:latest\"\n  productName: \"Basic App\"\n\n---\n# UI Component\napiVersion: ui.scality.com/v1alpha1\nkind: ScalityUIComponent\nmetadata:\n  name: hello-component\n  namespace: default\nspec:\n  image: \"nginx:latest\"\n  mountPath: \"/app/config\"\n\n---\n# Component Exposer\napiVersion: ui.scality.com/v1alpha1\nkind: ScalityUIComponentExposer\nmetadata:\n  name: hello-exposer\n  namespace: default\nspec:\n  scalityUI: \"basic-ui\"\n  scalityUIComponent: \"hello-component\"\n  appHistoryBasePath: \"/hello\"\n```\n\n### With Authentication\n\n```yaml\napiVersion: ui.scality.com/v1alpha1\nkind: ScalityUI\nmetadata:\n  name: secure-ui\nspec:\n  image: \"my-registry/ui-shell:v1.0.0\"\n  productName: \"Secure Application\"\n  auth:\n    kind: \"OIDC\"\n    providerUrl: \"https://auth.example.com\"\n    clientId: \"secure-ui\"\n    responseType: \"code\"\n    scopes: \"openid email profile\"\n    providerLogout: true\n```\n\n### Multi-Component Setup\n\n```yaml\n# Multiple components with different configurations\napiVersion: ui.scality.com/v1alpha1\nkind: ScalityUIComponentExposer\nmetadata:\n  name: dashboard-exposer\n  namespace: default\nspec:\n  scalityUI: \"main-ui\"\n  scalityUIComponent: \"dashboard-component\"\n  appHistoryBasePath: \"/dashboard\"\n  selfConfiguration:\n    theme: \"dark\"\n    refreshInterval: 30\n\n---\napiVersion: ui.scality.com/v1alpha1\nkind: ScalityUIComponentExposer\nmetadata:\n  name: settings-exposer\n  namespace: default\nspec:\n  scalityUI: \"main-ui\"\n  scalityUIComponent: \"settings-component\"\n  appHistoryBasePath: \"/settings\"\n```\n\n## Operations\n\n### Monitoring\n\nThe operator exposes Prometheus metrics at `/metrics`:\n\n```yaml\n# ServiceMonitor for Prometheus\napiVersion: monitoring.coreos.com/v1\nkind: ServiceMonitor\nmetadata:\n  name: ui-operator-metrics\nspec:\n  selector:\n    matchLabels:\n      app.kubernetes.io/name: ui-operator\n  endpoints:\n    - port: metrics\n      interval: 30s\n      path: /metrics\n```\n\n### Troubleshooting\n\n#### Check Resource Status\n\n```bash\n# Check UI status\nkubectl get scalityui my-ui-app -o yaml\n\n# Check component status\nkubectl describe scalityuicomponent my-component\n\n# Check exposer status\nkubectl get scalityuicomponentexposer my-exposer -o yaml\n```\n\n#### View Logs\n\n```bash\n# Operator logs\nkubectl logs -n ui-operator-system deployment/ui-operator-controller-manager\n\n# Component logs\nkubectl logs deployment/my-component\n```\n\n#### Common Issues\n\n1. **Component not starting**: Check image pull secrets and registry access\n2. **Configuration not applied**: Verify exposer references correct UI and component\n3. **Ingress not working**: Check ingress controller and network configuration\n\n### Backup and Restore\n\n```bash\n# Backup all UI resources\nkubectl get scalityui,scalityuicomponent,scalityuicomponentexposer -o yaml \u003e ui-backup.yaml\n\n# Restore resources\nkubectl apply -f ui-backup.yaml\n```\n\n### Upgrading\n\n```bash\n# Update to latest stable release (recommended)\nkubectl apply -f https://raw.githubusercontent.com/ui-operator/ui-operator/0.1.0/dist/install.yaml\n\n# Update to specific version\nkubectl apply -f https://raw.githubusercontent.com/ui-operator/ui-operator/{version}/dist/install.yaml\n\n# Update using main branch (not recommended for production)\nkubectl apply -f https://raw.githubusercontent.com/ui-operator/ui-operator/main/dist/install.yaml\n\n# Check operator version\nkubectl get deployment -n ui-operator-system ui-operator-controller-manager -o jsonpath='{.spec.template.spec.containers[0].image}'\n```\n\n### Uninstalling\n\n```bash\n# Delete all custom resources\nkubectl delete scalityui --all\nkubectl delete scalityuicomponent --all\nkubectl delete scalityuicomponentexposer --all\n\n# Remove operator (use the same version you installed)\nkubectl delete -f https://raw.githubusercontent.com/ui-operator/ui-operator/0.1.0/dist/install.yaml\n\n# Remove CRDs (optional)\nkubectl delete crd scalityuis.ui.scality.com\nkubectl delete crd scalityuicomponents.ui.scality.com\nkubectl delete crd scalityuicomponentexposers.ui.scality.com\n```\n\n## Security \u0026 RBAC\n\nThe 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.\n\n### Roles Created by the Operator\n\nThe following roles are created during installation:\n\n1. **Manager Role (ClusterRole)**:\n\n   - Used by the operator to manage resources\n   - Permissions to manage deployments, services, configmaps, ingresses, etc.\n   - Full access to the CRDs it manages\n\n2. **Editor Roles (ClusterRole)**:\n\n   - `scalityui-editor-role`: For users who need to create/update/delete ScalityUI resources\n   - `scalityuicomponent-editor-role`: For users who need to create/update/delete ScalityUIComponent resources\n   - `scalityuicomponentexposer-editor-role`: For users who need to create/update/delete ScalityUIComponentExposer resources\n\n3. **Viewer Roles (ClusterRole)**:\n\n   - `scalityui-viewer-role`: For users who only need read access to ScalityUI resources\n   - `scalityuicomponent-viewer-role`: For users who only need read access to ScalityUIComponent resources\n   - `scalityuicomponentexposer-viewer-role`: For users who only need read access to ScalityUIComponentExposer resources\n\n4. **Support Roles**:\n   - `metrics-reader-role`: For accessing Prometheus metrics\n   - `leader-election-role`: For the operator's leader election mechanism\n\n### Required Permissions for Users\n\nDifferent users require different levels of permissions:\n\n#### Cluster Administrators\n\n- Need permissions to install the operator and CRDs\n- Required permissions: `cluster-admin` or equivalent\n\n#### Application Operators\n\n- Need permissions to create and manage ScalityUI resources (cluster-scoped)\n- Required ClusterRoleBinding: `scalityui-editor-role`\n\n#### Application Developers\n\n- Need permissions to create and manage components in their namespaces\n- Required RoleBindings in relevant namespaces:\n  - `scalityuicomponent-editor-role`\n  - `scalityuicomponentexposer-editor-role`\n\n#### Read-only Users\n\n- Need permissions to view but not modify resources\n- Required RoleBindings: Viewer roles for respective resource types\n\n### Assigning RBAC Permissions\n\nTo assign permissions to a user or group:\n\n```yaml\n# Example: Granting a user edit permissions for UI Components\napiVersion: rbac.authorization.k8s.io/v1\nkind: RoleBinding\nmetadata:\n  name: developer-ui-component-editor\n  namespace: my-app-namespace\nsubjects:\n  - kind: User\n    name: developer@example.com\n    apiGroup: rbac.authorization.k8s.io\nroleRef:\n  kind: ClusterRole\n  name: scalityuicomponent-editor-role\n  apiGroup: rbac.authorization.k8s.io\n```\n\n### Security Best Practices\n\n1. **Follow Least Privilege Principle**:\n\n   - Assign the minimum necessary permissions\n   - Use viewer roles for users who only need read access\n\n2. **Namespace Isolation**:\n\n   - Create components and exposers in dedicated namespaces\n   - Limit access to those namespaces with RoleBindings\n\n3. **Audit Role Assignments**:\n\n   - Regularly review who has access to create/modify resources\n   - Use `kubectl auth can-i` to verify permissions\n\n4. **Secure Access to the Main UI Resource**:\n   - Since ScalityUI is cluster-scoped, carefully control who can create/modify them\n\n## Development\n\n### Building from Source\n\n```bash\n# Clone the repository\ngit clone https://github.com/ui-operator/ui-operator.git\ncd ui-operator\n\n# Build the operator\nmake build\n\n# Run tests\nmake test\n\n# Build Docker image\nmake docker-build IMG=\u003cyour-registry\u003e/ui-operator:tag\n```\n\n### Running Locally\n\n```bash\n# Install CRDs\nmake install\n\n# Run operator locally (outside cluster)\nmake run\n```\n\n### Testing\n\n```bash\n# Run unit tests\nmake test\n\n# Run tests with coverage\nmake test-cover\n\n# Run e2e tests\nmake test-e2e\n\n# Run specific controller tests\ngo test ./internal/controller/scalityuicomponentexposer -v\n```\n\n### Project Structure\n\n```\n├── api/v1alpha1/           # CRD type definitions\n├── internal/controller/    # Controller implementations\n├── config/                 # Kubernetes manifests\n├── examples/              # Example configurations\n├── test/                  # Test files\n└── Makefile              # Build targets\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscality%2Fui-operator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fscality%2Fui-operator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscality%2Fui-operator/lists"}