-
Notifications
You must be signed in to change notification settings - Fork 248
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat integrate spiffe #1663
base: master
Are you sure you want to change the base?
Feat integrate spiffe #1663
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
dependencies: | ||
- name: spire | ||
repository: https://spiffe.github.io/helm-charts-hardened/ | ||
version: 0.24.1 | ||
digest: sha256:f3b4dc973a59682bf3aa5ca9b53322f57935dd093081e82a37b8082e00becbe9 | ||
generated: "2024-12-20T16:52:40.180416+01:00" |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -52,15 +52,20 @@ import ( | |
"sigs.k8s.io/yaml" | ||
|
||
nfdclientset "sigs.k8s.io/node-feature-discovery/api/generated/clientset/versioned" | ||
"sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1" | ||
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1" | ||
"sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/nodefeaturerule" | ||
"sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/validate" | ||
nfdfeatures "sigs.k8s.io/node-feature-discovery/pkg/features" | ||
"sigs.k8s.io/node-feature-discovery/pkg/utils" | ||
klogutils "sigs.k8s.io/node-feature-discovery/pkg/utils/klog" | ||
spiffe "sigs.k8s.io/node-feature-discovery/pkg/utils/spiffe" | ||
"sigs.k8s.io/node-feature-discovery/pkg/version" | ||
) | ||
|
||
// SocketPath specifies Spiffe Socket Path | ||
const SocketPath = "unix:///run/spire/agent-sockets/api.sock" | ||
|
||
// Labels are a Kubernetes representation of discovered features. | ||
type Labels map[string]string | ||
|
||
|
@@ -93,6 +98,7 @@ type NFDConfig struct { | |
NfdApiParallelism int | ||
Klog klogutils.KlogConfigOpts | ||
Restrictions Restrictions | ||
EnableSpiffe bool | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, looking at this maybe it would be safest to only have this as a command line argument (i.e. NOT at as a dynamically configurable config file setting). Just to make it very clear if/when the setting is changed. WDYT? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sounds good for me! |
||
} | ||
|
||
// LeaderElectionConfig contains the configuration for leader election | ||
|
@@ -111,6 +117,7 @@ type ConfigOverrideArgs struct { | |
NoPublish *bool | ||
ResyncPeriod *utils.DurationVal | ||
NfdApiParallelism *int | ||
EnableSpiffe *bool | ||
} | ||
|
||
// Args holds command line arguments | ||
|
@@ -158,7 +165,8 @@ type nfdMaster struct { | |
nfdClient nfdclientset.Interface | ||
updaterPool *updaterPool | ||
deniedNs | ||
config *NFDConfig | ||
config *NFDConfig | ||
spiffeClient *spiffe.SpiffeClient | ||
} | ||
|
||
// NewNfdMaster creates a new NfdMaster server instance. | ||
|
@@ -216,6 +224,12 @@ func NewNfdMaster(opts ...NfdMasterOption) (NfdMaster, error) { | |
|
||
nfd.updaterPool = newUpdaterPool(nfd) | ||
|
||
spiffeClient, err := spiffe.NewSpiffeClient(SocketPath) | ||
if err != nil { | ||
return nfd, err | ||
} | ||
nfd.spiffeClient = spiffeClient | ||
|
||
return nfd, nil | ||
} | ||
|
||
|
@@ -257,14 +271,15 @@ func newDefaultConfig() *NFDConfig { | |
RetryPeriod: utils.DurationVal{Duration: time.Duration(2) * time.Second}, | ||
RenewDeadline: utils.DurationVal{Duration: time.Duration(10) * time.Second}, | ||
}, | ||
Klog: make(map[string]string), | ||
Restrictions: Restrictions{ | ||
DisableLabels: false, | ||
DisableExtendedResources: false, | ||
DisableAnnotations: false, | ||
AllowOverwrite: true, | ||
DenyNodeFeatureLabels: false, | ||
}, | ||
Klog: make(map[string]string), | ||
EnableSpiffe: false, | ||
} | ||
} | ||
|
||
|
@@ -680,6 +695,14 @@ func (m *nfdMaster) getAndMergeNodeFeatures(nodeName string) (*nfdv1alpha1.NodeF | |
return filteredObjs[i].Namespace < filteredObjs[j].Namespace | ||
}) | ||
|
||
// If spiffe is enabled, we should filter out the non verified NFD objects | ||
if m.config.EnableSpiffe { | ||
filteredObjs, err = m.getVerifiedNFDObjects(filteredObjs) | ||
if err != nil { | ||
return &nfdv1alpha1.NodeFeature{}, err | ||
} | ||
} | ||
|
||
if len(filteredObjs) > 0 { | ||
// Merge in features | ||
// | ||
|
@@ -1246,6 +1269,9 @@ func (m *nfdMaster) configure(filepath string, overrides string) error { | |
if m.args.Overrides.NfdApiParallelism != nil { | ||
c.NfdApiParallelism = *m.args.Overrides.NfdApiParallelism | ||
} | ||
if m.args.Overrides.EnableSpiffe != nil { | ||
c.EnableSpiffe = *m.args.Overrides.EnableSpiffe | ||
} | ||
|
||
if c.NfdApiParallelism <= 0 { | ||
return fmt.Errorf("the maximum number of concurrent labelers should be a non-zero positive number") | ||
|
@@ -1446,3 +1472,33 @@ func patchNode(cli k8sclient.Interface, nodeName string, patches []utils.JsonPat | |
func patchNodeStatus(cli k8sclient.Interface, nodeName string, patches []utils.JsonPatch) error { | ||
return patchNode(cli, nodeName, patches, "status") | ||
} | ||
|
||
func (m *nfdMaster) getVerifiedNFDObjects(objs []*v1alpha1.NodeFeature) ([]*v1alpha1.NodeFeature, error) { | ||
verifiedObjects := []*v1alpha1.NodeFeature{} | ||
|
||
workerPrivateKey, workerPublicKey, err := m.spiffeClient.GetWorkerKeys() | ||
if err != nil { | ||
return verifiedObjects, err | ||
} | ||
|
||
for _, obj := range objs { | ||
spiffeObj := spiffe.SpiffeObject{ | ||
Spec: obj.Spec, | ||
Name: obj.Name, | ||
Namespace: obj.Namespace, | ||
Labels: obj.Labels, | ||
} | ||
isSignatureVerified, err := spiffe.VerifyDataSignature(spiffeObj, obj.Annotations["signature"], workerPrivateKey, workerPublicKey) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to verify NodeFeature signature: %w", err) | ||
} | ||
|
||
if isSignatureVerified { | ||
klog.InfoS("NodeFeature verified", "NodeFeature name", obj.Name) | ||
verifiedObjects = append(verifiedObjects, obj) | ||
} else { | ||
klog.InfoS("NodeFeature not verified, skipping...", "NodeFeature name", obj.Name) | ||
} | ||
} | ||
return verifiedObjects, nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@marquiz should we define this as a feature-gate???
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably not. I think this will never be enabled by default so feature gate feels superfluous (and unintuitive). It would serve as a unnecessary second-level gate (we'd want the enable/disable setting anyway), i.e. you'd need to specify
-feature-gates spiffe=true -enable-spiffe