Skip to content

Commit

Permalink
Merge pull request #16 from mhrabovcin/classes-rewrite
Browse files Browse the repository at this point in the history
fix: rewrite priority class and ingress class
  • Loading branch information
mhrabovcin authored May 16, 2023
2 parents a08d1a1 + 173120d commit cf9f716
Show file tree
Hide file tree
Showing 11 changed files with 297 additions and 2 deletions.
6 changes: 5 additions & 1 deletion .github/workflows/checks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
uses: actions/checkout@v3

- name: Install asdf
uses: asdf-vm/actions/setup@v2.1.0
uses: asdf-vm/actions/install@v2.1.0
with:
asdf_branch: v0.11.2

Expand All @@ -36,6 +36,10 @@ jobs:

- name: Run unit tests
run: make test
env:
# This env variable is set automatically by endorama/asdf-parse-tool-versions
# and mockery is picking it up.
MOCKERY_VERSION: ""

- name: Annotate tests
if: always()
Expand Down
5 changes: 5 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,8 @@ issues:
include:
- EXC0012
- EXC0014
exclude-rules:
# Exclude some linters from running on tests files.
- path: _test\.go
linters:
- gochecknoglobals
1 change: 1 addition & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ golang 1.20.2
golangci-lint 1.51.2
pre-commit 3.1.1
goreleaser 1.16.1
mockery 2.27.1
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ export DOCKER_REGISTRY ?= ghcr.io
export DOCKERHUB_ORG ?= mhrabovcin
export GIT_TREE_STATE ?=

.PHONY: gogenerate
gogenerate:
go generate ./...

.PHONY: test
test: tools.gotestsum
test: tools.gotestsum gogenerate
gotestsum --format pkgname --junitfile unit-tests.xml --jsonfile test.json -- -coverprofile=cover.out ./... && \
go tool cover -func=cover.out

Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stretchr/objx v0.5.0 // indirect
github.com/ulikunitz/xz v0.5.9 // indirect
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
golang.org/x/net v0.7.0 // indirect
Expand Down
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
Expand Down
55 changes: 55 additions & 0 deletions pkg/rewriter/conditional.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package rewriter

import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
)

type conditionalRewriter struct {
rewriter ResourceRewriter
condition Condition
}

var _ ResourceRewriter = (*conditionalRewriter)(nil)

// When executes provided rewriter only if condition matches.
func When(condition Condition, rewriter ResourceRewriter) ResourceRewriter {
return &conditionalRewriter{
rewriter: rewriter,
condition: condition,
}
}

func (r *conditionalRewriter) BeforeImport(u *unstructured.Unstructured) error {
if r.condition(u) {
return r.rewriter.BeforeImport(u)
}
return nil
}

func (r *conditionalRewriter) BeforeServing(u *unstructured.Unstructured) error {
if r.condition(u) {
return r.rewriter.BeforeServing(u)
}
return nil
}

// Condition is function that returns bool with condition match result.
type Condition func(*unstructured.Unstructured) bool

// MatchGVK checks if resource matches given GroupVersionKind.
func MatchGVK(gvk schema.GroupVersionKind) Condition {
return func(u *unstructured.Unstructured) bool {
apiVersion, kind := gvk.ToAPIVersionAndKind()

if u.GetAPIVersion() != apiVersion {
return false
}

if u.GetKind() != kind {
return false
}

return true
}
}
80 changes: 80 additions & 0 deletions pkg/rewriter/conditional_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package rewriter_test

import (
"fmt"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"

"github.com/mhrabovcin/troubleshoot-live/pkg/rewriter"
"github.com/mhrabovcin/troubleshoot-live/pkg/rewriter/mocks"
)

var (
anyUnstructured = mock.MatchedBy(func(_ *unstructured.Unstructured) bool { return true })
matchAny = func(u *unstructured.Unstructured) bool { return true }
matchNone = func(u *unstructured.Unstructured) bool { return false }
)

func TestWhen_Matching(t *testing.T) {
rrMock := mocks.NewResourceRewriter(t)
rrMock.EXPECT().BeforeImport(anyUnstructured).Return(nil).Once()
rrMock.EXPECT().BeforeServing(anyUnstructured).Return(nil).Once()
assert.NoError(t, rewriter.When(matchAny, rrMock).BeforeImport(&unstructured.Unstructured{}))
assert.NoError(t, rewriter.When(matchAny, rrMock).BeforeServing(&unstructured.Unstructured{}))
}

func TestWhen_Matching_Error(t *testing.T) {
rrMock := mocks.NewResourceRewriter(t)
rrMock.EXPECT().BeforeImport(anyUnstructured).Return(fmt.Errorf("test")).Once()
rrMock.EXPECT().BeforeServing(anyUnstructured).Return(fmt.Errorf("serving")).Once()
assert.ErrorContains(t, rewriter.When(matchAny, rrMock).BeforeImport(&unstructured.Unstructured{}), "test")
assert.ErrorContains(t, rewriter.When(matchAny, rrMock).BeforeServing(&unstructured.Unstructured{}), "serving")
}

func TestWhen_NoMatch(t *testing.T) {
rrMock := mocks.NewResourceRewriter(t)
assert.NoError(t, rewriter.When(matchNone, rrMock).BeforeImport(&unstructured.Unstructured{}))
assert.NoError(t, rewriter.When(matchNone, rrMock).BeforeServing(&unstructured.Unstructured{}))
}

func TestCondition_MatchGVK(t *testing.T) {
testCases := []struct {
config schema.GroupVersionKind
apiVersion string
kind string
expected bool
}{
{
config: schema.FromAPIVersionAndKind("v1", "Pod"),
apiVersion: "v1",
kind: "Pod",
expected: true,
},
{
config: schema.FromAPIVersionAndKind("scheduling.k8s.io/v1beta1", "PriorityClass"),
apiVersion: "scheduling.k8s.io/v1",
kind: "PriorityClass",
expected: false,
},
{
config: schema.FromAPIVersionAndKind("scheduling.k8s.io/v1", "PriorityClass"),
apiVersion: "scheduling.k8s.io/v1",
kind: "PriorityClassDifferent",
expected: false,
},
}

for _, tc := range testCases {
t.Run(fmt.Sprintf("%s:%s/%s", tc.config, tc.apiVersion, tc.kind), func(tt *testing.T) {
condition := rewriter.MatchGVK(tc.config)
u := &unstructured.Unstructured{}
u.SetAPIVersion(tc.apiVersion)
u.SetKind(tc.kind)
assert.Equal(tt, tc.expected, condition(u))
})
}
}
21 changes: 21 additions & 0 deletions pkg/rewriter/default.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,31 @@
package rewriter

import (
"k8s.io/apimachinery/pkg/runtime/schema"
)

// Default provides a rewriter that covers most cases of required changes for
// successful import and serving of a diagnostics bundle.
func Default() ResourceRewriter {
return Multi(
GeneratedValues(),
DeletedNamespace(),
When(
MatchGVK(schema.FromAPIVersionAndKind("v1", "Pod")),
Multi(
RemoveField("spec", "priority"),
RemoveField("spec", "priorityClassName"),
),
),
When(
MatchGVK(schema.FromAPIVersionAndKind("v1", "Pod")),
Multi(
RemoveField("spec", "runtimeClassName"),
),
),
When(
MatchGVK(schema.FromAPIVersionAndKind("networking.k8s.io/v1", "Ingress")),
RemoveField("spec", "ingressClassName"),
),
)
}
121 changes: 121 additions & 0 deletions pkg/rewriter/mocks/ResourceRewriter.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions pkg/rewriter/rewriter.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ func annotationForField(fieldPath ...string) string {
return annotationForOriginalValue(strings.Join(fieldPath, "."))
}

//go:generate mockery --name ResourceRewriter --with-expecter

// ResourceRewriter prepares object for saving on import and rewrites the object
// before its returned back from proxy server.
type ResourceRewriter interface {
Expand Down

0 comments on commit cf9f716

Please sign in to comment.