-
Notifications
You must be signed in to change notification settings - Fork 335
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
feat(*): automate policy generation #4197
Changes from 13 commits
cb64fdd
d33bab5
807bc87
49e2e5e
2988671
767c919
725e349
b0cab1b
74e1e0c
2fe4ad8
2520bba
4a3fe6e
ecd5747
d571414
96bbcad
8c43d35
f3638cb
9e530b4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
syntax = "proto3"; | ||
|
||
package kuma.plugins.policies.donothingpolicy.v1alpha1; | ||
|
||
import "mesh/options.proto"; | ||
option go_package = "github.com/kumahq/kuma/pkg/plugins/policies/donothingpolicy/api/v1alpha1"; | ||
|
||
import "mesh/v1alpha1/selector.proto"; | ||
import "config.proto"; | ||
|
||
option (doc.config) = { | ||
type : Policy, | ||
name : "DoNothingPolicy", | ||
file_name : "donothingpolicy" | ||
}; | ||
|
||
// DoNothingPolicy defines permission for traffic between dataplanes. | ||
message DoNothingPolicy { | ||
|
||
option (kuma.mesh.resource).name = "DoNothingPolicyResource"; | ||
option (kuma.mesh.resource).type = "DoNothingPolicy"; | ||
option (kuma.mesh.resource).package = "mesh"; | ||
option (kuma.mesh.resource).kds.send_to_zone = true; | ||
option (kuma.mesh.resource).ws.name = "donothingpolicy"; | ||
option (kuma.mesh.resource).ws.plural = "donothingpolicies"; | ||
option (kuma.mesh.resource).allow_to_inspect = true; | ||
|
||
// List of selectors to match dataplanes that are sources of traffic. | ||
repeated kuma.mesh.v1alpha1.Selector sources = 1 [ (doc.required) = true ]; | ||
// List of selectors to match services that are destinations of traffic. | ||
repeated kuma.mesh.v1alpha1.Selector destinations = 2 | ||
[ (doc.required) = true ]; | ||
|
||
message Conf { | ||
// Set true in case of doing nothing | ||
bool enableDoNothing = 1; | ||
} | ||
|
||
Conf conf = 3; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
# How to generate a new Kuma policy | ||
|
||
1. Create a new directory for the policy in `pkg/plugins/policies`. Example: | ||
```shell | ||
mkdir -p pkg/plugins/policies/donothingpolicy | ||
``` | ||
|
||
2. Create a proto file for new policy in `pkg/plugins/policies/donothingpolicy/api/v1alpha1`. For example | ||
donothingpolicy.proto: | ||
```protobuf | ||
syntax = "proto3"; | ||
|
||
package kuma.plugins.policies.donothingpolicy.v1alpha1; | ||
|
||
import "mesh/options.proto"; | ||
option go_package = "github.com/kumahq/kuma/pkg/plugins/policies/donothingpolicy/api/v1alpha1"; | ||
|
||
import "mesh/v1alpha1/selector.proto"; | ||
import "config.proto"; | ||
|
||
option (doc.config) = { | ||
type : Policy, | ||
name : "DoNothingPolicy", | ||
file_name : "donothingpolicy" | ||
}; | ||
|
||
// DoNothingPolicy defines permission for traffic between dataplanes. | ||
message DoNothingPolicy { | ||
|
||
option (kuma.mesh.resource).name = "DoNothingPolicyResource"; | ||
option (kuma.mesh.resource).type = "DoNothingPolicy"; | ||
option (kuma.mesh.resource).package = "mesh"; | ||
option (kuma.mesh.resource).kds.send_to_zone = true; | ||
option (kuma.mesh.resource).ws.name = "donothingpolicy"; | ||
option (kuma.mesh.resource).ws.plural = "donothingpolicies"; | ||
option (kuma.mesh.resource).allow_to_inspect = true; | ||
|
||
// List of selectors to match dataplanes that are sources of traffic. | ||
repeated kuma.mesh.v1alpha1.Selector sources = 1 [ (doc.required) = true ]; | ||
// List of selectors to match services that are destinations of traffic. | ||
repeated kuma.mesh.v1alpha1.Selector destinations = 2 [ (doc.required) = true ]; | ||
|
||
message Conf { | ||
bool enableDoNothing = 1; | ||
} | ||
|
||
Conf conf = 3; | ||
|
||
} | ||
``` | ||
|
||
3. Call `make generate/policy/<POLICY_NAME>`. Example: | ||
```shell | ||
make generate/policy/donothingpolicy | ||
``` | ||
|
||
4. **Optional.** Add validation. Create file `validator.go`, file with such name won't be cleaned up | ||
by `make cleanup/policy/donothingpolicy`. Implement method `validate() error`: | ||
```go | ||
package v1alpha1 | ||
|
||
func (t *DoNothingPolicyResource) validate() error { | ||
// validate resource here | ||
return nil | ||
} | ||
``` | ||
|
||
6. Add import to `pkg/core/bootstrap/plugins.go`: | ||
```go | ||
_ "github.com/kumahq/kuma/pkg/plugins/policies/donothingpolicy" | ||
lobkovilya marked this conversation as resolved.
Show resolved
Hide resolved
|
||
``` | ||
|
||
7. Update Helm chart with a new CRD: | ||
```shell | ||
make generate/helm/donothingpolicy | ||
``` | ||
Also, today it's required to update `cp-rbac.yaml` manually, automation is yet to come. | ||
|
||
Now you can check swagger-ui for this policy: | ||
|
||
```shell | ||
docker run -p 80:8080 -e SWAGGER_JSON=/policy/rest.yaml -v $PWD/pkg/plugins/policies/donothingpolicy/api/v1alpha1:/policy swaggerapi/swagger-ui | ||
``` | ||
lobkovilya marked this conversation as resolved.
Show resolved
Hide resolved
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,49 @@ | ||||||
#!/bin/bash | ||||||
|
||||||
set -o errexit | ||||||
set -o pipefail | ||||||
set -o nounset | ||||||
|
||||||
POLICY=$1 | ||||||
VERSION=${2:-"v1alpha1"} | ||||||
|
||||||
POLICIES_DIR=pkg/plugins/policies | ||||||
POLICIES_API_DIR="${POLICIES_DIR}/${POLICY}/api/${VERSION}" | ||||||
POLICIES_CRD_DIR="${POLICIES_DIR}/${POLICY}/k8s/crd" | ||||||
|
||||||
SCHEMA_TEMPLATE=tools/policy-gen/templates/schema.yaml | ||||||
|
||||||
# 1. Copy file ${SCHEMA_TEMPLATE} to ${POLICIES_API_DIR}/schema.yaml. It contains | ||||||
# information about fields that are equal for all resources 'type', 'mesh' and 'name'. | ||||||
# | ||||||
# 2. Using yq extract item from the list '.spec.version[]' that has ${VERSION} and | ||||||
# take '.schema.openAPIV3Schema.properties.spec'. | ||||||
# | ||||||
# 3. Delete 'type' and 'description' for the extracted item, because these are 'type' | ||||||
# and 'description' for the 'spec' field. | ||||||
# | ||||||
# 4. Using yq eval-all with ireduce merge the file from Step 1 and output from Step 3, | ||||||
# placing the result into the file from Step 1 | ||||||
|
||||||
echo "Generating schema for ${POLICY}/${VERSION} based on CRD" | ||||||
|
||||||
function cleanupOnError() { | ||||||
rm "${POLICIES_API_DIR}"/schema.yaml | ||||||
echo "Script failed, schema.yaml wasn't generated" | ||||||
} | ||||||
trap cleanupOnError ERR | ||||||
|
||||||
cp "${SCHEMA_TEMPLATE}" "${POLICIES_API_DIR}"/schema.yaml | ||||||
|
||||||
if [ "$(find "${POLICIES_CRD_DIR}" -type f | wc -l | xargs echo)" != 1 ]; then | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Doesn't There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know why but it's |
||||||
echo "Exactly 1 file is expected in ${POLICIES_CRD_DIR}" | ||||||
exit 1 | ||||||
fi | ||||||
|
||||||
CRD_FILE=$(find "${POLICIES_CRD_DIR}" -type f) | ||||||
|
||||||
# we don't want expressions to be expanded with yq, that's why we're intentionally using single quotes | ||||||
# shellcheck disable=SC2016 | ||||||
yq e '.spec.versions[] | select (.name == "'"${VERSION}"'") | .schema.openAPIV3Schema.properties.spec | del(.type) | del(.description)' \ | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. May be my bash skills but this is an effort to read IMO, isn't
? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tried the option you proposed, but for some reason, it doesn't work. It just ignores escaping (debug mode output):
I can leave a comment about why we need
|
||||||
"${CRD_FILE}" | yq eval-all -i '. as $item ireduce ({}; . * $item )' \ | ||||||
"${POLICIES_API_DIR}"/schema.yaml - |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#!/bin/bash | ||
|
||
set -o errexit | ||
set -o pipefail | ||
set -o nounset | ||
|
||
POLICY=$1 | ||
|
||
POLICIES_DIR=pkg/plugins/policies | ||
POLICIES_CRD_DIR="${POLICIES_DIR}/${POLICY}/k8s/crd" | ||
|
||
if [ "$(find "${POLICIES_CRD_DIR}" -type f | wc -l | xargs echo)" != 1 ]; then | ||
echo "More than 1 file in crd directory" | ||
exit 1 | ||
fi | ||
|
||
CRD_FILE="$(find "${POLICIES_CRD_DIR}" -type f)" | ||
|
||
HELM_CRD_DIR=deployments/charts/kuma/crds | ||
|
||
cp "${CRD_FILE}" "${HELM_CRD_DIR}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe best just to link to the file