Skip to content

Commit 285e0ce

Browse files
Merge pull request #5621 from sergiordlr/migrate_security_tests
MCO-2110: Migrate security tests
2 parents 2163096 + a9c528d commit 285e0ce

20 files changed

Lines changed: 3162 additions & 72 deletions

cmd/machine-config-tests-ext/main.go

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,6 @@ func applyLabelFilters(specs et.ExtensionTestSpecs) {
4141
}
4242
}
4343
})
44-
45-
// Exclude tests with "Exclude:REASON" labels
46-
specs.Walk(func(spec *et.ExtensionTestSpec) {
47-
for label := range spec.Labels {
48-
if strings.HasPrefix(label, "Exclude:") {
49-
spec.Exclude("true")
50-
}
51-
}
52-
})
5344
}
5445

5546
func main() {
@@ -92,6 +83,12 @@ func main() {
9283
panic(fmt.Sprintf("couldn't build extension test specs from ginkgo: %+v", err.Error()))
9384
}
9485

86+
// Exclude tests with "Exclude:REASON" labels
87+
specs = specs.MustFilter([]string{
88+
`!labels.exists(l, l.startsWith("Exclude:"))`,
89+
})
90+
91+
// Configure environment flags filters
9592
applyLabelFilters(specs)
9693

9794
ext.AddSpecs(specs)

test/extended-priv/configmap.go

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66

77
o "github.com/onsi/gomega"
88
exutil "github.com/openshift/machine-config-operator/test/extended-priv/util"
9+
logger "github.com/openshift/machine-config-operator/test/extended-priv/util/logext"
910
)
1011

1112
// ConfigMap struct encapsulates the functionalities regarding ocp configmaps
@@ -28,7 +29,23 @@ func NewConfigMapList(oc *exutil.CLI, namespace string) *ConfigMapList {
2829
return &ConfigMapList{ResourceList: *NewNamespacedResourceList(oc, "ConfigMap", namespace)}
2930
}
3031

31-
// GetDataValue returns the value of a specific key in the .data field
32+
// HasKey returns if a key is present in "data"
33+
func (cm *ConfigMap) HasKey(key string) (string, bool, error) {
34+
dataMap, err := cm.GetDataMap()
35+
36+
if err != nil {
37+
return "", false, err
38+
}
39+
40+
data, ok := dataMap[key]
41+
if !ok {
42+
return "", false, nil
43+
}
44+
45+
return data, true, nil
46+
}
47+
48+
// GetDataValue return the value of a key stored in "data".
3249
func (cm *ConfigMap) GetDataValue(key string) (string, error) {
3350
// We cant use the "resource.Get" method, because exutil.client will trim the output, removing spaces and newlines that could be important in a configuration.
3451
dataMap, err := cm.GetDataMap()
@@ -44,6 +61,7 @@ func (cm *ConfigMap) GetDataValue(key string) (string, error) {
4461
}
4562

4663
return data, nil
64+
4765
}
4866

4967
// GetDataMap returns the valus in the .data field as a map[string][string]
@@ -61,7 +79,7 @@ func (cm *ConfigMap) GetDataMap() (map[string]string, error) {
6179
return data, nil
6280
}
6381

64-
// GetDataValueOrFail returns the value of a specific key in the .data field and fails the test if any error happens
82+
// GetDataValueOrFail return the value of a key stored in "data" and fails the test if the value cannot be retreived. If the "key" does not exist, it returns an empty string but does not fail
6583
func (cm *ConfigMap) GetDataValueOrFail(key string) string {
6684
value, err := cm.GetDataValue(key)
6785
o.ExpectWithOffset(1, err).NotTo(o.HaveOccurred(),
@@ -71,6 +89,52 @@ func (cm *ConfigMap) GetDataValueOrFail(key string) string {
7189
return value
7290
}
7391

92+
// SetData update the configmap with the given values. Same as "oc set data cm/..."
93+
func (cm *ConfigMap) SetData(arg string, args ...string) error {
94+
params := []string{"data"}
95+
params = append(params, cm.Resource.getCommonParams()...)
96+
params = append(params, arg)
97+
if len(args) > 0 {
98+
params = append(params, args...)
99+
}
100+
101+
return cm.Resource.oc.WithoutNamespace().Run("set").Args(params...).Execute()
102+
}
103+
104+
// RemoveDataKey removes a key from the configmap data values
105+
func (cm *ConfigMap) RemoveDataKey(key string) error {
106+
return cm.Patch("json", `[{"op": "remove", "path": "/data/`+key+`"}]`)
107+
}
108+
109+
// CreateConfigMapWithRandomCert creates a configmap that stores a random CA in it
110+
func CreateConfigMapWithRandomCert(oc *exutil.CLI, cmNamespace, cmName, certKey string) (*ConfigMap, error) {
111+
_, caPath, err := createCA(createTmpDir(), certKey)
112+
if err != nil {
113+
return nil, err
114+
}
115+
116+
err = oc.WithoutNamespace().Run("create").Args("cm", "-n", cmNamespace, cmName, "--from-file", caPath).Execute()
117+
118+
if err != nil {
119+
return nil, err
120+
}
121+
122+
return NewConfigMap(oc, cmNamespace, cmName), nil
123+
}
124+
125+
// GetCloudProviderConfigMap will return the CloudProviderConfigMap or nil if it is not defined in the infrastructure resource
126+
func GetCloudProviderConfigMap(oc *exutil.CLI) *ConfigMap {
127+
infra := NewResource(oc, "infrastructure", "cluster")
128+
cmName := infra.GetOrFail(`{.spec.cloudConfig.name}`)
129+
130+
if cmName == "" {
131+
logger.Infof("CloudProviderConfig ConfigMap is not defined in the infrastructure resource: %s", infra.PrettyString())
132+
return nil
133+
}
134+
135+
return NewConfigMap(oc, "openshift-config", cmName)
136+
}
137+
74138
// GetAll returns a []*ConfigMap list with all existing pinnedimageset sorted by creation timestamp
75139
func (cml *ConfigMapList) GetAll() ([]*ConfigMap, error) {
76140
cml.ResourceList.SortByTimestamp()

test/extended-priv/const.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,17 @@ const (
6060
// ExtensionsChangeIncWait extra minutes that MCPs will wait per node if we change the extensions in a configuration
6161
ExtensionsChangeIncWait = 5
6262

63+
// ImageRegistryCertificatesDir is the path were the image registry certificates will be stored in a node. Example: /etc/docker/certs.d/mycertname/ca.crt
64+
ImageRegistryCertificatesDir = "/etc/docker/certs.d"
65+
66+
// ImageRegistryCertificatesFileName is the name of the image registry certificates. Example: /etc/docker/certs.d/mycertname/ca.crt
67+
ImageRegistryCertificatesFileName = "ca.crt"
68+
69+
// SecurePort is the tls secured port to serve ignition configs
70+
IgnitionSecurePort = 22623
71+
// InsecurePort is the port to serve ignition configs w/o tls
72+
IgnitionInsecurePort = 22624
73+
6374
// MachineAPINamespace is the MachineAPI namespace
6475
MachineAPINamespace = "openshift-machine-api"
6576

@@ -87,6 +98,8 @@ const (
8798
BusyBoxImage = "quay.io/openshifttest/busybox@sha256:c5439d7db88ab5423999530349d327b04279ad3161d7596d2126dfb5b02bfd1f"
8899
// AlpineImage the multiplatform alpine image stored in openshifttest
89100
AlpineImage = "quay.io/openshifttest/alpine@sha256:dc1536cbff0ba235d4219462aeccd4caceab9def96ae8064257d049166890083"
101+
// TestSSLImage the testssl image stored in openshiftest
102+
TestSSLImage = "quay.io/openshifttest/testssl@sha256:ad6fb8002cb9cfce3ddc8829fd6e7e0d997aeb1faf972650f3e5d7603f90c6ef"
90103

91104
// Constants for NodeDisruptionPolicy
92105
NodeDisruptionPolicyActionNone = "None"
@@ -107,4 +120,13 @@ const (
107120
SkewEnforcementAutomaticMode = "Automatic"
108121
// SkewEnforcementNoneMode indicates boot image skew enforcement is disabled
109122
SkewEnforcementNoneMode = "None"
123+
124+
// MachineConfigServer mcs container name
125+
MachineConfigServer = "machine-config-server"
126+
127+
// TLS Security Version
128+
VersionTLS10 = 0x0301
129+
VersionTLS11 = 0x0302
130+
VersionTLS12 = 0x0303
131+
VersionTLS13 = 0x0304
110132
)
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
package extended
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
7+
b64 "encoding/base64"
8+
9+
exutil "github.com/openshift/machine-config-operator/test/extended-priv/util"
10+
logger "github.com/openshift/machine-config-operator/test/extended-priv/util/logext"
11+
"github.com/tidwall/gjson"
12+
)
13+
14+
// ControllerConfig struct is used to handle ControllerConfig resources in OCP
15+
type ControllerConfig struct {
16+
Resource
17+
}
18+
19+
// CertificateInfo stores the information regarding a given certificate
20+
type CertificateInfo struct {
21+
// subject is the cert subject
22+
Subject string `json:"subject"`
23+
24+
// signer is the cert Issuer
25+
Signer string `json:"signer"`
26+
27+
// notBefore is the lower boundary for validity
28+
NotBefore string `json:"notBefore"`
29+
30+
// notAfter is the upper boundary for validity
31+
NotAfter string `json:"notAfter"`
32+
33+
// bundleFile is the larger bundle a cert comes from
34+
BundleFile string `json:"bundleFile"`
35+
}
36+
37+
// NewControllerConfig create a ControllerConfig struct
38+
func NewControllerConfig(oc *exutil.CLI, name string) *ControllerConfig {
39+
return &ControllerConfig{Resource: *NewResource(oc, "ControllerConfig", name)}
40+
}
41+
42+
// GetKubeAPIServerServingCAData return the base64 decoded value of the kubeAPIServerServingCAData bundle stored in the ControllerConfig
43+
func (cc *ControllerConfig) GetKubeAPIServerServingCAData() (string, error) {
44+
b64KubeAPIServerServingData, err := cc.Get(`{.spec.kubeAPIServerServingCAData}`)
45+
if err != nil {
46+
return "", err
47+
}
48+
49+
kubeAPIServerServingCAData, err := b64.StdEncoding.DecodeString(b64KubeAPIServerServingData)
50+
if err != nil {
51+
return "", err
52+
}
53+
return string(kubeAPIServerServingCAData), err
54+
}
55+
56+
// GetRootCAData return the base64 decoded value of the rootCA bundle stored in the ControllerConfig
57+
func (cc *ControllerConfig) GetRootCAData() (string, error) {
58+
b64RootCAData, err := cc.Get(`{.spec.rootCAData}`)
59+
if err != nil {
60+
return "", err
61+
}
62+
63+
rootCAData, err := b64.StdEncoding.DecodeString(b64RootCAData)
64+
if err != nil {
65+
return "", err
66+
}
67+
return string(rootCAData), err
68+
}
69+
70+
// GetImageRegistryBundleData returns a map[string]string containing the filenames and values of the image registry bundle data
71+
func (cc *ControllerConfig) GetImageRegistryBundleData() (map[string]string, error) {
72+
return cc.GetImageRegistryBundle("imageRegistryBundleData")
73+
}
74+
75+
// GetImageRegistryBundleUserData returns a map[string]string containing the filenames and values of the image registry bundle user data
76+
func (cc *ControllerConfig) GetImageRegistryBundleUserData() (map[string]string, error) {
77+
return cc.GetImageRegistryBundle("imageRegistryBundleUserData")
78+
}
79+
80+
// GetImageRegistryBundle returns a map[string]string containing the filenames and values of the image registry certificates in a Bundle field
81+
func (cc *ControllerConfig) GetImageRegistryBundle(bundleField string) (map[string]string, error) {
82+
certs := map[string]string{}
83+
84+
bundleData, err := cc.Get(`{.spec.` + bundleField + `}`)
85+
if err != nil {
86+
return nil, err
87+
}
88+
89+
parsedBundleData := gjson.Parse(bundleData)
90+
91+
var b64Err error
92+
parsedBundleData.ForEach(func(_, item gjson.Result) bool {
93+
file := item.Get("file").String()
94+
data64 := item.Get("data").String()
95+
96+
data, b64Err := b64.StdEncoding.DecodeString(data64)
97+
if err != nil {
98+
logger.Infof("Error decoding data for image registry bundle file %s: %s", file, b64Err)
99+
return false // stop iterating
100+
}
101+
102+
certs[file] = string(data)
103+
return true // keep iterating
104+
})
105+
if b64Err != nil {
106+
return nil, b64Err
107+
}
108+
109+
return certs, nil
110+
}
111+
112+
// GetImageRegistryBundleByFileName returns the image registry bundle searching by bundle filename
113+
func (cc *ControllerConfig) GetImageRegistryBundleDataByFileName(fileName string) (string, error) {
114+
certs, err := cc.GetImageRegistryBundleData()
115+
if err != nil {
116+
return "", err
117+
}
118+
119+
data, ok := certs[fileName]
120+
if !ok {
121+
return "", fmt.Errorf("There is no image registry bundle with file name %s", fileName)
122+
}
123+
124+
return data, nil
125+
}
126+
127+
// GetImageRegistryUserBundleByFileName returns the image registry bundle searching by bundle filename
128+
func (cc *ControllerConfig) GetImageRegistryBundleUserDataByFileName(fileName string) (string, error) {
129+
certs, err := cc.GetImageRegistryBundleUserData()
130+
if err != nil {
131+
return "", err
132+
}
133+
134+
data, ok := certs[fileName]
135+
if !ok {
136+
return "", fmt.Errorf("There is no image registry bundle with file name %s", fileName)
137+
}
138+
139+
return data, nil
140+
}
141+
142+
// Returns a list of CertificateInfo structs with the information of all the certificates tracked by ControllerConfig
143+
func (cc *ControllerConfig) GetCertificatesInfo() ([]CertificateInfo, error) {
144+
certsInfoString := cc.GetOrFail(`{.status.controllerCertificates}`)
145+
146+
logger.Debugf("CERTIFICATES: %s", certsInfoString)
147+
148+
var certsInfo []CertificateInfo
149+
150+
jsonerr := json.Unmarshal([]byte(certsInfoString), &certsInfo)
151+
152+
if jsonerr != nil {
153+
return nil, jsonerr
154+
}
155+
156+
return certsInfo, nil
157+
}
158+
159+
func (cc *ControllerConfig) GetCertificatesInfoByBundleFileName(bundleFile string) ([]CertificateInfo, error) {
160+
161+
var certsInfo []CertificateInfo
162+
163+
allCertsInfo, err := cc.GetCertificatesInfo()
164+
if err != nil {
165+
return nil, err
166+
}
167+
168+
for _, ciLoop := range allCertsInfo {
169+
ci := ciLoop
170+
if ci.BundleFile == bundleFile {
171+
certsInfo = append(certsInfo, ci)
172+
}
173+
}
174+
175+
return certsInfo, nil
176+
}

0 commit comments

Comments
 (0)