diff --git a/.github/workflows/integration_test.yaml b/.github/workflows/integration_test.yaml index b5132c2..cb6bb92 100644 --- a/.github/workflows/integration_test.yaml +++ b/.github/workflows/integration_test.yaml @@ -10,4 +10,8 @@ jobs: with: setup-devstack-swift: true trivy-image-config: "trivy.yaml" + juju-channel: 3/stable + channel: 1.29-strict/stable extra-arguments: "--openstack-rc=${GITHUB_WORKSPACE}/openrc" + self-hosted-runner: true + self-hosted-runner-label: self-hosted-linux-amd64-jammy-large diff --git a/.licenserc.yaml b/.licenserc.yaml index e4a7d1b..ed68438 100644 --- a/.licenserc.yaml +++ b/.licenserc.yaml @@ -19,6 +19,7 @@ header: - '.flake8' - '.jujuignore' - '.gitignore' + - '.trivyignore' - '.licenserc.yaml' - 'CODEOWNERS' - 'icon.svg' diff --git a/.trivyignore b/.trivyignore new file mode 100644 index 0000000..503ffd2 --- /dev/null +++ b/.trivyignore @@ -0,0 +1,27 @@ +CVE-2023-24538 +CVE-2023-24540 +CVE-2024-24790 +CVE-2022-27664 +CVE-2022-2879 +CVE-2022-2880 +CVE-2022-32190 +CVE-2022-41715 +CVE-2022-41716 +CVE-2022-41720 +CVE-2022-41722 +CVE-2022-41723 +CVE-2022-41724 +CVE-2022-41725 +CVE-2023-24534 +CVE-2023-24536 +CVE-2023-24537 +CVE-2023-24539 +CVE-2023-29400 +CVE-2023-29403 +CVE-2023-39325 +CVE-2023-45283 +CVE-2023-45287 +CVE-2023-45288 +CVE-2024-34156 +# Pebble vulnerabilities +CVE-2024-45338 diff --git a/README.md b/README.md index 1531b6c..7200c92 100644 --- a/README.md +++ b/README.md @@ -5,16 +5,15 @@ # Content Cache Operator -A Juju charm for deploying and managing a content cache. +A [Juju](https://juju.is/) [charm](https://juju.is/docs/olm/charmed-operators) deploying and managing service for caching content on Kubernetes, built on top of [Nginx](https://www.nginx.com/), configurable to cache any http or https web site and useful for building Content Delivery Networks (CDN). -## Overview - -A service for caching content, built on top of [Nginx](https://www.nginx.com/), -configurable to cache any http or https web site. Tuning options include -cache storage size, maximum request size to cache and cache validity duration. +Like any Juju charm, this charm supports one-line deployment, configuration, integration, scaling, and more. For Charmed Content Cache, this includes: +* scaling the number of cache instances +* cache configuration changes +* deployment on many different Kubernetes platforms, from MicroK8s to Charmed Kubernetes and public cloud Kubernetes offerings This service was developed to provide front-end caching for web sites run by -Canonical's IS team, and to reduce the need for third-party CDNs by providing +Canonical's IS (Infrastructure Services) team, and to reduce the need for third-party CDNs by providing high-bandwidth access to web sites via this caching front-end. Currently used for a number of services including [the Snap Store](https://snapcraft.io/store), the majority of Canonical's web properties including [ubuntu.com](https://ubuntu.com) and @@ -24,17 +23,55 @@ This Kubernetes-based version is built using the same approach as the [machine c a situation where your Kubernetes cluster and its ingress controllers have a fast connection to the Internet. +For information about how to deploy, integrate, and manage this charm, see the Official [Content Cache Documentation](https://charmhub.io/content-cache-k8s/docs). + +## Get started + +To begin, refer to the [Content Cache tutorial](https://charmhub.io/content-cache-k8s/docs/tutorial-getting-started) for step-by-step instructions. + +### Basic operations + +The following actions are available for the charm: +- report-visits-by-ip + +Tuning options include: +- cache storage size +- maximum request size to cache +- cache validity duration + +You can find more information about supported actions in [the Charmhub documentation](https://charmhub.io/content-cache-k8s/actions). + +## Integrations + +Content-cache is meant to serve as cache for another charm. You can use Wordpress as an example: + +``` +juju deploy content-cache-k8s +juju deploy wordpress-k8s +juju deploy mysql-k8s --trust + +juju integrate wordpress-k8s mysql-k8s:database +juju integrate content-cache-k8s:nginx-proxy wordpress-k8s +``` + +Apart from this integration, the charm can be integrated with other Juju charms and services as well. You can find the full list of integrations in [the Charmhub documentation](https://charmhub.io/content-cache-k8s/integrations). + + +## Learn more + +- [Read more](https://charmhub.io/content-cache-k8s/docs) +- [Developer documentation](https://nginx.org/en/docs/dev/development_guide.html) +- [Official webpage](https://www.nginx.com/) +- [Troubleshooting](https://matrix.to/#/#charmhub-charmdev:ubuntu.com) + + ## Project and community -The Content-cache-k8s Operator is a member of the Ubuntu family. It's an +The Content-cache-k8s Operator is a member of the Ubuntu family. It is an open source project that warmly welcomes community projects, contributions, suggestions, fixes and constructive feedback. * [Code of conduct](https://ubuntu.com/community/code-of-conduct) * [Get support](https://discourse.charmhub.io/) -* [Join our online chat](https://chat.charmhub.io/charmhub/channels/charm-dev) -* [Contribute](https://charmhub.io/content-cache-k8s/docs/how-to-guides-contributing) -Thinking about using the Content-cache-k8s for your next project? [Get in touch](https://chat.charmhub.io/charmhub/channels/charm-dev)! - ---- - -For further details, [see the charm's detailed documentation](https://charmhub.io/content-cache-k8s/docs) +* [Contribute](https://charmhub.io/content-cache-k8s/docs/how-to-contribute) +* [Issues](https://github.com/canonical/content-cache-k8s-operator/issues) +* [Matrix](https://matrix.to/#/#charmhub-charmdev:ubuntu.com) diff --git a/charmcraft.yaml b/charmcraft.yaml index 4c562bf..3ed817b 100644 --- a/charmcraft.yaml +++ b/charmcraft.yaml @@ -11,5 +11,21 @@ bases: channel: "22.04" parts: charm: - prime: + plugin: charm + source: . + build-snaps: + - rustup + override-build: | + rustup default stable + craftctl default + build-packages: + - libffi-dev + - libssl-dev + - pkg-config + rock_data: + plugin: dump + source: . + prime: - content-cache_rock/nginx_cfg.tmpl + + diff --git a/content-cache_rock/rockcraft.yaml b/content-cache_rock/rockcraft.yaml index 6f36dc4..46a8c8f 100644 --- a/content-cache_rock/rockcraft.yaml +++ b/content-cache_rock/rockcraft.yaml @@ -4,7 +4,7 @@ name: content-cache summary: Content-cache-k8s ROCK image. description: Content-cache-k8s ROCK. version: "latest" -base: ubuntu:22.04 +base: ubuntu@22.04 license: Apache-2.0 platforms: amd64: diff --git a/requirements.txt b/requirements.txt index 9684eab..c435b27 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -cosl -ops>=1.2.0 -tabulate +cosl==0.0.48 +ops==2.17.1 +tabulate==0.9.0 diff --git a/src/charm.py b/src/charm.py index 59cc23d..023c88f 100755 --- a/src/charm.py +++ b/src/charm.py @@ -11,6 +11,7 @@ from datetime import datetime, timedelta from urllib.parse import urlparse +import ops.pebble from charms.grafana_k8s.v0.grafana_dashboard import GrafanaDashboardProvider from charms.loki_k8s.v0.loki_push_api import LogProxyConsumer from charms.nginx_ingress_integrator.v0.nginx_route import ( @@ -268,7 +269,7 @@ def _generate_keys_zone(self, name): hashed_name = hashed_value.hexdigest()[0:12] return f"{hashed_name}-cache" - def _get_nginx_prometheus_exporter_pebble_config(self): + def _get_nginx_prometheus_exporter_pebble_config(self) -> ops.pebble.LayerDict: """Generate pebble config for the nginx-prometheus-exporter container. Returns: @@ -278,7 +279,7 @@ def _get_nginx_prometheus_exporter_pebble_config(self): "summary": "Nginx prometheus exporter", "description": "Prometheus exporter for nginx", "services": { - "nginx-prometheus-exporter": { + EXPORTER_CONTAINER_NAME: { "override": "replace", "summary": "Nginx Prometheus Exporter", "command": ( @@ -286,6 +287,7 @@ def _get_nginx_prometheus_exporter_pebble_config(self): f" -nginx.scrape-uri=http://localhost:{CONTAINER_PORT}/stub_status" ), "startup": "enabled", + "requires": [CONTAINER_NAME], }, }, "checks": { @@ -401,7 +403,7 @@ def _make_env_config(self, domain="svc.cluster.local") -> dict: return env_config - def _make_pebble_config(self, env_config) -> dict: + def _make_pebble_config(self, env_config) -> ops.pebble.PlanDict: """Generate our pebble config layer. Args: @@ -422,6 +424,13 @@ def _make_pebble_config(self, env_config) -> dict: "environment": env_config, }, }, + "checks": { + CONTAINER_NAME: { + "override": "replace", + "exec": {"command": "ps -A | grep nginx"}, + "threshold": 1, + } + }, } return pebble_config diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index c504dfb..63b9a48 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -43,6 +43,7 @@ async def _run_action(application_name: str, action_name: str, **params): Returns: The results of the executed action """ + assert ops_test.model application = ops_test.model.applications[application_name] action = await application.units[0].run_action(action_name, **params) await action.wait() @@ -143,6 +144,7 @@ async def app( channel="beta", config={"src-overwrite": json.dumps(any_charm_src_overwrite)}, ) + await ops_test.model.wait_for_idle(timeout=600) await run_action(any_app_name, "rpc", method="start_server") await ops_test.model.wait_for_idle() diff --git a/tests/unit/test_charm.py b/tests/unit/test_charm.py index ca5b6bc..30a233c 100644 --- a/tests/unit/test_charm.py +++ b/tests/unit/test_charm.py @@ -51,6 +51,13 @@ "environment": "", }, }, + "checks": { + CONTAINER_NAME: { + "override": "replace", + "exec": {"command": "ps -A | grep nginx"}, + "threshold": 1, + } + }, } DATE_NOW = datetime.now().strftime("%d/%b/%Y:%H:%M:%S") diff --git a/tox.ini b/tox.ini index f341365..3ee1f29 100644 --- a/tox.ini +++ b/tox.ini @@ -63,7 +63,6 @@ commands = [testenv:unit] description = Run unit tests deps = - cosl pytest coverage[toml] -r{toxinidir}/requirements.txt @@ -78,7 +77,6 @@ setenv = PYTHONPATH = {toxinidir}:{toxinidir}/lib:{[vars]src_path} description = Generate documentation for src deps = - cosl lazydocs -r{toxinidir}/requirements.txt commands = @@ -108,8 +106,7 @@ deps = pytest pytest-cov pytest-operator - # Last compatible version with Juju 2.9 - juju==3.0.4 + juju -r{toxinidir}/requirements.txt -r{toxinidir}/tests/integration/requirements.txt commands =