Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
Signed-off-by: kaku <[email protected]>
  • Loading branch information
likakuli committed May 6, 2022
1 parent 44b99bd commit f298e37
Show file tree
Hide file tree
Showing 32 changed files with 3,031 additions and 2 deletions.
64 changes: 64 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: build

on:
# Run this workflow every time a new commit pushed to upstream/fork repository.
# Run workflow on fork repository will help contributors find and resolve issues before sending a PR.
push:
pull_request:
jobs:
golangci:
name: lint
runs-on: ubuntu-18.04
steps:
- name: checkout code
uses: actions/checkout@v2
- name: install Go
uses: actions/setup-go@v2
with:
go-version: 1.17.x
- name: lint
run: hack/verify-staticcheck.sh.sh
- name: import alias
run: hack/verify-import-aliases.sh
fmt:
name: gofmt
runs-on: ubuntu-18.04
steps:
- name: checkout code
uses: actions/checkout@v2
- name: install Go
uses: actions/setup-go@v2
with:
go-version: 1.17.x
- name: go fmt check
run: make fmt-check
vet:
name: go vet
runs-on: ubuntu-18.04
steps:
- name: checkout code
uses: actions/checkout@v2
- name: install Go
uses: actions/setup-go@v2
with:
go-version: 1.17.x
- name: go vet
run: make vet
test:
name: unit test
needs:
- fmt
- vet
runs-on: ubuntu-18.04
steps:
- name: checkout code
uses: actions/checkout@v2
- name: install Go
uses: actions/setup-go@v2
with:
go-version: 1.17.x
- name: Run coverage
run: ./script/test.sh
- name: Codecov
uses: codecov/[email protected]

6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*.dll
*.so
*.dylib
kinitiras-webhook

# Test binary, built with `go test -c`
*.test
Expand All @@ -12,4 +13,7 @@
*.out

# Dependency directories (remove the comment below to include it)
# vendor/
vendor/

# IDE
.idea/
128 changes: 128 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# Go information
GO ?= go
GOFMT ?= gofmt "-s"
GOOS ?= $(shell go env GOOS)
GOARCH ?= $(shell go env GOARCH)
SOURCES := $(shell find . -type f -name '*.go')

GOFILES := $(shell find . -name "*.go" | grep -v vendor)
TESTFOLDER := $(shell $(GO) list ./... | grep -v examples)
TESTTAGS ?= ""
VETPACKAGES ?= $(shell $(GO) list ./... | grep -v /examples/)

# Images management
REGISTRY?="registry.cn-hangzhou.aliyuncs.com/k-cloud-labs"

# Git information
GIT_VERSION ?= $(shell git describe --tags --dirty --always)
GIT_COMMIT_HASH ?= $(shell git rev-parse HEAD)
GIT_TREESTATE = "clean"
GIT_DIFF = $(shell git diff --quiet >/dev/null 2>&1; if [ $$? -eq 1 ]; then echo "1"; fi)
ifeq ($(GIT_DIFF), 1)
GIT_TREESTATE = "dirty"
endif
BUILDDATE = $(shell date -u +'%Y-%m-%dT%H:%M:%SZ')

LDFLAGS := "-X github.com/k-cloud-labs/kinitiras/pkg/version.gitVersion=$(GIT_VERSION) \
-X github.com/k-cloud-labs/kinitiras/pkg/version.gitCommit=$(GIT_COMMIT_HASH) \
-X github.com/k-cloud-labs/kinitiras/pkg/version.gitTreeState=$(GIT_TREESTATE) \
-X github.com/k-cloud-labs/kinitiras/pkg/version.buildDate=$(BUILDDATE)"

# Set your version by env or using latest tags from git
VERSION?=""
ifeq ($(VERSION), "")
LATEST_TAG=$(shell git describe --tags --always)
ifeq ($(LATEST_TAG),)
# Forked repo may not sync tags from upstream, so give it a default tag to make CI happy.
VERSION="unknown"
else
VERSION=$(LATEST_TAG)
endif
endif

# Setting SHELL to bash allows bash commands to be executed by recipes.
# This is a requirement for 'setup-envtest.sh' in the test target.
# Options are set to exit when a recipe line exits non-zero or a piped command fails.
SHELL = /usr/bin/env bash -o pipefail
.SHELLFLAGS = -ec

##@ General

# The help target prints out all targets with their descriptions organized
# beneath their categories. The categories are represented by '##@' and the
# target descriptions by '##'. The awk commands is responsible for reading the
# entire set of makefiles included in this invocation, looking for lines of the
# file as xyz: ## something, and then pretty-format the target and help. Then,
# if there's a line with ##@ something, that gets pretty-printed as a category.
# More info on the usage of ANSI control characters for terminal formatting:
# https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters
# More info on the awk command:
# http://linuxcommand.org/lc3_adv_awk.php

.PHONY: help
help: ## Display this help.
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)

.PHONY: checkall
checkall: fmt-check vet ## Do all check
hack/verify-staticcheck.sh
hack/verify-import-aliases.sh

.PHONY: kinitiras-webhook
kinitiras-webhook: $(SOURCES) ## Build kinitiras webhook binary file
@CGO_ENABLED=0 GOOS=$(GOOS) go build \
-ldflags $(LDFLAGS) \
-o kinitiras-webhook \
main.go

.PHONY: clean
clean: ## Clean kinitiras webhook binary file
@rm -rf kinitiras-webhook

.PHONY: fmt
fmt: ## Format project files
@$(GOFMT) -w $(GOFILES)

.PHONY: fmt-check
fmt-check: ## Check project files format info
@diff=$$($(GOFMT) -d $(GOFILES)); \
if [ -n "$$diff" ]; then \
echo "Please run 'make fmt' and commit the result:"; \
echo "$${diff}"; \
exit 1; \
fi;

.PHONY: vet
vet:
@$(GO) vet $(VETPACKAGES)

.PHONY: test
test: fmt-check vet ## Run project unit test and generate coverage result
echo "mode: count" > coverage.out
for d in $(TESTFOLDER); do \
$(GO) test -tags $(TESTTAGS) -v -covermode=count -coverprofile=profile.out $$d > tmp.out; \
cat tmp.out; \
if grep -q "^--- FAIL" tmp.out; then \
rm tmp.out; \
exit 1; \
elif grep -q "build failed" tmp.out; then \
rm tmp.out; \
exit 1; \
elif grep -q "setup failed" tmp.out; then \
rm tmp.out; \
exit 1; \
fi; \
if [ -f profile.out ]; then \
cat profile.out | grep -v "mode:" >> coverage.out; \
rm profile.out; \
fi; \
done

.PHONY: images
images: image-kinitiras-webhook ## Build all images

.PHONY: image-kinitiras-webhook
image-kinitiras-webhook: ## Build webhook image
VERSION=$(VERSION) REGISTRY=$(REGISTRY) hack/docker.sh webhook


42 changes: 41 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,41 @@
# kinitiras
# kinitiras
![pidalio-logo](docs/images/pidolio.png)

[![Build Status](https://github.com/k-cloud-labs/kinitiras/actions/workflows/ci.yml/badge.svg)](https://github.com/k-cloud-labs/kinitiras/actions?query=workflow%3Abuild)
[![codecov](https://codecov.io/gh/k-cloud-labs/kinitiras/branch/main/graph/badge.svg?token=74uYpOiawR)](https://codecov.io/gh/k-cloud-labs/kinitiras)
[![Go Report Card](https://goreportcard.com/badge/github.com/k-cloud-labs/kinitiras)](https://goreportcard.com/report/github.com/k-cloud-labs/kinitiras)
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/k-cloud-labs/kinitiras)

A transport middleware working in clientside for client-go to mutate any k8s resource via (Cluster)OverridePolicy.

If you want to use it in serverside as a webhook, please use https://github.com/k-cloud-labs/kinitiras.


## Quick Start

### Apply crd files to your cluster
```shell
kubectl apply -f https://raw.githubusercontent.com/k-cloud-labs/pkg/main/charts/_crds/bases/policy.kcloudlabs.io_overridepolicies.yaml
kubectl apply -f https://raw.githubusercontent.com/k-cloud-labs/pkg/main/charts/_crds/bases/policy.kcloudlabs.io_clusteroverridepolicies.yaml
```

OverridePolicy is used to mutate object in the same namespace.
ClusterOverridePolicy can mutate object in any namespace.

For cluster scoped resource:
- Apply ClusterOverridePolicy by policies name in ascending;

For namespaced scoped resource, apply order is:
- First apply ClusterOverridePolicy;
- Then apply OverridePolicy;

### Add transport middleware
What you need to do is just call `Wrap` func after `rest.Config` initialized and before client to initialize.

```go
config.Wrap(pidalio.NewPolicyTransport(config, stopCh).Wrap)
```

## Feature
- [x] Support mutate k8s resource by (Cluster)OverridePolicy via plaintext jsonpatch.
- [x] Support mutate k8s resource by (Cluster)OverridePolicy programmable via cue.
70 changes: 70 additions & 0 deletions cmd/app/options/options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package options

import (
"github.com/spf13/pflag"
"k8s.io/component-base/cli/globalflag"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/metrics"
)

const (
defaultBindAddress = "0.0.0.0"
defaultPort = 8443
defaultCertDir = "/tmp/k8s-webhook-server/serving-certs"
defaultTLSMinVersion = "1.3"
)

// Options contains everything necessary to create and run webhook server.
type Options struct {
// BindAddress is the IP address on which to listen for the --secure-port port.
// Default is "0.0.0.0".
BindAddress string
// SecurePort is the port that the webhook server serves at.
// Default is 8443.
SecurePort int
// MetricsBindAddress is the IP:Port address on which to listen for the webhook metrics.
// Default is ":8080".
MetricsBindAddress string
// CertDir is the directory that contains the server key and certificate.
// if not set, webhook server would look up the server key and certificate in {TempDir}/k8s-webhook-server/serving-certs.
// The server key and certificate must be named `tls.key` and `tls.crt`, respectively.
CertDir string
// TLSMinVersion is the minimum version of TLS supported. Possible values: 1.0, 1.1, 1.2, 1.3.
// Some environments have automated security scans that trigger on TLS versions or insecure cipher suites, and
// setting TLS to 1.3 would solve both problems.
// Defaults to 1.3.
TLSMinVersion string
// KubeAPIQPS is the QPS to use while talking with kube-apiserver.
KubeAPIQPS float32
// KubeAPIBurst is the burst to allow while talking with kube-apiserver.
KubeAPIBurst int
}

// NewOptions builds an empty options.
func NewOptions() *Options {
return &Options{}
}

// AddFlags adds flags to the specified FlagSet.
func (o *Options) AddFlags(flags *pflag.FlagSet) {
flags.StringVar(&o.BindAddress, "bind-address", defaultBindAddress,
"The IP address on which to listen for the --secure-port port.")
flags.IntVar(&o.SecurePort, "secure-port", defaultPort,
"The secure port on which to serve HTTPS.")
flags.StringVar(&o.MetricsBindAddress, "metrics-bind-address", metrics.DefaultBindAddress,
"The Metrics bind address on which to listen for the webhook metrics.")
flags.StringVar(&o.CertDir, "cert-dir", defaultCertDir,
"The directory that contains the server key(named tls.key) and certificate(named tls.crt).")
flags.StringVar(&o.TLSMinVersion, "tls-min-version", defaultTLSMinVersion, "Minimum TLS version supported. Possible values: 1.0, 1.1, 1.2, 1.3.")
flags.Float32Var(&o.KubeAPIQPS, "kube-api-qps", 40.0, "QPS to use while talking with kube-apiserver. Doesn't cover events and node heartbeat apis which rate limiting is controlled by a different set of flags.")
flags.IntVar(&o.KubeAPIBurst, "kube-api-burst", 60, "Burst to use while talking with kube-apiserver. Doesn't cover events and node heartbeat apis which rate limiting is controlled by a different set of flags.")

globalflag.AddGlobalFlags(flags, "global")
}

// PrintFlags logs the flags in the flagset
func PrintFlags(flags *pflag.FlagSet) {
flags.VisitAll(func(flag *pflag.Flag) {
klog.Infof("FLAG: --%s=%q", flag.Name, flag.Value)
})
}
23 changes: 23 additions & 0 deletions cmd/app/options/validation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package options

import (
"net"

"k8s.io/apimachinery/pkg/util/validation/field"
)

// Validate checks Options and return a slice of found errs.
func (o *Options) Validate() field.ErrorList {
errs := field.ErrorList{}

newPath := field.NewPath("Options")
if net.ParseIP(o.BindAddress) == nil {
errs = append(errs, field.Invalid(newPath.Child("BindAddress"), o.BindAddress, "not a valid textual representation of an IP address"))
}

if o.SecurePort < 0 || o.SecurePort > 65535 {
errs = append(errs, field.Invalid(newPath.Child("SecurePort"), o.SecurePort, "must be a valid port between 0 and 65535 inclusive"))
}

return errs
}
Loading

0 comments on commit f298e37

Please sign in to comment.