Skip to content

Commit 8a92c65

Browse files
committed
Add feature "confidential"
Remove dummy feature "timeTravel". Add two functions: - handleFeatureConfidential - updateConfigMap (in utils.go) When the feature is enabled, handleFeatureConfidential sets config maps to confidential values. Changes the ImageConfigMap, so that the image creation job will create a confidential image. This will happen at the first reconciliation loop, before the image creation job starts. Changes the peer pods configMap to enable confidential. This will happen likely after several reconciliation loops, because it has prerequisites: - Peer pods must be enabled in the KataConfig. - The peer pods config map must exist. When the feature is disabled, handleFeatureConfidential resets the config maps to non-confidential values. Signed-off-by: Camilla Conte <[email protected]>
1 parent 0bbc7c7 commit 8a92c65

File tree

3 files changed

+128
-22
lines changed

3 files changed

+128
-22
lines changed

controllers/confidential_handler.go

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package controllers
2+
3+
import (
4+
k8serrors "k8s.io/apimachinery/pkg/api/errors"
5+
)
6+
7+
// When the feature is enabled, handleFeatureConfidential sets config maps to confidential values.
8+
//
9+
// Changes the ImageConfigMap, so that the image creation job will create a confidential image.
10+
// This will happen at the first reconciliation loop, before the image creation job starts.
11+
//
12+
// Changes the peer pods configMap to enable confidential.
13+
// This will happen likely after several reconciliation loops, because it has prerequisites:
14+
//
15+
// - Peer pods must be enabled in the KataConfig.
16+
// - The peer pods config map must exist.
17+
//
18+
// When the feature is disabled, handleFeatureConfidential resets the config maps to non-confidential values.
19+
func (r *KataConfigOpenShiftReconciler) handleFeatureConfidential(state FeatureGateState) error {
20+
21+
// ImageConfigMap
22+
23+
if err := InitializeImageGenerator(r.Client); err != nil {
24+
return err
25+
}
26+
ig := GetImageGenerator()
27+
28+
if ig.provider == unsupportedCloudProvider {
29+
r.Log.Info("unsupported cloud provider, skipping confidential image configuration")
30+
} else {
31+
if ig.isImageIDSet() {
32+
r.Log.Info("Image ID is already set, skipping confidential image configuration")
33+
} else {
34+
if state == Enabled {
35+
// Create ImageConfigMap, if it doesn't exist already.
36+
if err := ig.createImageConfigMapFromFile(); err != nil {
37+
return err
38+
}
39+
40+
// Patch ImageConfigMap.
41+
imageConfigMapData := map[string]string{"CONFIDENTIAL_COMPUTE_ENABLED": "yes"}
42+
if err := updateConfigMap(r.Client, r.Log, ig.getImageConfigMapName(), OperatorNamespace, imageConfigMapData); err != nil {
43+
return err
44+
}
45+
} else {
46+
// Patch ImageConfigMap.
47+
imageConfigMapData := map[string]string{"CONFIDENTIAL_COMPUTE_ENABLED": "no"}
48+
if err := updateConfigMap(r.Client, r.Log, ig.getImageConfigMapName(), OperatorNamespace, imageConfigMapData); err != nil {
49+
if k8serrors.IsNotFound(err) {
50+
// Nothing to do, feature is disabled and configMap doesn't exist.
51+
} else {
52+
return err
53+
}
54+
}
55+
}
56+
}
57+
}
58+
59+
// peer pods config
60+
61+
// Patch peer pods configMap, if it exists.
62+
var peerpodsCMData map[string]string
63+
if state == Enabled {
64+
peerpodsCMData = map[string]string{"DISABLECVM": "false"}
65+
} else {
66+
peerpodsCMData = map[string]string{"DISABLECVM": "true"}
67+
}
68+
if err := updateConfigMap(r.Client, r.Log, peerpodsCMName, OperatorNamespace, peerpodsCMData); err != nil {
69+
if k8serrors.IsNotFound(err) {
70+
// When feature is Enabled: ConfigMap doesn't exist yet, will try again at the next reconcile run.
71+
// Else: Nothing to do, feature is disabled and configMap doesn't exist.
72+
} else {
73+
return err
74+
}
75+
}
76+
77+
return nil
78+
}

controllers/fg_handler.go

+18-22
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,20 @@ import (
99
)
1010

1111
const (
12-
TimeTravelFeatureGate = "timeTravel"
13-
FgConfigMapName = "osc-feature-gates"
12+
FgConfigMapName = "osc-feature-gates"
13+
ConfidentialFeatureGate = "confidential"
1414
)
1515

1616
var DefaultFeatureGates = map[string]bool{
17-
"timeTravel": false,
17+
ConfidentialFeatureGate: false,
1818
}
1919

2020
type FeatureGateStatus struct {
2121
FeatureGates map[string]bool
2222
}
2323

2424
// Create enum to represent the state of the feature gates
25+
// While today we just have two states, we retain the flexibility in case we want to introduce some additional states.
2526
type FeatureGateState int
2627

2728
const (
@@ -78,27 +79,22 @@ func (r *KataConfigOpenShiftReconciler) processFeatureGates() error {
7879

7980
// Check which feature gates are enabled in the FG ConfigMap and
8081
// perform the necessary actions
81-
82-
if IsEnabled(fgStatus, TimeTravelFeatureGate) {
83-
r.Log.Info("Feature gate is enabled", "featuregate", TimeTravelFeatureGate)
84-
// Perform the necessary actions
85-
r.handleTimeTravelFeature(Enabled)
86-
} else {
87-
r.Log.Info("Feature gate is disabled", "featuregate", TimeTravelFeatureGate)
88-
// Perform the necessary actions
89-
r.handleTimeTravelFeature(Disabled)
82+
if r.kataConfig.Spec.EnablePeerPods {
83+
if IsEnabled(fgStatus, ConfidentialFeatureGate) {
84+
r.Log.Info("Feature gate is enabled", "featuregate", ConfidentialFeatureGate)
85+
// Perform the necessary actions
86+
if err := r.handleFeatureConfidential(Enabled); err != nil {
87+
return err
88+
}
89+
} else {
90+
r.Log.Info("Feature gate is disabled", "featuregate", ConfidentialFeatureGate)
91+
// Perform the necessary actions
92+
if err := r.handleFeatureConfidential(Disabled); err != nil {
93+
return err
94+
}
95+
}
9096
}
9197

9298
return err
9399

94100
}
95-
96-
// Function to handle the TimeTravel feature gate
97-
func (r *KataConfigOpenShiftReconciler) handleTimeTravelFeature(state FeatureGateState) {
98-
// Perform the necessary actions for the TimeTravel feature gate
99-
if state == Enabled {
100-
r.Log.Info("Starting TimeTravel")
101-
} else {
102-
r.Log.Info("Stopping TimeTravel")
103-
}
104-
}

controllers/utils.go

+32
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"time"
1010

1111
yaml "github.com/ghodss/yaml"
12+
"github.com/go-logr/logr"
1213
configv1 "github.com/openshift/api/config/v1"
1314
ccov1 "github.com/openshift/cloud-credential-operator/pkg/apis/cloudcredential/v1"
1415
mcfgv1 "github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.openshift.io/v1"
@@ -192,3 +193,34 @@ func getClusterID(c client.Client) (string, error) {
192193
// Return first 8 characters of the cluster id
193194
return string(clusterVersion.Spec.ClusterID[:8]), nil
194195
}
196+
197+
func updateConfigMap(client client.Client, logger logr.Logger, cmName string, namespace string, newData map[string]string) error {
198+
// Get current configMap.
199+
configMap := &corev1.ConfigMap{}
200+
if err := client.Get(context.TODO(), types.NamespacedName{
201+
Name: cmName,
202+
Namespace: namespace,
203+
}, configMap); err != nil {
204+
return err
205+
}
206+
207+
update := false
208+
209+
// Loop over each new value
210+
// Update the value if it's different.
211+
// Log the change.
212+
for key, newValue := range newData {
213+
if configMap.Data[key] != newValue {
214+
logger.Info("updateConfigMap", "namespace", namespace, "name", cmName, "key", key, "value", newValue)
215+
configMap.Data[key] = newValue
216+
update = true
217+
}
218+
}
219+
220+
if update {
221+
// Update the configMap on Kubernetes.
222+
return client.Update(context.TODO(), configMap)
223+
} else {
224+
return nil
225+
}
226+
}

0 commit comments

Comments
 (0)