Skip to content

Commit 875c19b

Browse files
committed
Automate OCP-42543: should not install resources annotated with release.openshift.io/delete=true
1 parent 95c76c7 commit 875c19b

File tree

4 files changed

+92
-5
lines changed

4 files changed

+92
-5
lines changed

.openshift-tests-extension/openshift_payload_cluster-version-operator.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,19 @@
2828
"source": "openshift:payload:cluster-version-operator",
2929
"lifecycle": "blocking",
3030
"environmentSelector": {}
31+
},
32+
{
33+
"name": "[Jira:\"Cluster Version Operator\"] cluster-version-operator should not install resources annotated with release.openshift.io/delete=true",
34+
"labels": {
35+
"42543": {},
36+
"Conformance": {},
37+
"High": {}
38+
},
39+
"resources": {
40+
"isolation": {}
41+
},
42+
"source": "openshift:payload:cluster-version-operator",
43+
"lifecycle": "blocking",
44+
"environmentSelector": {}
3145
}
3246
]

test/cvo/cvo.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
package cvo
22

33
import (
4+
"bytes"
45
"context"
6+
"fmt"
7+
"os"
8+
"path/filepath"
9+
"strings"
510

611
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
712
"k8s.io/client-go/kubernetes"
@@ -13,6 +18,7 @@ import (
1318
"github.com/openshift/cluster-version-operator/test/oc"
1419
ocapi "github.com/openshift/cluster-version-operator/test/oc/api"
1520
"github.com/openshift/cluster-version-operator/test/util"
21+
"github.com/openshift/library-go/pkg/manifest"
1622
)
1723

1824
var logger = g.GinkgoLogr.WithName("cluster-version-operator-tests")
@@ -80,4 +86,56 @@ var _ = g.Describe(`[Jira:"Cluster Version Operator"] cluster-version-operator`,
8086
sccAnnotation := cvoPod.Annotations["openshift.io/scc"]
8187
o.Expect(sccAnnotation).To(o.Equal("hostaccess"), "Expected the annotation 'openshift.io/scc annotation' on pod %s to have the value 'hostaccess', but got %s", cvoPod.Name, sccAnnotation)
8288
})
89+
90+
g.It(`should not install resources annotated with release.openshift.io/delete=true`, g.Label("Conformance", "High", "42543"), func() {
91+
// Initialize the ocapi.OC instance
92+
g.By("Setting up oc")
93+
err := os.Setenv("OC_CLI_TIMEOUT", "90s")
94+
o.Expect(err).NotTo(o.HaveOccurred(), "Setup environment variable OC_CLI_TIMEOUT failed")
95+
ocClient, err := oc.NewOC(logger)
96+
o.Expect(err).NotTo(o.HaveOccurred())
97+
o.Expect(ocClient).NotTo(o.BeNil())
98+
defer func() {
99+
err = os.Unsetenv("OC_CLI_TIMEOUT")
100+
o.Expect(err).NotTo(o.HaveOccurred(), "Unset environment variable OC_CLI_TIMEOUT failed")
101+
}()
102+
103+
g.By("Extracting manifests in the release")
104+
annotation := "release.openshift.io/delete"
105+
manifestDir := ocapi.ReleaseExtractOptions{To: "/tmp/OTA-42543-manifest"}
106+
logger.Info(fmt.Sprintf("Extract manifests to: %s", manifestDir.To))
107+
defer func() { _ = os.RemoveAll(manifestDir.To) }()
108+
err = ocClient.AdmReleaseExtract(manifestDir)
109+
o.Expect(err).NotTo(o.HaveOccurred(), "extracting manifests failed")
110+
111+
files, err := os.ReadDir(manifestDir.To)
112+
o.Expect(err).NotTo(o.HaveOccurred())
113+
g.By(fmt.Sprintf("Checking if getting manifests with %s on the cluster led to not-found error", annotation))
114+
for _, manifestFile := range files {
115+
if strings.Contains(strings.ToLower(manifestFile.Name()), "cleanup") {
116+
logger.Info(fmt.Sprintf("skipping file %s because it matches cleanup filter", manifestFile.Name()))
117+
continue
118+
}
119+
120+
filePath := filepath.Join(manifestDir.To, manifestFile.Name())
121+
raw, err := os.ReadFile(filePath)
122+
if err != nil {
123+
o.Expect(err).NotTo(o.HaveOccurred(), "failed to read manifest file")
124+
}
125+
manifests, err := manifest.ParseManifests(bytes.NewReader(raw))
126+
if err != nil {
127+
// files like release-metadata are not manifest file, so skip them
128+
logger.Error(err, "failed to parse manifest file: "+filePath)
129+
}
130+
131+
for _, ms := range manifests {
132+
ann := ms.Obj.GetAnnotations()
133+
if ann == nil || ann[annotation] != "true" {
134+
continue
135+
}
136+
_, err := ocClient.Run("get", "-f", filePath)
137+
o.Expect(err).To(o.HaveOccurred(), "The deleted manifest should not be installed, but actually installed")
138+
}
139+
}
140+
})
83141
})

test/oc/api/api.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ type VersionOptions struct {
1111
type OC interface {
1212
AdmReleaseExtract(o ReleaseExtractOptions) error
1313
Version(o VersionOptions) (string, error)
14+
Run(args ...string) ([]byte, error)
1415
}

test/oc/cli/cli.go

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ type client struct {
2020
}
2121

2222
type executor interface {
23-
Run(args ...string) ([]byte, error)
23+
run(args ...string) ([]byte, error)
2424
}
2525

2626
type ocExecutor struct {
@@ -32,7 +32,7 @@ type ocExecutor struct {
3232
execute func(dir, command string, args ...string) ([]byte, error)
3333
}
3434

35-
func (e *ocExecutor) Run(args ...string) ([]byte, error) {
35+
func (e *ocExecutor) run(args ...string) ([]byte, error) {
3636
logger := e.logger.WithValues("cmd", e.oc, "args", strings.Join(args, " "))
3737
b, err := e.execute("", e.oc, args...)
3838
if err != nil {
@@ -70,12 +70,13 @@ func NewOCCli(logger logr.Logger) (api.OC, error) {
7070
timeout := 30 * time.Second
7171
timeoutStr := os.Getenv("OC_CLI_TIMEOUT")
7272
if timeoutStr != "" {
73+
logger.Info(fmt.Sprintf("will use the environment timeout variable to run command: %s", timeoutStr))
7374
timeout, err = time.ParseDuration(timeoutStr)
7475
if err != nil {
7576
return nil, err
7677
}
7778
}
78-
79+
logger.Info(fmt.Sprintf("timeout is: %s", timeout))
7980
executor, err := newOCExecutor(oc, timeout, logger)
8081
if err != nil {
8182
return nil, err
@@ -88,8 +89,17 @@ func NewOCCli(logger logr.Logger) (api.OC, error) {
8889
}
8990

9091
func (c *client) AdmReleaseExtract(o api.ReleaseExtractOptions) error {
92+
_, err := os.Stat(o.To)
93+
if errors.Is(err, os.ErrNotExist) {
94+
c.logger.Info(fmt.Sprintf("the output directory does not exist, will create it: %s", o.To))
95+
if err = os.Mkdir(o.To, 0755); err != nil {
96+
err = fmt.Errorf("failed to create directory: %v", err)
97+
return err
98+
}
99+
c.logger.Info(fmt.Sprintf("the output directory has been created: %s", o.To))
100+
}
91101
args := []string{"adm", "release", "extract", fmt.Sprintf("--to=%s", o.To)}
92-
_, err := c.executor.Run(args...)
102+
_, err = c.executor.run(args...)
93103
if err != nil {
94104
return err
95105
}
@@ -98,9 +108,13 @@ func (c *client) AdmReleaseExtract(o api.ReleaseExtractOptions) error {
98108

99109
func (c *client) Version(o api.VersionOptions) (string, error) {
100110
args := []string{"version", fmt.Sprintf("--client=%t", o.Client)}
101-
output, err := c.executor.Run(args...)
111+
output, err := c.executor.run(args...)
102112
if err != nil {
103113
return "", err
104114
}
105115
return string(output), nil
106116
}
117+
118+
func (c *client) Run(args ...string) ([]byte, error) {
119+
return c.executor.run(args...)
120+
}

0 commit comments

Comments
 (0)