/
fips.go
84 lines (74 loc) · 2.86 KB
/
fips.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package security
import (
"context"
"fmt"
"strconv"
"strings"
g "github.com/onsi/ginkgo/v2"
o "github.com/onsi/gomega"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
admissionapi "k8s.io/pod-security-admission/api"
configv1 "github.com/openshift/api/config/v1"
exutil "github.com/openshift/origin/test/extended/util"
)
const (
installConfigName = "cluster-config-v1"
fipsFile = "/proc/sys/crypto/fips_enabled"
)
func validateFIPSOnNode(oc *exutil.CLI, fipsExpected bool, node *corev1.Node) error {
// The oc debug output prints a bunch of info messages and possible warnings (the latter can not be disabled).
// Echo a prefix to be able to identify the line with our output.
const commandLineIdentifierPrefix = "fips-command"
out, err := oc.AsAdmin().Run("debug").Args("node/"+node.Name, "--", "/bin/bash", "-c", "echo -n "+commandLineIdentifierPrefix+" && cat "+fipsFile).Output()
if err != nil {
return err
}
var outFiltered string
for _, line := range strings.Split(out, "\n") {
if strings.HasPrefix(line, commandLineIdentifierPrefix) {
outFiltered = strings.TrimPrefix(line, commandLineIdentifierPrefix)
break
}
}
nodeFips, err := strconv.ParseBool(outFiltered)
if err != nil {
return fmt.Errorf("Error parsing %s on node %s: %v", fipsFile, node.Name, err)
}
if nodeFips != fipsExpected {
return fmt.Errorf("Expected FIPS state %v, found %v", fipsExpected, nodeFips)
}
return nil
}
var _ = g.Describe("[sig-arch] [Conformance] FIPS", func() {
defer g.GinkgoRecover()
oc := exutil.NewCLIWithPodSecurityLevel("fips", admissionapi.LevelPrivileged)
g.It("TestFIPS", func() {
controlPlaneTopology, err := exutil.GetControlPlaneTopology(oc)
o.Expect(err).NotTo(o.HaveOccurred())
clusterAdminKubeClientset := oc.AdminKubeClient()
isFIPS, err := exutil.IsFIPS(clusterAdminKubeClientset.CoreV1())
o.Expect(err).NotTo(o.HaveOccurred())
// fetch one control plane and one worker, and validate FIPS state on it.
// skip the controlplane node verification when external controlPlaneTopology as
// there are no controlplane nodes.
if *controlPlaneTopology != configv1.ExternalTopologyMode {
masterNodes, err := clusterAdminKubeClientset.CoreV1().Nodes().List(context.Background(), metav1.ListOptions{
LabelSelector: "node-role.kubernetes.io/master",
})
o.Expect(err).NotTo(o.HaveOccurred())
masterNode := &masterNodes.Items[0]
err = validateFIPSOnNode(oc, isFIPS, masterNode)
}
o.Expect(err).NotTo(o.HaveOccurred())
workerNodes, err := clusterAdminKubeClientset.CoreV1().Nodes().List(context.Background(), metav1.ListOptions{
LabelSelector: "node-role.kubernetes.io/worker",
})
o.Expect(err).NotTo(o.HaveOccurred())
if len(workerNodes.Items) > 0 {
workerNode := &workerNodes.Items[0]
err = validateFIPSOnNode(oc, isFIPS, workerNode)
o.Expect(err).NotTo(o.HaveOccurred())
}
})
})