Skip to content

Commit dc5f6de

Browse files
Merge pull request #218 from timflannagan/sync/11-30-and-registry-no-grpc-bump
Sync registry and API upstream commits (without the grpc client bump)
2 parents d1d3813 + 5ba7d1a commit dc5f6de

File tree

164 files changed

+9576
-1924
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

164 files changed

+9576
-1924
lines changed

staging/api/RELEASE.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ post to the [operator-framework group][of-ggroup].
88
## Tags
99

1010
As per semver, all releases containing new features must map to a major or minor version increase.
11-
Patch releases must only contain fixes to features released in a prior release.
11+
12+
**Patch releases must only contain bug fixes. Releases containing features must be major or minor releases.**
1213

1314
## Process
1415

@@ -31,6 +32,8 @@ Then create release notes while still on the `master` branch:
3132
while read -r line; do echo $line | awk '{f = $1; $1 = ""; print "-"$0; }'; done <<< $(git log $PREVIOUS_RELEASE_TAG..$RELEASE_TAG --format=oneline --no-merges)
3233
```
3334

35+
**You cannot cut a patch release if any of these release notes start with `feat:` or `feature:`.**
36+
3437
Copy them into the Github release [description form][release-desc-page],
3538
select `vX.Y.Z` in the `Tag version` form, and click `Publish release`.
3639

staging/api/pkg/apis/scorecard/v1alpha3/configuration_types.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ type Configuration struct {
2222

2323
// Storage is the optional storage configuration
2424
Storage Storage `json:"storage,omitempty" yaml:"storage,omitempty"`
25+
26+
// ServiceAccount is the service account under which scorecard tests are run. This field is optional. If left unset, the `default` service account will be used.
27+
ServiceAccount string `json:"serviceaccount,omitempty" yaml:"serviceaccount,omitempty"`
2528
}
2629

2730
// StageConfiguration configures a set of tests to be run.

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import (
88
operatorsv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1"
99
"github.com/operator-framework/api/pkg/validation/errors"
1010
interfaces "github.com/operator-framework/api/pkg/validation/interfaces"
11+
v1 "k8s.io/api/core/v1"
12+
"k8s.io/apimachinery/pkg/runtime"
1113
"k8s.io/apimachinery/pkg/runtime/schema"
1214
)
1315

@@ -26,9 +28,42 @@ func validateBundles(objs ...interface{}) (results []errors.ManifestResult) {
2628
func validateBundle(bundle *manifests.Bundle) (result errors.ManifestResult) {
2729
result = validateOwnedCRDs(bundle, bundle.CSV)
2830
result.Name = bundle.CSV.Spec.Version.String()
31+
saErrors := validateServiceAccounts(bundle)
32+
if saErrors != nil {
33+
result.Add(saErrors...)
34+
}
2935
return result
3036
}
3137

38+
func validateServiceAccounts(bundle *manifests.Bundle) []errors.Error {
39+
// get service account names defined in the csv
40+
saNamesFromCSV := make(map[string]struct{}, 0)
41+
for _, deployment := range bundle.CSV.Spec.InstallStrategy.StrategySpec.DeploymentSpecs {
42+
saName := deployment.Spec.Template.Spec.ServiceAccountName
43+
saNamesFromCSV[saName] = struct{}{}
44+
}
45+
46+
// find any hardcoded service account objects are in the bundle, then check if they match any sa definition in the csv
47+
var errs []errors.Error
48+
for _, obj := range bundle.Objects {
49+
if obj.GroupVersionKind() != v1.SchemeGroupVersion.WithKind("ServiceAccount") {
50+
continue
51+
}
52+
sa := v1.ServiceAccount{}
53+
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &sa); err == nil {
54+
if _, ok := saNamesFromCSV[sa.Name]; ok {
55+
errs = append(errs, errors.ErrInvalidBundle(fmt.Sprintf("invalid service account found in bundle. " +
56+
"This service account %s in your bundle is not valid, because a service account with the same name " +
57+
"was already specified in your CSV. If this was unintentional, please remove the service account " +
58+
"manifest from your bundle. If it was intentional to specify a separate service account, " +
59+
"please rename the SA in either the bundle manifest or the CSV.",sa.Name), sa.Name))
60+
}
61+
}
62+
}
63+
64+
return errs
65+
}
66+
3267
func validateOwnedCRDs(bundle *manifests.Bundle, csv *operatorsv1alpha1.ClusterServiceVersion) (result errors.ManifestResult) {
3368
ownedKeys := getOwnedCustomResourceDefintionKeys(csv)
3469

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

Lines changed: 107 additions & 7 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
)
@@ -43,20 +45,118 @@ func TestValidateBundle(t *testing.T) {
4345
hasError: true,
4446
errString: `duplicate CRD "test.example.com/v1alpha1, Kind=Test" in bundle "test-operator.v0.0.1"`,
4547
},
48+
{
49+
description: "invalid bundle service account can't match sa in csv",
50+
directory: "./testdata/invalid_bundle_sa",
51+
hasError: true,
52+
errString: `invalid service account found in bundle. This service account etcd-operator in your bundle is not valid, because a service account with the same name was already specified in your CSV. If this was unintentional, please remove the service account manifest from your bundle. If it was intentional to specify a separate service account, please rename the SA in either the bundle manifest or the CSV.`,
53+
},
4654
}
4755

4856
for _, tt := range table {
49-
// Validate the bundle object
50-
bundle, err := manifests.GetBundleFromDir(tt.directory)
51-
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)
5261

53-
results := BundleValidator.Validate(bundle)
62+
results := BundleValidator.Validate(bundle)
5463

55-
if len(results) > 0 {
56-
require.Equal(t, results[0].HasError(), tt.hasError)
57-
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")
5867
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")
5970
}
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
6081
}
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. This service account foo in your bundle is not valid, because a service account with the same name was already specified in your CSV. If this was unintentional, please remove the service account manifest from your bundle. If it was intentional to specify a separate service account, please rename the SA in either the bundle manifest or the 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+
})
61161
}
62162
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ const IndexImagePathKey = "index-path"
2121
// where the bundle will be distributed
2222
const ocpLabelindex = "com.redhat.openshift.versions"
2323

24+
// OCP version where the apis v1beta1 is no longer supported
25+
const ocpVerV1beta1Unsupported = "4.9"
26+
2427
// CommunityOperatorValidator validates the bundle manifests against the required criteria to publish
2528
// the projects on the community operators
2629
//

0 commit comments

Comments
 (0)