Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
8bd88b2
CH-243: Make route pattern customizable
iamludal Feb 27, 2026
61961bb
Include forward slash in route pattern regex
iamludal Feb 28, 2026
8dde96f
Fix indent
iamludal Feb 28, 2026
4238c75
Add documentation
iamludal Feb 28, 2026
6a7d566
Fix linting
iamludal Mar 1, 2026
3dc0062
Try fix nil pointer
iamludal Mar 1, 2026
af4a92e
Fix nil pointer
iamludal Mar 1, 2026
0ae1782
Add router path matcher Traefik annotation
iamludal Mar 1, 2026
56439ab
Add configurable gatekeeper secret key secret. If no
Mar 6, 2026
1932760
Merge branch 'develop' into feature/CH-224
Mar 6, 2026
382e4c3
feat: define annotations based on ingress class
iamludal Mar 9, 2026
cab5ceb
Merge branch 'CH-243-customizable-route-pattern' into develop
filippomc Mar 9, 2026
59ecd9f
Merge branch 'feature/CH-224' of github.com:MetaCell/cloud-harness in…
filippomc Mar 9, 2026
ee02cae
CH-243 support for traefik routes
filippomc Mar 9, 2026
3a707cc
CH-224 Use secret for gateway encryption code
filippomc Mar 9, 2026
1bccfff
CH-243 path generation fix
filippomc Mar 9, 2026
ad29c79
CH-224 GK helm template fix
filippomc Mar 9, 2026
9360472
CH-224 GK helm template fix
filippomc Mar 9, 2026
b08d271
CH-243 post refactoring issue with certificates fix
filippomc Mar 9, 2026
54b73e9
CH-248 external database configuration
filippomc Mar 9, 2026
bc505ba
CH-248 add endpoint to test the external db
filippomc Mar 9, 2026
7ea8c0f
CH-224 GK encryption key to AES-256
filippomc Mar 9, 2026
c8a7208
CH-248 add test coverage for CI/CD secret set
filippomc Mar 9, 2026
7387a1d
CH-248 fix helm templates guard
filippomc Mar 9, 2026
1ee00c5
CH-248 fix helm templates guard
filippomc Mar 9, 2026
be1d737
CH-248 fix helm templates guard
filippomc Mar 9, 2026
71b1f26
CH-243 ingress root path fix
filippomc Mar 9, 2026
5274ec8
chore: linting and test related fixes
filippomc Mar 10, 2026
d8cb7fe
chore: Python code linting fix
filippomc Mar 10, 2026
cc5b125
chore: Update docs and default sample configuration
filippomc Mar 10, 2026
e94a771
Update CH default image version to 4.6.0
Mar 10, 2026
244e206
CH-248 #840 chore: rename connect string variable
filippomc Mar 10, 2026
88c9596
Merge branch 'feature/gateway-updates' of github.com:MetaCell/cloud-h…
filippomc Mar 10, 2026
eee05b1
add django command to sync users
filippomc Mar 11, 2026
9550a74
CH-250 alternative dockerfiles implementation
filippomc Mar 11, 2026
b120de4
CH-251 start network policy implementation
filippomc Mar 11, 2026
2046fc5
chore: test value fix
filippomc Mar 11, 2026
ec81e23
CH-251 add simple auto network policy specs
filippomc Mar 12, 2026
73779cc
CH-252 align skaffold clone to codefresh
filippomc Mar 12, 2026
85cbf72
small robustness enhancement
filippomc Mar 12, 2026
3e36d95
Runtime applications stability and consistency enhancements
filippomc Mar 13, 2026
6c980bd
chore: use envmap vs env for keycloak configuration
filippomc Mar 16, 2026
da9ed82
ingress: fix error with no subdomain
filippomc Mar 17, 2026
3a714d0
Remove dependencies from looked up dockerfiles
filippomc Mar 17, 2026
1e14b16
Fix files copy regression
filippomc Mar 17, 2026
58be65a
Improve merge directories efficiency with symlinks
filippomc Mar 17, 2026
2ccdb34
ci/cd fix issues with git dependencies and overrides
filippomc Mar 18, 2026
81ebfd0
improve git instructions on exception handling
filippomc Mar 18, 2026
7223405
Fix dependency overrides copy using .dockerignore
filippomc Mar 18, 2026
f3f0172
Copy overridesregression fix
filippomc Mar 18, 2026
248df42
Improve ignore strategy on overridden applications
filippomc Mar 18, 2026
0a8bdb3
chore: linting fix
filippomc Mar 18, 2026
8476275
Fix preprocessing test
filippomc Mar 18, 2026
ad45cb2
Fix configmap deleting pull secret name
filippomc Mar 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .github/instructions/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,10 @@ Verify which application/components is in scope and read specific prompt instruc

Check best practices in every instruction file in scope and docs and apply them when writing code or performing code reviews.
Use reference for any questions regarding project structure, development workflow, and best practices.
If you have any doubts about where to find information, ask for clarification before proceeding.
If you have any doubts about where to find information, ask for clarification before proceeding.

### Development principles
- Follow the best practices and coding style guidelines outlined in the documentation and instruction files.
- Configuration is set on values.yaml files and injected into the application via Helm templates and Kubernetes manifests. Do not hardcode configuration values directly into the application code or templates.
- Structured configuration can be injected via resources, that are process by helm templates and loaded as ConfigMaps automatically. See for instance `applications/accounts/deploy/resources/realm.json`
- The cloud harness configuration API is handled by the models library and defined as [openapi spec](../../libraries/models/api/openapi.yaml). Use `harness-generate models` to generate the models library after making changes to the spec.
1 change: 1 addition & 0 deletions .github/instructions/tools.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ Take the following best practices into account when writing code for the project
- Handle exceptions only at the higher level; let lower layers raise. NEVER catch exceptions in helpers or services unless you are adding context and re-raising.
- Cover critical logic with unit tests, especially in helpers and services. Use mocks to isolate units under test.
- Prefer models classes for helpers and services to ensure data validation and clear interfaces. Use typed dicts for structured data that isn't covered by Schema classes. Use plain dicts only to represent real unstructured data. Avoid returning tuples.
- Bubble up exceptions to the highest level possible, where they can be handled. Avoid return values to reflect success or failure. Embed library exceptions and untyped exceptions in custom exceptions with clear meaning and context. This allows for better error handling and debugging.


## Important Constraints
Expand Down
1 change: 1 addition & 0 deletions applications/accounts/deploy/resources/realm.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"rememberMe": true,
"verifyEmail": false,
"loginWithEmailAllowed": true,
"organizationsEnabled": {{ .Values.apps.accounts.realm.organizationsEnabled | default false }},
"duplicateEmailsAllowed": false,
"resetPasswordAllowed": true,
"editUsernameAllowed": {{ .Values.apps.accounts.editUsernameAllowed }},
Expand Down
57 changes: 22 additions & 35 deletions applications/accounts/deploy/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,44 +7,29 @@ harness:
port: 8080
resources:
requests:
memory: "512Mi"
memory: "800Mi"
cpu: "10m"
limits:
memory: "1024Mi"
memory: "1Gi"
service:
auto: true
port: 8080
env:
- name: KC_BOOTSTRAP_ADMIN_USERNAME
value: "admin"
- name: KC_BOOTSTRAP_ADMIN_PASSWORD
value: "metacell"
- name: KC_PROXY_HEADERS
value: xforwarded
- name: KC_DB
value: "postgres"
- name: KC_DB_URL_HOST
value: "keycloak-postgres"
- name: KC_DB_URL_DATABASE
value: "auth_db"
- name: KC_DB_USERNAME
value: "user"
- name: KC_DB_PASSWORD
value: "password"
- name: KC_HTTP_ENABLED
value: "true"
- name: KC_PROXY
value: "edge"
- name: KC_HOSTNAME_STRICT
value: "false"
- name: KC_HOSTNAME_STRICT_HTTPS
value: "false"
- name: KC_HEALTH_ENABLED
value: "true"
- name: KC_METRICS_ENABLED
value: "true"
- name: JAVA_OPTS
value: -server -Xms64m -Xmx896m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true --add-exports=java.base/sun.nio.ch=ALL-UNNAMED --add-exports=jdk.unsupported/sun.misc=ALL-UNNAMED --add-exports=jdk.unsupported/sun.reflect=ALL-UNNAMED
envmap:
KC_BOOTSTRAP_ADMIN_USERNAME: "admin"
KC_BOOTSTRAP_ADMIN_PASSWORD: "metacell"
KC_PROXY_HEADERS: xforwarded
KC_DB: "postgres"
KC_DB_URL_HOST: "keycloak-postgres"
KC_DB_URL_DATABASE: "auth_db"
KC_DB_USERNAME: "user"
KC_DB_PASSWORD: "password"
KC_HTTP_ENABLED: "true"
KC_PROXY: "edge"
KC_HOSTNAME_STRICT: "false"
KC_HOSTNAME_STRICT_HTTPS: "false"
KC_HEALTH_ENABLED: "true"
KC_METRICS_ENABLED: "true"
JAVA_OPTS: "-server -Xms64m -Xmx896m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true --add-exports=java.base/sun.nio.ch=ALL-UNNAMED --add-exports=jdk.unsupported/sun.misc=ALL-UNNAMED --add-exports=jdk.unsupported/sun.reflect=ALL-UNNAMED"
database:
auto: true
name: keycloak-postgres
Expand Down Expand Up @@ -87,10 +72,12 @@ admin:
editUsernameAllowed: true
useEvents: true
identityProviders:
- github
- google
- github
- google
theme:
login: "keycloak"
account: "keycloak"
admin: "keycloak"
email: "keycloak"
realm:
organizationsEnabled: false
16 changes: 16 additions & 0 deletions applications/samples/api/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,22 @@ paths:
description: |
Check if the token is valid
x-openapi-router-controller: samples.controllers.auth_controller
/db-connect-string:
get:
tags:
- database
summary: Get database connection string
operationId: get_db_connect_string
description: Returns the database connection string for the current application.
responses:
"200":
description: Database connection string returned successfully
content:
application/json:
schema:
type: string
"500":
description: Error retrieving database connection string
/sampleresources:
summary: Path used to manage the list of sampleresources.
description: >-
Expand Down
22 changes: 13 additions & 9 deletions applications/samples/backend/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
connexion[swagger-ui,flask,uvicorn]>=3.0.0,<4.0.0
swagger-ui-bundle>=1.1.0
python_dateutil>=2.9.0
setuptools>=21.0.0
uvicorn
# Following some unnecessary requirements to make sure they can be installed
psycopg2-binary
sqlalchemy<2.0.0
scipy
connexion[swagger-ui] >= 2.6.0; python_version>="3.6"
# 2.3 is the last version that supports python 3.4-3.5
connexion[swagger-ui] <= 2.3.0; python_version=="3.5" or python_version=="3.4"
# prevent breaking dependencies from advent of connexion>=3.0
connexion[swagger-ui] <= 2.14.2; python_version>"3.4"
# connexion requires werkzeug but connexion < 2.4.0 does not install werkzeug
# we must peg werkzeug versions below to fix connexion
# https://github.com/zalando/connexion/pull/1044
werkzeug == 0.16.1; python_version=="3.5" or python_version=="3.4"
swagger-ui-bundle >= 0.0.2
python_dateutil >= 2.6.0
setuptools >= 21.0.0
Flask == 2.1.1
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import connexion
from typing import Dict
from typing import Tuple
from typing import Union

from samples.models.get_db_connect_string200_response import GetDbConnectString200Response # noqa: E501
from samples import util


def get_db_connect_string(): # noqa: E501
"""Get database connection string

Returns the database connection string for the current application. # noqa: E501


:rtype: Union[GetDbConnectString200Response, Tuple[GetDbConnectString200Response, int], Tuple[GetDbConnectString200Response, int, Dict[str, str]]
"""
from cloudharness.applications import get_current_configuration
config = get_current_configuration()
return config.get_db_connection_string()
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from typing import List


def info_from_bearerAuth(token):
"""
Check and retrieve authentication information from custom bearer token.
Returned value will be passed in 'token_info' parameter of your operation function, if there is one.
'sub' or 'uid' will be set in 'user' parameter of your operation function, if there is one.

:param token Token provided by Authorization header
:type token: str
:return: Decoded token information or None if token is invalid
:rtype: dict | None
"""
return {'uid': 'user_id'}


def info_from_cookieAuth(api_key, required_scopes):
"""
Check and retrieve authentication information from api_key.
Returned value will be passed in 'token_info' parameter of your operation function, if there is one.
'sub' or 'uid' will be set in 'user' parameter of your operation function, if there is one.

:param api_key API key provided by Authorization header
:type api_key: str
:param required_scopes Always None. Used for other authentication method
:type required_scopes: None
:return: Information attached to provided api_key or None if api_key is invalid or does not allow access to called API
:rtype: dict | None
"""
return {'uid': 'user_id'}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
from datetime import date, datetime # noqa: F401

from typing import List, Dict # noqa: F401

from samples.models.base_model import Model
from samples import util


class GetDbConnectString200Response(Model):
"""NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).

Do not edit the class manually.
"""

def __init__(self, connect_string=None): # noqa: E501
"""GetDbConnectString200Response - a model defined in OpenAPI

:param connect_string: The connect_string of this GetDbConnectString200Response. # noqa: E501
:type connect_string: str
"""
self.openapi_types = {
'connect_string': str
}

self.attribute_map = {
'connect_string': 'connect_string'
}

self._connect_string = connect_string

@classmethod
def from_dict(cls, dikt) -> 'GetDbConnectString200Response':
"""Returns the dict as a model

:param dikt: A dict.
:type: dict
:return: The get_db_connect_string_200_response of this GetDbConnectString200Response. # noqa: E501
:rtype: GetDbConnectString200Response
"""
return util.deserialize_model(dikt, cls)

@property
def connect_string(self) -> str:
"""Gets the connect_string of this GetDbConnectString200Response.


:return: The connect_string of this GetDbConnectString200Response.
:rtype: str
"""
return self._connect_string

@connect_string.setter
def connect_string(self, connect_string: str):
"""Sets the connect_string of this GetDbConnectString200Response.


:param connect_string: The connect_string of this GetDbConnectString200Response.
:type connect_string: str
"""

self._connect_string = connect_string
19 changes: 18 additions & 1 deletion applications/samples/backend/samples/openapi/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,23 @@ tags:
- description: ""
name: resource
paths:
/db-connect-string:
get:
description: Returns the database connection string for the current application.
operationId: get_db_connect_string
responses:
"200":
content:
application/json:
schema:
type: string
description: Database connection string returned successfully
"500":
description: Error retrieving database connection string
summary: Get database connection string
tags:
- database
x-openapi-router-controller: samples.controllers.database_controller
/error:
get:
operationId: error
Expand Down Expand Up @@ -336,4 +353,4 @@ components:
in: cookie
name: kc-access
type: apiKey
x-apikeyInfoFunc: samples.controllers.security_controller_.info_from_cookieAuth
x-apikeyInfoFunc: cloudharness.auth.decode_token
10 changes: 8 additions & 2 deletions applications/samples/deploy/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ harness:
size: 10Mi
usenfs: false
auto: true
port: 8080
port: 8080
gateway:
path: /
pathType: Prefix
proxy:
gatekeeper:
replicas: 1
Expand Down Expand Up @@ -96,4 +99,7 @@ harness:

dockerfile:
buildArgs:
TEST_ARGUMENT: example value
TEST_ARGUMENT: example value
database:
type: postgres
connect_string: "test connection string"
35 changes: 35 additions & 0 deletions applications/samples/test.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
ARG CLOUDHARNESS_FRONTEND_BUILD
ARG CLOUDHARNESS_FLASK

FROM $CLOUDHARNESS_FRONTEND_BUILD as frontend

ARG TEST_ARGUMENT=default
RUN echo $TEST_ARGUMENT

ENV APP_DIR=/app

WORKDIR ${APP_DIR}
COPY frontend/package.json ${APP_DIR}
COPY frontend/yarn.lock ${APP_DIR}
RUN yarn install --frozen-lockfile --timeout 60000

COPY frontend ${APP_DIR}
RUN yarn build

#####
FROM $CLOUDHARNESS_FLASK
ENV MODULE_NAME=samples

ENV WORKERS=2
ENV PORT=8080

COPY backend/requirements.txt /usr/src/app/

RUN --mount=type=cache,target=/root/.cache python -m pip install --upgrade pip &&\
pip3 install -r requirements.txt --prefer-binary

COPY backend/ /usr/src/app

COPY --from=frontend app/dist/ /usr/src/app/www

RUN pip3 install -e .
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
networks:
- ch
restart: always
image: quay.io/gogatekeeper/gatekeeper:2.14.3
image: quay.io/gogatekeeper/gatekeeper:4.6.0
expose:
- '8080'
- '8443'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,26 @@
value: {{ .app.harness.database.pass | quote }}
- name: PGDATA
value: /data/db/pgdata
livenessProbe:
exec:
command:
- pg_isready
- -U
- {{ .app.harness.database.user | quote }}
- -d
- {{ .app.harness.database.postgres.initialdb | quote }}
initialDelaySeconds: 30
timeoutSeconds: 5
failureThreshold: 6
readinessProbe:
exec:
command:
- pg_isready
- -U
- {{ .app.harness.database.user | quote }}
- -d
- {{ .app.harness.database.postgres.initialdb | quote }}
initialDelaySeconds: 5
timeoutSeconds: 5
failureThreshold: 6
{{- end }}
Loading
Loading