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

refactor: rename localFilesClient to localSchemasClient and don't consider CRDs #53

Merged
merged 1 commit into from
May 31, 2023
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
2 changes: 1 addition & 1 deletion pkg/cmd/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ func (c *commandFlags) Run(cmd *cobra.Command, args []string) error {
openapiclient.PatchLoaderFromDirectory(nil, c.schemaPatchesDir),
openapiclient.NewComposite(
// consult local OpenAPI
openapiclient.NewLocalFiles(nil, c.localSchemasDir),
openapiclient.NewLocalSchemaFiles(nil, c.localSchemasDir),
// consult local CRDs
openapiclient.NewLocalCRDFiles(nil, c.localCRDsDir),
openapiclient.NewOverlay(
Expand Down
1 change: 0 additions & 1 deletion pkg/openapiclient/github_builtins_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,4 @@ func TestGitHubBuiltins(t *testing.T) {
t.Fatal(err)
}
fmt.Println(m)

}
138 changes: 0 additions & 138 deletions pkg/openapiclient/local_files.go

This file was deleted.

61 changes: 61 additions & 0 deletions pkg/openapiclient/local_schemas.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package openapiclient

import (
"fmt"
"io/fs"
"path/filepath"
"strings"

"k8s.io/client-go/openapi"
"sigs.k8s.io/kubectl-validate/pkg/openapiclient/groupversion"
"sigs.k8s.io/kubectl-validate/pkg/utils"
)

// client which provides openapi read from files on disk
type localSchemasClient struct {
fs fs.FS
dir string
}

// Dir should have openapi files following directory layout:
// /<apis>/<group>/<version>.json
// /api/<version>.json
func NewLocalSchemaFiles(fs fs.FS, dirPath string) openapi.Client {
return &localSchemasClient{
fs: fs,
dir: dirPath,
}
}

func (k *localSchemasClient) Paths() (map[string]openapi.GroupVersion, error) {
if len(k.dir) == 0 {
return nil, nil
}
res := map[string]openapi.GroupVersion{}
apiGroups, _ := utils.ReadDir(k.fs, filepath.Join(k.dir, "apis"))
for _, f := range apiGroups {
groupPath := filepath.Join(k.dir, "apis", f.Name())
versions, err := utils.ReadDir(k.fs, groupPath)
if err != nil {
return nil, fmt.Errorf("failed reading local files dir %s: %w", groupPath, err)
}
for _, v := range versions {
if !utils.IsJson(v.Name()) {
continue
}
name := strings.TrimSuffix(v.Name(), filepath.Ext(v.Name()))
path := filepath.Join("apis", f.Name(), name)
res[path] = groupversion.NewForFile(k.fs, filepath.Join(groupPath, v.Name()))
}
}
coregroup, _ := utils.ReadDir(k.fs, filepath.Join(k.dir, "api"))
for _, v := range coregroup {
if !utils.IsJson(v.Name()) {
continue
}
name := strings.TrimSuffix(v.Name(), filepath.Ext(v.Name()))
path := filepath.Join("api", name)
res[path] = groupversion.NewForFile(k.fs, filepath.Join(k.dir, "api", v.Name()))
}
return res, nil
}
161 changes: 161 additions & 0 deletions pkg/openapiclient/local_schemas_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
package openapiclient

import (
"io/fs"
"os"
"reflect"
"testing"

"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/client-go/openapi"
)

func TestNewLocalSchemaFiles(t *testing.T) {
tests := []struct {
name string
fs fs.FS
dirPath string
want openapi.Client
}{{
name: "fs nil and dir empty",
want: &localSchemasClient{},
}, {
name: "only dir",
dirPath: "test",
want: &localSchemasClient{
dir: "test",
},
}, {
name: "only fs",
fs: os.DirFS("."),
want: &localSchemasClient{
fs: os.DirFS("."),
},
}, {
name: "both fs and dir",
fs: os.DirFS("."),
dirPath: "test",
want: &localSchemasClient{
fs: os.DirFS("."),
dir: "test",
},
}}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := NewLocalSchemaFiles(tt.fs, tt.dirPath); !reflect.DeepEqual(got, tt.want) {
t.Errorf("NewLocalSchemaFiles() = %v, want %v", got, tt.want)
}
})
}
}

func Test_localSchemasClient_Paths(t *testing.T) {
tests := []struct {
name string
fs fs.FS
dir string
want sets.Set[string]
wantErr bool
}{{
name: "fs nil and dir empty",
}, {
name: "only dir",
dir: "./builtins/1.27",
want: sets.New(
"api/v1",
"apis/admissionregistration.k8s.io/v1",
"apis/admissionregistration.k8s.io/v1alpha1",
"apis/apiextensions.k8s.io/v1",
"apis/apps/v1",
"apis/authentication.k8s.io/v1",
"apis/authentication.k8s.io/v1alpha1",
"apis/authentication.k8s.io/v1beta1",
"apis/authorization.k8s.io/v1",
"apis/autoscaling/v1",
"apis/autoscaling/v2",
"apis/batch/v1",
"apis/certificates.k8s.io/v1",
"apis/certificates.k8s.io/v1alpha1",
"apis/coordination.k8s.io/v1",
"apis/discovery.k8s.io/v1",
"apis/events.k8s.io/v1",
"apis/flowcontrol.apiserver.k8s.io/v1beta2",
"apis/flowcontrol.apiserver.k8s.io/v1beta3",
"apis/internal.apiserver.k8s.io/v1alpha1",
"apis/networking.k8s.io/v1",
"apis/networking.k8s.io/v1alpha1",
"apis/node.k8s.io/v1",
"apis/policy/v1",
"apis/rbac.authorization.k8s.io/v1",
"apis/resource.k8s.io/v1alpha2",
"apis/scheduling.k8s.io/v1",
"apis/storage.k8s.io/v1",
),
}, {
name: "only fs",
fs: os.DirFS("./builtins/1.27"),
}, {
name: "both fs and dir",
fs: os.DirFS("./builtins"),
dir: "1.27",
want: sets.New(
"api/v1",
"apis/admissionregistration.k8s.io/v1",
"apis/admissionregistration.k8s.io/v1alpha1",
"apis/apiextensions.k8s.io/v1",
"apis/apps/v1",
"apis/authentication.k8s.io/v1",
"apis/authentication.k8s.io/v1alpha1",
"apis/authentication.k8s.io/v1beta1",
"apis/authorization.k8s.io/v1",
"apis/autoscaling/v1",
"apis/autoscaling/v2",
"apis/batch/v1",
"apis/certificates.k8s.io/v1",
"apis/certificates.k8s.io/v1alpha1",
"apis/coordination.k8s.io/v1",
"apis/discovery.k8s.io/v1",
"apis/events.k8s.io/v1",
"apis/flowcontrol.apiserver.k8s.io/v1beta2",
"apis/flowcontrol.apiserver.k8s.io/v1beta3",
"apis/internal.apiserver.k8s.io/v1alpha1",
"apis/networking.k8s.io/v1",
"apis/networking.k8s.io/v1alpha1",
"apis/node.k8s.io/v1",
"apis/policy/v1",
"apis/rbac.authorization.k8s.io/v1",
"apis/resource.k8s.io/v1alpha2",
"apis/scheduling.k8s.io/v1",
"apis/storage.k8s.io/v1",
),
}, {
name: "invalid dir",
dir: "invalid",
want: sets.New[string](),
}, {
name: "invalid fs",
fs: os.DirFS("../../invalid"),
dir: ".",
want: sets.New[string](),
}}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
k := NewLocalSchemaFiles(tt.fs, tt.dir)
paths, err := k.Paths()
if (err != nil) != tt.wantErr {
t.Errorf("localSchemasClient.Paths() error = %v, wantErr %v", err, tt.wantErr)
return
}
var got sets.Set[string]
if paths != nil {
got = sets.New[string]()
for key := range paths {
got.Insert(key)
}
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("localSchemasClient.Paths() = %v, want %v", got, tt.want)
}
})
}
}