Skip to content

Commit

Permalink
feat: first release (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
azrod authored Feb 14, 2024
1 parent fe60934 commit 800d109
Show file tree
Hide file tree
Showing 9 changed files with 254 additions and 17 deletions.
3 changes: 3 additions & 0 deletions .changelog/1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:feature
`core` - First release of k8-env
```
116 changes: 116 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# Visit https://golangci-lint.run/ for usage documentation
# and information on other useful linters
issues:
max-same-issues: 0

linters:
enable:
- asciicheck # Simple linter to check that your code does not contain non-ASCII identifiers [fast: true, auto-fix: false]
- bidichk # Checks for dangerous unicode character sequences [fast: true, auto-fix: false]
- decorder # check declaration order and count of types, constants, variables and functions [fast: true, auto-fix: false]
- dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) [fast: true, auto-fix: false]
- durationcheck # check for two durations multiplied together [fast: false, auto-fix: false]
- errcheck # Errcheck is a program for checking for unchecked errors in go programs. These unchecked errors can be critical bugs in some cases [fast: false, auto-fix: false]
- errchkjson # Checks types passed to the json encoding functions. Reports unsupported types and optionally reports occasions, where the check for the returned error can be omitted. [fast: false, auto-fix: false]
- errname # Checks that sentinel errors are prefixed with the `Err` and error types are suffixed with the `Error`. [fast: false, auto-fix: false]
- execinquery # execinquery is a linter about query string checker in Query function which reads your Go src files and warning it finds [fast: false, auto-fix: false]
- exportloopref # checks for pointers to enclosing loop variables [fast: false, auto-fix: false]
- forbidigo # Forbids identifiers [fast: true, auto-fix: false]
- gci # Gci controls golang package import order and makes it always deterministic. [fast: true, auto-fix: false]
- gocritic # Provides diagnostics that check for bugs, performance and style issues. [fast: false, auto-fix: false]
- gocyclo # Computes and checks the cyclomatic complexity of functions [fast: true, auto-fix: false]
- gofmt # Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification [fast: true, auto-fix: true]
- goheader # Checks is file header matches to pattern [fast: true, auto-fix: false]
- gofumpt # Gofumpt checks whether code was gofumpt-ed. [fast: true, auto-fix: true]
- gomoddirectives # Manage the use of 'replace', 'retract', and 'excludes' directives in go.mod. [fast: true, auto-fix: false]
- gomodguard # Allow and block list linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations. [fast: true, auto-fix: false]
- goprintffuncname # Checks that printf-like functions are named with `f` at the end [fast: true, auto-fix: false]
- gosec #(gas): Inspects source code for security problems [fast: false, auto-fix: false]
- gosimple #(megacheck): Linter for Go source code that specializes in simplifying a code [fast: false, auto-fix: false]
- govet #(vet, vetshadow): Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string [fast: false, auto-fix: false]
- grouper # An analyzer to analyze expression groups. [fast: true, auto-fix: false]
- ifshort # Checks that your code uses short syntax for if-statements whenever possible [fast: true, auto-fix: false]
- importas # Enforces consistent import aliases [fast: false, auto-fix: false]
- ineffassign # Detects when assignments to existing variables are not used [fast: true, auto-fix: false]
- makezero # Finds slice declarations with non-zero initial length [fast: false, auto-fix: false]
- misspell # Finds commonly misspelled English words in comments [fast: true, auto-fix: true]
- nilerr # Finds the code that returns nil even if it checks that the error is not nil. [fast: false, auto-fix: false]
- noctx # noctx finds sending http request without context.Context [fast: false, auto-fix: false]
- nolintlint # Reports ill-formed or insufficient nolint directives [fast: true, auto-fix: false]
- nosprintfhostport # Checks for misuse of Sprintf to construct a host with port in a URL. [fast: true, auto-fix: false]
- predeclared # find code that shadows one of Go's predeclared identifiers [fast: true, auto-fix: false]
- promlinter # Check Prometheus metrics naming via promlint [fast: true, auto-fix: false]
- revive # Fast, configurable, extensible, flexible, and beautiful linter for Go. Drop-in replacement of golint. [fast: false, auto-fix: false]
- rowserrcheck # checks whether Err of rows is checked successfully [fast: false, auto-fix: false]
- sqlclosecheck # Checks that sql.Rows and sql.Stmt are closed. [fast: false, auto-fix: false]
- stylecheck # Stylecheck is a replacement for golint [fast: false, auto-fix: false]
- tagliatelle # Checks the struct tags. [fast: true, auto-fix: false]
- tenv # tenv is analyzer that detects using os.Setenv instead of t.Setenv since Go1.17 [fast: false, auto-fix: false]
- tparallel # tparallel detects inappropriate usage of t.Parallel() method in your Go test codes [fast: false, auto-fix: false]
- typecheck # Like the front-end of a Go compiler, parses and type-checks Go code [fast: false, auto-fix: false]
- unconvert # Remove unnecessary type conversions [fast: false, auto-fix: false]
- wastedassign # wastedassign finds wasted assignment statements. [fast: false, auto-fix: false]
- whitespace # Tool for detection of leading and trailing whitespace [fast: true, auto-fix: true]
- errorlint # errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13. [fast: false, auto-fix: false]
- nilnil # Checks that there is no simultaneous return of `nil` error and an invalid value. [fast: false, auto-fix: false]
- godot # Check if comments end in a period [fast: true, auto-fix: true]
- unused #(megacheck): Checks Go code for unused constants, variables, functions and types [fast: false, auto-fix: false]
- unparam # reports unused function parameters
- staticcheck #(megacheck): Staticcheck is a go vet on steroids, applying a ton of static analysis checks [fast: false, auto-fix: false]
- bodyclose # checks whether HTTP response body is closed successfully
- goconst # Finds repeated strings that could be replaced by a constant [fast: true, auto-fix: false]

disable:
- dupl # Tool for code clone detection [fast: true, auto-fix: false]
- varcheck # Finds unused global variables and constants [fast: false, auto-fix: false]
- deadcode # Finds unused code [fast: false, auto-fix: false]
- structcheck # Finds unused struct fields [fast: false, auto-fix: false]
- nakedret # Finds naked returns in functions greater than a specified function length [fast: true, auto-fix: false]
- depguard # Go linter that checks if package imports are in a list of acceptable packages [fast: true, auto-fix: false]
- goimports # In addition to fixing imports, goimports also formats your code in the same style as gofmt. [fast: true, auto-fix: true]
- containedctx # containedctx is a linter that detects struct contained context.Context field [fast: true, auto-fix: false]
- thelper # thelper detects golang test helpers without t.Helper() call and checks the consistency of test helpers [fast: false, auto-fix: false]
- cyclop # checks function and package cyclomatic complexity [fast: false, auto-fix: false]
- exhaustive # check exhaustiveness of enum switch statements [fast: false, auto-fix: false]
- funlen # Tool for detection of long functions [fast: true, auto-fix: false]
- gochecknoglobals # check that no global variables exist [fast: true, auto-fix: false]
- gochecknoinits # Checks that no init functions are present in Go code [fast: true, auto-fix: false]
- gocognit # Computes and checks the cognitive complexity of functions [fast: true, auto-fix: false]
- godox # Tool for detection of FIXME, TODO and other comment keywords [fast: true, auto-fix: false]
- goerr113 # Golang linter to check the errors handling expressions [fast: false, auto-fix: false]
- gomnd # An analyzer to detect magic numbers. [fast: true, auto-fix: false]
- lll # Reports long lines [fast: true, auto-fix: false]
- maintidx # maintidx measures the maintainability index of each function. [fast: true, auto-fix: false]
- nestif # Reports deeply nested if statements [fast: true, auto-fix: false]
- nlreturn # nlreturn checks for a new line before return and branch statements to increase code clarity [fast: true, auto-fix: false]
- varnamelen # checks that the length of a variable's name matches its scope [fast: false, auto-fix: false]
- wrapcheck # Checks that errors returned from external packages are wrapped [fast: false, auto-fix: false]
- wsl # Whitespace Linter - Forces you to use empty lines! [fast: true, auto-fix: false]

linters-settings:
goimports:
local-prefixes: github.com/orange-cloudavenue/k8-env

gci:
# Section configuration to compare against.
# Section names are case-insensitive and may contain parameters in ().
# The default order of sections is `standard > default > custom > blank > dot`,
# If `custom-order` is `true`, it follows the order of `sections` option.
# Default: ["standard", "default"]
sections:
- standard # Standard section: captures all standard packages.
- default # Default section: contains all imports that could not be matched to another section type.
- prefix(github.com/orange-cloudavenue/k8-env)
- blank # Blank section: contains all blank imports. This section is not present unless explicitly enabled.
- dot # Dot section: contains all dot imports. This section is not present unless explicitly enabled.
skip-generated: true
custom-order: true

gofumpt:
# Module path which contains the source code being formatted.
# Default: ""
module-path: github.com/orange-cloudavenue/k8-env
# Choose whether to use the extra rules.
# Default: false
extra-rules: true

51 changes: 51 additions & 0 deletions .vscode/changelog.code-snippets
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"Release Note Breaking change": {
"scope": "plaintext",
"prefix": "release-note-breaking-change",
"body": [
"```release-note:breaking-change",
"`xx` - Short Description.",
"```"
]
},
// Release note feature
"Release Note New Feature": {
"scope": "plaintext",
"prefix": "release-note-feature",
"body": [
"```release-note:feature",
"`xx` - Short Description.",
"```"
]
},
// Release note bug
"Release Note Bug": {
"scope": "plaintext",
"prefix": "release-note-bug",
"body": [
"```release-note:bug",
"`xx` - Short Description.",
"```"
]
},
// Release note Note
"Release Note Note": {
"scope": "plaintext",
"prefix": "release-note-note",
"body": [
"```release-note:note",
"`xx` - Short Description.",
"```"
]
},
// Release note enchancement
"Release Note Enhancement": {
"scope": "plaintext",
"prefix": "release-note-enhancement",
"body": [
"```release-note:enhancement",
"`xx` - Short Description.",
"```"
]
},
}
12 changes: 12 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"gopls": {
"ui.semanticTokens": true,
"formatting.local": "github.com/azrod/golink",
},
"go.lintTool": "golangci-lint",
"go.lintFlags": [
"--fast",
"--fix"
],
"go.lintOnSave": "package"
}
57 changes: 53 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,62 @@

A Kubernetes mutating webhook server that implements environnement variable injection.

## How to use

### Prerequisites
## Prerequisites

- A Kubernetes cluster with the `admissionregistration.k8s.io/v1beta1` API enabled.
A Kubernetes cluster (v1.19+) with the `admissionregistration.k8s.io/v1beta1` API enabled.
Verify that by the following command :

```bash
kubectl api-versions | grep admissionregistration.k8s.io
```

## How to use

### 1. Create a `namespace`

Create a `namespace` with the label `env-injection: true` :

```yaml
apiVersion: v1
kind: Namespace
metadata:
name: my-namespace
labels:
env-injection: true
```
### 2. Create kustomization configuration
Change the `namespace` or create a `k8-env` namespace and create a `kustomization.yaml` file :

```bash
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: k8-env
resources:
- https://raw.githubusercontent.com/orange-cloudavenue/k8-env/v0.1.0/manifests/manifests.yaml
images:
- name: k8-env
newName: ghcr.io/orange-cloudavenue/k8-env
newTag: v0.1.0
configMapGenerator:
- name: k8-env
behavior: replace
files:
- envconfig.yaml
```

### 3. Create a `envconfig.yaml` file

Create a `envconfig.yaml` with the environment variables to inject :

```yaml
env:
- name: ENV_VAR_1
value: "value1"
- name: ENV_VAR_2
value: "value2"
```
2 changes: 1 addition & 1 deletion cmd/cert.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (

// generateCert generate a self-signed CA for given organization
// and sign certificate with the CA for given common name and dns names
// it resurns the CA, certificate and private key in PEM format
// it resurns the CA, certificate and private key in PEM format.
func generateCert(orgs, dnsNames []string, commonName string) (*bytes.Buffer, *bytes.Buffer, *bytes.Buffer, error) {
// init CA config
ca := &x509.Certificate{
Expand Down
9 changes: 7 additions & 2 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"os"
"os/signal"
"syscall"
"time"
)

var (
Expand Down Expand Up @@ -72,8 +73,12 @@ func main() {
whsvr := &WebhookServer{
envConfig: envConfig,
server: &http.Server{
Addr: fmt.Sprintf(":%v", port),
TLSConfig: &tls.Config{Certificates: []tls.Certificate{pair}},
ReadHeaderTimeout: 5 * time.Second,
Addr: fmt.Sprintf(":%v", port),
TLSConfig: &tls.Config{
Certificates: []tls.Certificate{pair},
MinVersion: tls.VersionTLS12,
},
},
}

Expand Down
14 changes: 7 additions & 7 deletions cmd/webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func loadConfig(configFile string) (*Config, error) {
return &cfg, nil
}

// Check whether the target resoured need to be mutated
// Check whether the target resoured need to be mutated.
func mutationRequired(ignoredList []string, metadata *metav1.ObjectMeta) bool {
// skip special kubernete system namespaces
for _, namespace := range ignoredList {
Expand Down Expand Up @@ -99,7 +99,7 @@ func mutationRequired(ignoredList []string, metadata *metav1.ObjectMeta) bool {
return required
}

// addEnvironnement add environnement to the target container
// addEnvironnement add environnement to the target container.
func addEnvironnement(containers []corev1.Container, added []corev1.EnvVar, basePath string) (patch []patchOperation) {
// for each containers in the pod spec, append the env vars
for i := range containers {
Expand All @@ -120,7 +120,7 @@ func addEnvironnement(containers []corev1.Container, added []corev1.EnvVar, base
return patch
}

func updateAnnotation(target map[string]string, added map[string]string) (patch []patchOperation) {
func updateAnnotation(target, added map[string]string) (patch []patchOperation) {
for key, value := range added {
if target == nil || target[key] == "" {
target = map[string]string{}
Expand All @@ -142,7 +142,7 @@ func updateAnnotation(target map[string]string, added map[string]string) (patch
return patch
}

// create mutation patch for resoures
// create mutation patch for resoures.
func createPatch(pod *corev1.Pod, config *Config, annotations map[string]string) ([]byte, error) {
var patch []patchOperation

Expand All @@ -152,7 +152,7 @@ func createPatch(pod *corev1.Pod, config *Config, annotations map[string]string)
return json.Marshal(patch)
}

// main mutation process
// main mutation process.
func (whsvr *WebhookServer) mutate(ar *admissionv1.AdmissionReview) *admissionv1.AdmissionResponse {
req := ar.Request
var pod corev1.Pod
Expand Down Expand Up @@ -197,7 +197,7 @@ func (whsvr *WebhookServer) mutate(ar *admissionv1.AdmissionReview) *admissionv1
}
}

// Serve method for webhook server
// Serve method for webhook server.
func (whsvr *WebhookServer) serve(w http.ResponseWriter, r *http.Request) {
var body []byte
if r.Body != nil {
Expand Down Expand Up @@ -250,7 +250,7 @@ func (whsvr *WebhookServer) serve(w http.ResponseWriter, r *http.Request) {
warningLogger.Printf("Can't encode response: %v", err)
http.Error(w, fmt.Sprintf("could not encode response: %v", err), http.StatusInternalServerError)
}
infoLogger.Printf("Ready to write reponse ...")
infoLogger.Printf("Ready to write response ...")
if _, err := w.Write(resp); err != nil {
warningLogger.Printf("Can't write response: %v", err)
http.Error(w, fmt.Sprintf("could not write response: %v", err), http.StatusInternalServerError)
Expand Down
7 changes: 4 additions & 3 deletions cmd/webhookconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,16 +74,17 @@ func createOrUpdateMutatingWebhookConfiguration(caPEM *bytes.Buffer, webhookServ
}

foundWebhookConfig, err := mutatingWebhookConfigV1Client.MutatingWebhookConfigurations().Get(context.TODO(), webhookConfigName, metav1.GetOptions{})
if err != nil && apierrors.IsNotFound(err) {
switch {
case err != nil && apierrors.IsNotFound(err):
if _, err := mutatingWebhookConfigV1Client.MutatingWebhookConfigurations().Create(context.TODO(), mutatingWebhookConfig, metav1.CreateOptions{}); err != nil {
warningLogger.Printf("Failed to create the mutatingwebhookconfiguration: %s", webhookConfigName)
return err
}
infoLogger.Printf("Created mutatingwebhookconfiguration: %s", webhookConfigName)
} else if err != nil {
case err != nil:
warningLogger.Printf("Failed to check the mutatingwebhookconfiguration: %s", webhookConfigName)
return err
} else {
default:
// there is an existing mutatingWebhookConfiguration
if len(foundWebhookConfig.Webhooks) != len(mutatingWebhookConfig.Webhooks) ||
!(foundWebhookConfig.Webhooks[0].Name == mutatingWebhookConfig.Webhooks[0].Name &&
Expand Down

0 comments on commit 800d109

Please sign in to comment.