Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove kyverno support #818

Merged
merged 2 commits into from
Dec 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 0 additions & 1 deletion .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ RUN apt-get update --fix-missing && \

COPY --from=docker.io/bitnami/kubectl:1.32.0 /opt/bitnami/kubectl/bin/kubectl /usr/local/bin/kubectl
COPY --from=registry.k8s.io/kustomize/kustomize:v5.4.3 /app/kustomize /usr/local/bin/kustomize
COPY --from=ghcr.io/kyverno/kyverno-cli:v1.13.2 /ko-app/kubectl-kyverno /usr/local/bin/kyverno
COPY --from=docker.io/alpine/helm:3.16.4 /usr/bin/helm /usr/local/bin/helm
COPY --from=ghcr.io/fluxcd/flux-cli:v2.4.0 /usr/local/bin/flux /usr/local/bin/flux

Expand Down
1 change: 0 additions & 1 deletion .github/workflows/flux-local-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ jobs:
- uses: ./action/test
with:
enable-helm: true
enable-kyverno: false
sources: cluster=tests/testdata/cluster3,flux-system,home-ops-kubernetes
path: ${{ matrix.cluster_path }}
api-versions: batch/v1/CronJob
5 changes: 0 additions & 5 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,6 @@ jobs:
- uses: actions/checkout@v4
- name: Setup Flux CLI
uses: fluxcd/flux2/[email protected]
- uses: supplypike/setup-bin@v4
with:
uri: https://github.com/kyverno/kyverno/releases/download/v1.11.3/kyverno-cli_v1.11.3_linux_x86_64.tar.gz
name: kyverno-cli
version: v1.11.3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
Expand Down
1 change: 0 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:3.13-alpine as base

Check warning on line 1 in Dockerfile

View workflow job for this annotation

GitHub Actions / test

The 'as' keyword should match the case of the 'from' keyword

FromAsCasing: 'as' and 'FROM' keywords' casing do not match More info: https://docs.docker.com/go/dockerfile/rule/from-as-casing/

RUN apk add --no-cache ca-certificates git

Expand All @@ -13,7 +13,6 @@
COPY --from=docker.io/alpine/helm:3.16.4 /usr/bin/helm /usr/local/bin/helm
COPY --from=docker.io/bitnami/kubectl:1.32.0 /opt/bitnami/kubectl/bin/kubectl /usr/local/bin/kubectl
COPY --from=registry.k8s.io/kustomize/kustomize:v5.4.3 /app/kustomize /usr/local/bin/kustomize
COPY --from=ghcr.io/kyverno/kyverno-cli:v1.13.2 /ko-app/kubectl-kyverno /usr/local/bin/kyverno

USER 1001
ENTRYPOINT ["/usr/local/bin/flux-local"]
18 changes: 2 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,18 +209,7 @@ collected 18 items

You may also validate `HelmRelease` objects can be templated properly with the `--enable-helm`
flag. This will run `kustomize build` then run `helm template` on all the `HelmRelease` objects
found. Additionally the `--enable-kyverno` flag will apply any found `ClusterPolicy` objects to
all objects in the cluster and verify they pass:
```
$ flux-local test --enable-helm --enable-kyverno
============================================= test session starts =============================================
collected 81 items

clusters/dev ..................................... [ 45%]
clusters/prod ............................................ [100%]

======================================== 81 passed in 75.40s (0:01:15) ========================================
```
found.

## GitHub Action

Expand All @@ -230,9 +219,7 @@ or PRs. The actions expect to find the `flux` and `kustomize` binaries installed
### test action

The `test` action will validate the cluster will build, and can optionally
validate flux `HelmRelease` builds and also verify that all objects pass
kyverno policies (e.g. for determining there are no deprecated api resources
or that ingress objects are valid).
validate flux `HelmRelease` builds.

This example will run `flux-local test` against the cluster in `clusters/prod` with
helm release expansion enabled.
Expand All @@ -244,7 +231,6 @@ helm release expansion enabled.
with:
path: clusters/prod
enable-helm: true
enable-kyverno: false
```

### diff action
Expand Down
14 changes: 0 additions & 14 deletions action/test/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,6 @@ inputs:
description: Kubernetes api versions used for helm Capabilities.APIVersions
default: policy/v1/PodDisruptionBudget
required: false
enable-kyverno:
description: Validate cluster resources against kyverno policies found in the cluster
default: false
required: false
kyverno-version:
description: Kyverno version to use when enabled
default: v1.9.0
python-version:
description: Python version used for running flux-local
default: "3.10"
Expand Down Expand Up @@ -57,19 +50,12 @@ runs:
pip install -r ${{ steps.copy-requirements.outputs.directory }}/requirements.txt
pip install -e ${{ github.action_path }}/../../
shell: bash
- uses: supplypike/setup-bin@v3
with:
uri: https://github.com/kyverno/kyverno/releases/download/${{ inputs.kyverno-version }}/kyverno-cli_${{ inputs.kyverno-version }}_linux_x86_64.tar.gz
name: "kyverno-cli"
version: ${{ inputs.kyverno-version }}
if: ${{ inputs.enable-kyverno == 'true' }}
- name: Test cluster (flux-local)
run: |
flux-local \
--log-level ${{ inputs.debug != 'true' && 'INFO' || 'DEBUG' }} \
test \
--${{ inputs.enable-helm != 'true' && 'no-' || '' }}enable-helm \
--${{ inputs.enable-kyverno != 'true' && 'no-' || '' }}enable-kyverno \
--api-versions "${{ inputs.api-versions }}" \
--kustomize-build-flags="${{ inputs.kustomize-build-flags }}" \
--sources "${{ inputs.sources }}" \
Expand Down
4 changes: 0 additions & 4 deletions flux_local/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,6 @@ class HelmException(CommandException):
"""Raised when there is a failure running a helm command."""


class KyvernoException(CommandException):
"""Raised when there is an error running kyverno policy command."""


class InvalidValuesReference(FluxException):
"""Exception raised for an unsupported ValuesReference."""

Expand Down
32 changes: 1 addition & 31 deletions flux_local/git_repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@
FLUXTOMIZE_DOMAIN,
KUSTOMIZE_DOMAIN,
Cluster,
ClusterPolicy,
HelmRelease,
HelmRepository,
Kustomization,
Expand Down Expand Up @@ -77,7 +76,6 @@
KUSTOMIZE_KIND = "Kustomization"
HELM_REPO_KIND = "HelmRepository"
HELM_RELEASE_KIND = "HelmRelease"
CLUSTER_POLICY_KIND = "ClusterPolicy"
GIT_REPO_KIND = "GitRepository"
OCI_REPO_KIND = "OCIRepository"
DEFAULT_NAMESPACE = "flux-system"
Expand Down Expand Up @@ -208,7 +206,6 @@ class ResourceVisitor:
Kustomization
| HelmRelease
| HelmRepository
| ClusterPolicy
| OCIRepository,
kustomize.Kustomize | None,
],
Expand Down Expand Up @@ -271,7 +268,7 @@ class MetadataSelector:
def predicate(
self,
) -> Callable[
[Kustomization | HelmRelease | HelmRepository | ClusterPolicy | OCIRepository],
[Kustomization | HelmRelease | HelmRepository | OCIRepository],
bool,
]:
"""A predicate that selects Kustomization objects."""
Expand All @@ -281,7 +278,6 @@ def predicate(
Kustomization
| HelmRelease
| HelmRepository
| ClusterPolicy
| OCIRepository
),
) -> bool:
Expand Down Expand Up @@ -340,9 +336,6 @@ class ResourceSelector:
oci_repo: MetadataSelector = field(default_factory=MetadataSelector)
"""OCIRepository objects to return."""

cluster_policy: MetadataSelector = field(default_factory=MetadataSelector)
"""ClusterPolicy objects to return."""

doc_visitor: DocumentVisitor | None = None
"""Raw objects to visit."""

Expand Down Expand Up @@ -587,13 +580,11 @@ async def build_kustomization(
helm_repo_selector: MetadataSelector = selector.helm_repo
oci_repo_selector: MetadataSelector = selector.oci_repo
helm_release_selector: MetadataSelector = selector.helm_release
cluster_policy_selector: MetadataSelector = selector.cluster_policy
if (
not kustomization_selector.enabled
and not helm_repo_selector.enabled
and not oci_repo_selector.visitor
and not helm_release_selector.enabled
and not cluster_policy_selector.enabled
and not selector.doc_visitor
):
return
Expand Down Expand Up @@ -633,8 +624,6 @@ async def build_kustomization(
kinds.append(HELM_RELEASE_KIND)
# Needed for expanding value references
kinds.append(SECRET_KIND)
if cluster_policy_selector.enabled:
kinds.append(CLUSTER_POLICY_KIND)
if selector.doc_visitor:
kinds.extend(selector.doc_visitor.kinds)
if not kinds:
Expand Down Expand Up @@ -681,16 +670,6 @@ async def build_kustomization(
],
)
)
kustomization.cluster_policies = list(
filter(
cluster_policy_selector.predicate,
[
ClusterPolicy.parse_doc(doc)
for doc in docs
if doc.get("kind") == CLUSTER_POLICY_KIND
],
)
)
kustomization.config_maps = [
ConfigMap.parse_doc(doc)
for doc in docs
Expand Down Expand Up @@ -842,15 +821,6 @@ async def update_kustomization(cluster: Cluster) -> None:
None,
)

if selector.cluster_policy.visitor:
for kustomization in cluster.kustomizations:
for cluster_policy in kustomization.cluster_policies:
await selector.cluster_policy.visitor.func(
Path(kustomization.path),
cluster_policy,
None,
)

return Manifest(clusters=clusters)


Expand Down
42 changes: 0 additions & 42 deletions flux_local/kustomize.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@
for object in objects:
print(f"Found ConfigMap: {object['metadata']['name']}")
```

You can apply kyverno policies to the objects with the `validate` method.
"""

from aiofiles.ospath import isdir
Expand All @@ -40,7 +38,6 @@
from collections.abc import AsyncIterator
import logging
from pathlib import Path
import tempfile
from typing import Any, AsyncGenerator

import yaml
Expand All @@ -50,7 +47,6 @@
from .exceptions import (
InputException,
KustomizeException,
KyvernoException,
KustomizePathException,
)
from .manifest import Kustomization
Expand All @@ -64,7 +60,6 @@
]

KUSTOMIZE_BIN = "kustomize"
KYVERNO_BIN = "kyverno"
FLUX_BIN = "flux"
HELM_RELEASE_KIND = "HelmRelease"

Expand Down Expand Up @@ -148,43 +143,6 @@ def filter_resources(self, kinds: list[str]) -> "Kustomize":
skip_re = "|".join(kinds)
return self.grep(f"kind=^({skip_re})$", invert=False)

async def validate_policies(self, policies: list[manifest.ClusterPolicy]) -> None:
"""Apply kyverno policies to objects built so far."""
if not policies:
return
_LOGGER.debug("Validating policies (len=%d)", len(policies))
with tempfile.TemporaryDirectory() as tmpdir:
policyfile = Path(tmpdir) / "policies.yaml"
policyfile.write_text(
yaml.dump_all(
[policy.doc for policy in policies],
sort_keys=False,
explicit_start=True,
)
)
await self.validate(policyfile)

async def validate(self, policy_path: Path) -> None:
"""Apply kyverno policies from the directory to any objects built so far.

The specified `policy_path` is a file or directory containing policy objects.
All secrets will stripped since otherwise they fail the kyverno cli.
"""
kustomize = self.skip_resources([manifest.SECRET_KIND])
cmds = kustomize._cmds + [ # pylint: disable=protected-access
Command(
[
KYVERNO_BIN,
"apply",
str(policy_path),
"--resource",
"-",
],
exc=KyvernoException,
),
]
await run_piped(cmds)

async def stash(self) -> "Kustomize":
"""Memoize the contents built so far for efficient reuse.

Expand Down
41 changes: 0 additions & 41 deletions flux_local/manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
"HelmRepository",
"HelmRelease",
"HelmChart",
"ClusterPolicy",
"ConfigMap",
"Secret",
]
Expand All @@ -42,7 +41,6 @@
HELM_REPO_DOMAIN = "source.toolkit.fluxcd.io"
HELM_RELEASE_DOMAIN = "helm.toolkit.fluxcd.io"
OCI_REPOSITORY_DOMAIN = "source.toolkit.fluxcd.io"
CLUSTER_POLICY_DOMAIN = "kyverno.io"
CRD_KIND = "CustomResourceDefinition"
SECRET_KIND = "Secret"
CONFIG_MAP_KIND = "ConfigMap"
Expand Down Expand Up @@ -336,33 +334,6 @@ def repo_name(self) -> str:
return f"{self.namespace}-{self.name}"


@dataclass
class ClusterPolicy(BaseManifest):
"""A kyverno policy object."""

name: str
"""The name of the kustomization."""

namespace: str | None = None
"""The namespace of the kustomization."""

doc: dict[str, Any] | None = field(metadata={"serialize": "omit"}, default=None)
"""The raw ClusterPolicy document."""

@classmethod
def parse_doc(cls, doc: dict[str, Any]) -> "ClusterPolicy":
"""Parse a cluster policy object from a kubernetes resource."""
_check_version(doc, CLUSTER_POLICY_DOMAIN)
if not (metadata := doc.get("metadata")):
raise InputException(f"Invalid {cls} missing metadata: {doc}")
if not (name := metadata.get("name")):
raise InputException(f"Invalid {cls} missing metadata.name: {doc}")
namespace = metadata.get("namespace")
if not doc.get("spec"):
raise InputException(f"Invalid {cls} missing spec: {doc}")
return ClusterPolicy(name=name, namespace=namespace, doc=doc)


@dataclass
class ConfigMap(BaseManifest):
"""A ConfigMap is an API object used to store data in key-value pairs."""
Expand Down Expand Up @@ -481,9 +452,6 @@ class Kustomization(BaseManifest):
helm_releases: list[HelmRelease] = field(default_factory=list)
"""The set of HelmRelease represented in this kustomization."""

cluster_policies: list[ClusterPolicy] = field(default_factory=list)
"""The set of ClusterPolicies represented in this kustomization."""

config_maps: list[ConfigMap] = field(default_factory=list)
"""The list of config maps referenced in the kustomization."""

Expand Down Expand Up @@ -648,15 +616,6 @@ def helm_releases(self) -> list[HelmRelease]:
for release in kustomization.helm_releases
]

@property
def cluster_policies(self) -> list[ClusterPolicy]:
"""Return the list of ClusterPolicy objects from all Kustomizations."""
return [
policy
for kustomization in self.kustomizations
for policy in kustomization.cluster_policies
]


@dataclass
class Manifest(BaseManifest):
Expand Down
2 changes: 0 additions & 2 deletions flux_local/tool/selector.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@ def build_ks_selector( # type: ignore[no-untyped-def]
selector.kustomization.namespace = None
selector.kustomization.skip_crds = kwargs["skip_crds"]
selector.kustomization.skip_secrets = kwargs["skip_secrets"]
selector.cluster_policy.enabled = False
return selector


Expand Down Expand Up @@ -170,7 +169,6 @@ def build_hr_selector( # type: ignore[no-untyped-def]
selector.helm_release.skip_secrets = kwargs["skip_secrets"]
selector.kustomization.name = None
selector.kustomization.namespace = None
selector.cluster_policy.enabled = False
return selector


Expand Down
Loading
Loading