Skip to content

Commit 3722d28

Browse files
committed
adding eol check
1 parent c296a1c commit 3722d28

File tree

9 files changed

+246
-3
lines changed

9 files changed

+246
-3
lines changed

internal/chartverifier/checks/charttesting.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const (
2626
// Versioner provides OpenShift version
2727
type Versioner func(envSettings *cli.EnvSettings) (string, error)
2828

29-
func getVersion(envSettings *cli.EnvSettings) (string, error) {
29+
func GetVersion(envSettings *cli.EnvSettings) (string, error) {
3030
kubeConfig := tool.GetClientConfig(envSettings)
3131
kubectl, err := tool.NewKubectl(kubeConfig)
3232
if err != nil {
@@ -174,7 +174,7 @@ func ChartTesting(opts *CheckOptions) (Result, error) {
174174
}
175175
}
176176

177-
if versionError := setOCVersion(opts.AnnotationHolder, opts.HelmEnvSettings, getVersion); versionError != nil {
177+
if versionError := setOCVersion(opts.AnnotationHolder, opts.HelmEnvSettings, GetVersion); versionError != nil {
178178
if versionError != nil {
179179
utils.LogWarning(fmt.Sprintf("End chart install and test check with version error: %v", versionError))
180180
}

internal/chartverifier/checks/checks.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"strings"
2828

2929
"github.com/opdev/getocprange"
30+
"github.com/redhat-certification/chart-verifier/internal/chartverifier/utils"
3031
"helm.sh/helm/v3/pkg/action"
3132
"helm.sh/helm/v3/pkg/lint"
3233
"helm.sh/helm/v3/pkg/lint/support"
@@ -64,6 +65,8 @@ const (
6465
ImageCertified = "Image is Red Hat certified"
6566
ImageNotCertified = "Image is not Red Hat certified"
6667
ChartTestingSuccess = "Chart tests have passed"
68+
ClusterNotEOL = "Chart tests ran on a non EOL cluster"
69+
ClusterIsEOL = "Chart tests ran on an EOL cluster"
6770
MetadataFailure = "Empty metadata in chart"
6871
RequiredAnnotationsSuccess = "All required annotations present"
6972
RequiredAnnotationsFailure = "Missing required annotations"
@@ -529,3 +532,27 @@ func certifyImages(r Result, opts *CheckOptions, registry string) Result {
529532

530533
return r
531534
}
535+
536+
func ClusterIsNotEOL(opt *CheckOptions) (Result, error) {
537+
538+
// Get version with k8s client
539+
version, err := GetVersion(opt.HelmEnvSettings)
540+
if err != nil {
541+
return Result{}, err
542+
}
543+
544+
// Get lifecycle status for version
545+
lifeCycleData := utils.LifeCycleData{}
546+
lifecycleStatus, err := lifeCycleData.GetLifecycleStatus(version)
547+
if err != nil {
548+
return Result{}, err
549+
}
550+
551+
result := NewResult(true, ClusterNotEOL)
552+
if lifecycleStatus == "End of life" {
553+
result.SetResult(false, ClusterIsEOL)
554+
return result, nil
555+
}
556+
557+
return result, nil
558+
}

internal/chartverifier/profiles/default.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const (
1010
CheckVersion10 = "v1.0"
1111
CheckVersion11 = "v1.1"
1212
DefaultProfile = "partner"
13-
DefaultProfileVersion = "v1.3"
13+
DefaultProfileVersion = "v1.4"
1414
)
1515

1616
func getDefaultProfile(msg string) *Profile {
@@ -44,6 +44,7 @@ func getDefaultProfile(msg string) *Profile {
4444
{Name: fmt.Sprintf("%s/%s", CheckVersion10, apiChecks.RequiredAnnotationsPresent), Type: apiChecks.MandatoryCheckType},
4545
{Name: fmt.Sprintf("%s/%s", CheckVersion10, apiChecks.SignatureIsValid), Type: apiChecks.MandatoryCheckType},
4646
{Name: fmt.Sprintf("%s/%s", CheckVersion10, apiChecks.HasNotes), Type: apiChecks.OptionalCheckType},
47+
{Name: fmt.Sprintf("%s/%s", CheckVersion10, apiChecks.ClusterIsNotEOL), Type: apiChecks.OptionalCheckType},
4748
}
4849

4950
return &profile
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package utils
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"io"
7+
"net/http"
8+
"net/url"
9+
"strings"
10+
)
11+
12+
const ApiVersion = "v1"
13+
const Api = "products"
14+
const ApiEndpoint = "access.redhat.com/product-life-cycles/api/" + ApiVersion + "/" + Api
15+
const SearchString = "Openshift Container Platform"
16+
17+
type LifeCycleData struct {
18+
UUID string `json:"uuid"`
19+
Name string `json:"name"`
20+
FormerNames []any `json:"former_names"`
21+
ShowLastMinorRelease bool `json:"show_last_minor_release"`
22+
ShowFinalMinorRelease bool `json:"show_final_minor_release"`
23+
IsLayeredProduct bool `json:"is_layered_product"`
24+
AllPhases []struct {
25+
Name string `json:"name"`
26+
Ptype string `json:"ptype"`
27+
Tooltip any `json:"tooltip"`
28+
DisplayName string `json:"display_name"`
29+
AdditionalText string `json:"additional_text"`
30+
} `json:"all_phases"`
31+
Versions []struct {
32+
Name string `json:"name"`
33+
Type string `json:"type"`
34+
LastMinorRelease any `json:"last_minor_release"`
35+
FinalMinorRelease any `json:"final_minor_release"`
36+
ExtraHeaderValue any `json:"extra_header_value"`
37+
AdditionalText string `json:"additional_text"`
38+
Phases []struct {
39+
Name string `json:"name"`
40+
Date string `json:"date"`
41+
DateFormat string `json:"date_format"`
42+
AdditionalText string `json:"additional_text"`
43+
} `json:"phases"`
44+
Tier string `json:"tier"`
45+
OpenshiftCompatibility string `json:"openshift_compatibility"`
46+
ExtraDependences []any `json:"extra_dependences"`
47+
} `json:"versions"`
48+
Footnote string `json:"footnote"`
49+
IsOperator bool `json:"is_operator"`
50+
ShowOpenshiftCompatibility bool `json:"show_openshift_compatibility"`
51+
ReleaseCadence string `json:"release_cadence"`
52+
Package string `json:"package"`
53+
Link string `json:"link"`
54+
Policies string `json:"policies"`
55+
}
56+
57+
type Results struct {
58+
Data []LifeCycleData `json:"data"`
59+
}
60+
61+
func (*LifeCycleData) GetLifecycleStatus(clusterVersion string) (string, error) {
62+
63+
// Get lifecycle data
64+
requestURL := fmt.Sprintf("https://%s?name=%s", ApiEndpoint, url.QueryEscape(SearchString))
65+
res, err := http.Get(requestURL)
66+
if err != nil {
67+
fmt.Printf("Error getting request: %s\n", err)
68+
return "Unknown", err
69+
}
70+
defer res.Body.Close()
71+
body, err := io.ReadAll(res.Body)
72+
if err != nil {
73+
fmt.Printf("Error reading body: %s\n", err)
74+
}
75+
76+
// Filter to get EOL dates
77+
var results Results
78+
err = json.Unmarshal(body, &results)
79+
if err != nil {
80+
fmt.Printf("Error unmarshalling json: %s\n", err.Error())
81+
}
82+
for _, product := range results.Data {
83+
for _, version := range product.Versions {
84+
if strings.Compare(version.Name, clusterVersion) == 0 {
85+
return version.Type, nil
86+
}
87+
}
88+
}
89+
90+
return "Unknown", nil
91+
}

internal/chartverifier/verifierbuilder.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ func init() {
5151
defaultRegistry.Add(apiChecks.RequiredAnnotationsPresent, "v1.0", checks.RequiredAnnotationsPresent)
5252
defaultRegistry.Add(apiChecks.SignatureIsValid, "v1.0", checks.SignatureIsValid)
5353
defaultRegistry.Add(apiChecks.HasNotes, "v1.0", checks.HasNotes)
54+
defaultRegistry.Add(apiChecks.ClusterIsNotEOL, "v1.0", checks.ClusterIsNotEOL)
5455
}
5556

5657
func DefaultRegistry() checks.Registry {
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
apiversion: v1
2+
kind: verifier-profile
3+
vendorType: community
4+
version: v1.3
5+
annotations:
6+
- "Digest"
7+
- "TestedOpenShiftVersion"
8+
- "LastCertifiedTimestamp"
9+
- "SupportedOpenShiftVersions"
10+
checks:
11+
- name: v1.0/has-readme
12+
type: Optional
13+
- name: v1.0/is-helm-v3
14+
type: Optional
15+
- name: v1.0/contains-test
16+
type: Optional
17+
- name: v1.0/contains-values
18+
type: Optional
19+
- name: v1.0/contains-values-schema
20+
type: Optional
21+
- name: v1.1/has-kubeversion
22+
type: Optional
23+
- name: v1.0/not-contains-crds
24+
type: Optional
25+
- name: v1.0/helm-lint
26+
type: Mandatory
27+
- name: v1.0/not-contain-csi-objects
28+
type: Optional
29+
- name: v1.1/images-are-certified
30+
type: Optional
31+
- name: v1.0/chart-testing
32+
type: Optional
33+
- name: v1.0/required-annotations-present
34+
type: Optional
35+
- name: v1.0/signature-is-valid
36+
type: Optional
37+
- name: v1.0/has-notes
38+
type: Optional
39+
- name: v1.0/cluster-is-not-eol
40+
type: Optional
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
apiversion: v1
2+
kind: verifier-profile
3+
vendorType: partner
4+
version: v1.4
5+
annotations:
6+
- "Digest"
7+
- "TestedOpenShiftVersion"
8+
- "LastCertifiedTimestamp"
9+
- "SupportedOpenShiftVersions"
10+
checks:
11+
- name: v1.0/has-readme
12+
type: Mandatory
13+
- name: v1.0/is-helm-v3
14+
type: Mandatory
15+
- name: v1.0/contains-test
16+
type: Mandatory
17+
- name: v1.0/contains-values
18+
type: Mandatory
19+
- name: v1.0/contains-values-schema
20+
type: Mandatory
21+
- name: v1.1/has-kubeversion
22+
type: Mandatory
23+
- name: v1.0/not-contains-crds
24+
type: Mandatory
25+
- name: v1.0/helm-lint
26+
type: Mandatory
27+
- name: v1.0/not-contain-csi-objects
28+
type: Mandatory
29+
- name: v1.1/images-are-certified
30+
type: Mandatory
31+
- name: v1.0/chart-testing
32+
type: Mandatory
33+
- name: v1.0/required-annotations-present
34+
type: Mandatory
35+
- name: v1.0/signature-is-valid
36+
type: Mandatory
37+
- name: v1.0/has-notes
38+
type: Optional
39+
- name: v1.0/cluster-is-not-eol
40+
type: Optional
41+
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
apiversion: v1
2+
kind: verifier-profile
3+
vendorType: redhat
4+
version: v1.4
5+
annotations:
6+
- "Digest"
7+
- "TestedOpenShiftVersion"
8+
- "LastCertifiedTimestamp"
9+
- "SupportedOpenShiftVersions"
10+
checks:
11+
- name: v1.0/has-readme
12+
type: Mandatory
13+
- name: v1.0/is-helm-v3
14+
type: Mandatory
15+
- name: v1.0/contains-test
16+
type: Mandatory
17+
- name: v1.0/contains-values
18+
type: Mandatory
19+
- name: v1.0/contains-values-schema
20+
type: Mandatory
21+
- name: v1.1/has-kubeversion
22+
type: Mandatory
23+
- name: v1.0/not-contains-crds
24+
type: Mandatory
25+
- name: v1.0/helm-lint
26+
type: Mandatory
27+
- name: v1.0/not-contain-csi-objects
28+
type: Mandatory
29+
- name: v1.1/images-are-certified
30+
type: Mandatory
31+
- name: v1.0/chart-testing
32+
type: Mandatory
33+
- name: v1.0/required-annotations-present
34+
type: Mandatory
35+
- name: v1.0/signature-is-valid
36+
type: Mandatory
37+
- name: v1.0/has-notes
38+
type: Optional
39+
- name: v1.0/cluster-is-not-eol
40+
type: Optional

pkg/chartverifier/checks/checks.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const (
1515
RequiredAnnotationsPresent CheckName = "required-annotations-present"
1616
SignatureIsValid CheckName = "signature-is-valid"
1717
HasNotes CheckName = "has-notes"
18+
ClusterIsNotEOL CheckName = "cluster-is-not-eol"
1819
MandatoryCheckType CheckType = "Mandatory"
1920
OptionalCheckType CheckType = "Optional"
2021
ExperimentalCheckType CheckType = "Experimental"
@@ -27,6 +28,7 @@ var setCheckNames = []CheckName{
2728
ContainsValues,
2829
HasKubeVersion,
2930
HasNotes,
31+
ClusterIsNotEOL,
3032
HasReadme,
3133
HelmLint,
3234
ImagesAreCertified,

0 commit comments

Comments
 (0)