Skip to content

Commit

Permalink
lib/resourceread/rbac: Ensure v1beta1 conversion
Browse files Browse the repository at this point in the history
Protecting us from [1,2]:

  converting (v1beta1.Role) to (v1.Role): unknown conversion

in unit tests.  The manual conversion and wash through JSON seems like
a terrible hack, but I haven't been able to figure out a more elegant
approach yet.  From [3]:

  Promotes the rbac.authorization.k8s.io/v1beta1 API to v1 with no changes

so all we really need is the apiVersion bump.

Also add similar logic for apiregistration, since that's the other
group where we register multiple schema versions.

[1]: kubernetes/kubernetes#90018
[2]: openshift#420 (comment)
[3]: kubernetes/kubernetes#49642
  • Loading branch information
wking committed Jul 30, 2020
1 parent ba32622 commit 6f247d4
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 14 deletions.
12 changes: 8 additions & 4 deletions lib/resourceread/apireg.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import (
)

var (
apiRegScheme = runtime.NewScheme()
apiRegCodecs = serializer.NewCodecFactory(apiRegScheme)
apiRegScheme = runtime.NewScheme()
apiRegCodecs = serializer.NewCodecFactory(apiRegScheme)
apiRegDecoder runtime.Decoder
)

func init() {
Expand All @@ -19,13 +20,16 @@ func init() {
if err := apiregv1.AddToScheme(apiRegScheme); err != nil {
panic(err)
}
apiRegDecoder = apiRegCodecs.UniversalDecoder(apiregv1beta1.SchemeGroupVersion, apiregv1.SchemeGroupVersion)
}

// ReadAPIServiceV1OrDie reads aiservice object from bytes. Panics on error.
func ReadAPIServiceV1OrDie(objBytes []byte) *apiregv1.APIService {
requiredObj, err := runtime.Decode(apiRegCodecs.UniversalDecoder(apiregv1.SchemeGroupVersion), objBytes)
requiredObj, err := runtime.Decode(apiRegDecoder, objBytes)
if err != nil {
panic(err)
}
return requiredObj.(*apiregv1.APIService)
v1 := &apiregv1.APIService{}
apiRegScheme.Convert(requiredObj, v1, 0)
return v1
}
57 changes: 57 additions & 0 deletions lib/resourceread/apireg_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package resourceread

import (
"testing"
)

func TestReadAPIServiceV1OrDie(t *testing.T) {
type args struct {
objBytes []byte
}
tests := []struct {
name string
args args
}{
{
name: "v1beta1",
args: args{
objBytes: []byte(`
apiVersion: apiregistration.k8s.io/v1beta1
kind: APIService
metadata:
namespace: default
name: pod-reader
spec:
group: example
version: v1
`),
},
},
{
name: "v1",
args: args{
objBytes: []byte(`
apiVersion: apiregistration.k8s.io/v1
kind: APIService
metadata:
namespace: default
name: pod-reader
spec:
group: example
version: v1
`),
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
defer func() {
if r := recover(); r != nil {
t.Error(r)
t.Fail()
}
}()
_ = ReadAPIServiceV1OrDie(tt.args.objBytes)
})
}
}
30 changes: 20 additions & 10 deletions lib/resourceread/rbac.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import (
)

var (
rbacScheme = runtime.NewScheme()
rbacCodecs = serializer.NewCodecFactory(rbacScheme)
rbacScheme = runtime.NewScheme()
rbacCodecs = serializer.NewCodecFactory(rbacScheme)
rbacDecoder runtime.Decoder
)

func init() {
Expand All @@ -19,40 +20,49 @@ func init() {
if err := rbacv1beta1.AddToScheme(rbacScheme); err != nil {
panic(err)
}
rbacDecoder = rbacCodecs.UniversalDecoder(rbacv1beta1.SchemeGroupVersion, rbacv1.SchemeGroupVersion)
}

// ReadClusterRoleBindingV1OrDie reads clusterrolebinding object from bytes. Panics on error.
func ReadClusterRoleBindingV1OrDie(objBytes []byte) *rbacv1.ClusterRoleBinding {
requiredObj, err := runtime.Decode(rbacCodecs.UniversalDecoder(rbacv1.SchemeGroupVersion), objBytes)
requiredObj, err := runtime.Decode(rbacDecoder, objBytes)
if err != nil {
panic(err)
}
return requiredObj.(*rbacv1.ClusterRoleBinding)
v1 := &rbacv1.ClusterRoleBinding{}
rbacScheme.Convert(requiredObj, v1, 0)
return v1
}

// ReadClusterRoleV1OrDie reads clusterole object from bytes. Panics on error.
func ReadClusterRoleV1OrDie(objBytes []byte) *rbacv1.ClusterRole {
requiredObj, err := runtime.Decode(rbacCodecs.UniversalDecoder(rbacv1.SchemeGroupVersion), objBytes)
requiredObj, err := runtime.Decode(rbacDecoder, objBytes)
if err != nil {
panic(err)
}
return requiredObj.(*rbacv1.ClusterRole)
v1 := &rbacv1.ClusterRole{}
rbacScheme.Convert(requiredObj, v1, 0)
return v1
}

// ReadRoleBindingV1OrDie reads clusterrolebinding object from bytes. Panics on error.
func ReadRoleBindingV1OrDie(objBytes []byte) *rbacv1.RoleBinding {
requiredObj, err := runtime.Decode(rbacCodecs.UniversalDecoder(rbacv1.SchemeGroupVersion), objBytes)
requiredObj, err := runtime.Decode(rbacDecoder, objBytes)
if err != nil {
panic(err)
}
return requiredObj.(*rbacv1.RoleBinding)
v1 := &rbacv1.RoleBinding{}
rbacScheme.Convert(requiredObj, v1, 0)
return v1
}

// ReadRoleV1OrDie reads clusterole object from bytes. Panics on error.
func ReadRoleV1OrDie(objBytes []byte) *rbacv1.Role {
requiredObj, err := runtime.Decode(rbacCodecs.UniversalDecoder(rbacv1.SchemeGroupVersion), objBytes)
requiredObj, err := runtime.Decode(rbacDecoder, objBytes)
if err != nil {
panic(err)
}
return requiredObj.(*rbacv1.Role)
v1 := &rbacv1.Role{}
rbacScheme.Convert(requiredObj, v1, 0)
return v1
}
59 changes: 59 additions & 0 deletions lib/resourceread/rbac_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package resourceread

import (
"testing"
)

func TestReadRoleOrDie(t *testing.T) {
type args struct {
objBytes []byte
}
tests := []struct {
name string
args args
}{
{
name: "v1beta1",
args: args{
objBytes: []byte(`
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]
`),
},
},
{
name: "v1",
args: args{
objBytes: []byte(`
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]
`),
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
defer func() {
if r := recover(); r != nil {
t.Error(r)
t.Fail()
}
}()
_ = ReadRoleV1OrDie(tt.args.objBytes)
})
}
}

0 comments on commit 6f247d4

Please sign in to comment.