Skip to content

Commit 7082274

Browse files
Eric Stroczynskiperdasilva
authored andcommitted
fix(validators): check object GVK in bundle service account validator (openshift#161)
Signed-off-by: Eric Stroczynski <[email protected]> Upstream-repository: api Upstream-commit: cdabf11822cbff3914e444ab6e30b8145a0a9b6a
1 parent c559a28 commit 7082274

File tree

3 files changed

+136
-8
lines changed

3 files changed

+136
-8
lines changed

staging/api/pkg/validation/internal/bundle.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ func validateServiceAccounts(bundle *manifests.Bundle) []errors.Error {
4646
// find any hardcoded service account objects are in the bundle, then check if they match any sa definition in the csv
4747
var errs []errors.Error
4848
for _, obj := range bundle.Objects {
49+
if obj.GroupVersionKind() != v1.SchemeGroupVersion.WithKind("ServiceAccount") {
50+
continue
51+
}
4952
sa := v1.ServiceAccount{}
5053
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &sa); err == nil {
5154
if _, ok := saNamesFromCSV[sa.Name]; ok {

staging/api/pkg/validation/internal/bundle_test.go

Lines changed: 102 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import (
44
"testing"
55

66
"github.com/operator-framework/api/pkg/manifests"
7+
"github.com/operator-framework/api/pkg/operators/v1alpha1"
8+
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
79

810
"github.com/stretchr/testify/require"
911
)
@@ -47,22 +49,114 @@ func TestValidateBundle(t *testing.T) {
4749
description: "invalid bundle service account can't match sa in csv",
4850
directory: "./testdata/invalid_bundle_sa",
4951
hasError: true,
50-
errString: `Error: Value etcd-operator: invalid service account found in bundle. sa name cannot match service account defined for deployment spec in CSV`,
52+
errString: `invalid service account found in bundle. sa name cannot match service account defined for deployment spec in CSV`,
5153
},
5254
}
5355

5456
for _, tt := range table {
55-
// Validate the bundle object
56-
bundle, err := manifests.GetBundleFromDir(tt.directory)
57-
require.NoError(t, err)
57+
t.Run(tt.description, func(t *testing.T) {
58+
// Validate the bundle object
59+
bundle, err := manifests.GetBundleFromDir(tt.directory)
60+
require.NoError(t, err)
5861

59-
results := BundleValidator.Validate(bundle)
62+
results := BundleValidator.Validate(bundle)
6063

61-
if len(results) > 0 {
62-
require.Equal(t, results[0].HasError(), tt.hasError)
63-
if results[0].HasError() {
64+
require.Greater(t, len(results), 0)
65+
if tt.hasError {
66+
require.True(t, results[0].HasError(), "found no error when an error was expected")
6467
require.Contains(t, results[0].Errors[0].Error(), tt.errString)
68+
} else {
69+
require.False(t, results[0].HasError(), "found error when an error was not expected")
6570
}
71+
})
72+
}
73+
}
74+
75+
func TestValidateServiceAccount(t *testing.T) {
76+
csvWithSAs := func(saNames ...string) *v1alpha1.ClusterServiceVersion {
77+
csv := &v1alpha1.ClusterServiceVersion{}
78+
depSpecs := make([]v1alpha1.StrategyDeploymentSpec, len(saNames))
79+
for i, saName := range saNames {
80+
depSpecs[i].Spec.Template.Spec.ServiceAccountName = saName
6681
}
82+
csv.Spec.InstallStrategy.StrategySpec.DeploymentSpecs = depSpecs
83+
return csv
84+
}
85+
86+
var table = []struct {
87+
description string
88+
bundle *manifests.Bundle
89+
hasError bool
90+
errString string
91+
}{
92+
{
93+
description: "an object with the same name as the service account",
94+
bundle: &manifests.Bundle{
95+
CSV: csvWithSAs("foo"),
96+
Objects: []*unstructured.Unstructured{
97+
{Object: map[string]interface{}{
98+
"apiVersion": "apps/v1",
99+
"kind": "Deployment",
100+
"metadata": map[string]interface{}{
101+
"name": "foo",
102+
},
103+
"spec": map[string]interface{}{
104+
"template": map[string]interface{}{
105+
"spec": map[string]interface{}{
106+
"serviceAccountName": "foo",
107+
},
108+
},
109+
},
110+
}},
111+
},
112+
},
113+
hasError: false,
114+
},
115+
{
116+
description: "service account included in both CSV and bundle",
117+
bundle: &manifests.Bundle{
118+
CSV: csvWithSAs("foo"),
119+
Objects: []*unstructured.Unstructured{
120+
{Object: map[string]interface{}{
121+
"apiVersion": "apps/v1",
122+
"kind": "Deployment",
123+
"metadata": map[string]interface{}{
124+
"name": "foo",
125+
},
126+
"spec": map[string]interface{}{
127+
"template": map[string]interface{}{
128+
"spec": map[string]interface{}{
129+
"serviceAccountName": "foo",
130+
},
131+
},
132+
},
133+
}},
134+
{Object: map[string]interface{}{
135+
"apiVersion": "v1",
136+
"kind": "ServiceAccount",
137+
"metadata": map[string]interface{}{
138+
"name": "foo",
139+
},
140+
}},
141+
},
142+
},
143+
hasError: true,
144+
errString: `invalid service account found in bundle. sa name cannot match service account defined for deployment spec in CSV`,
145+
},
146+
}
147+
148+
for _, tt := range table {
149+
t.Run(tt.description, func(t *testing.T) {
150+
// Validate the bundle object
151+
results := BundleValidator.Validate(tt.bundle)
152+
153+
require.Greater(t, len(results), 0)
154+
if tt.hasError {
155+
require.True(t, results[0].HasError(), "found no error when an error was expected")
156+
require.Contains(t, results[0].Errors[0].Error(), tt.errString)
157+
} else {
158+
require.False(t, results[0].HasError(), "found error when an error was not expected")
159+
}
160+
})
67161
}
68162
}

vendor/github.com/operator-framework/api/pkg/validation/internal/bundle.go

Lines changed: 31 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)