Embedding ETW Name-GUID Mapping for Log Forward Service#2617
Embedding ETW Name-GUID Mapping for Log Forward Service#2617marma-dev wants to merge 4 commits intomicrosoft:mainfrom
Conversation
501b49d to
86e68a3
Compare
Signed-off-by: Manish Ranjan Mahanta <mmahanta@microsoft.com>
57b670a to
3ebe430
Compare
Signed-off-by: Manish Ranjan Mahanta <mmahanta@microsoft.com>
Signed-off-by: Manish Ranjan Mahanta <mmahanta@microsoft.com>
f18f459 to
2eac7bb
Compare
rawahars
left a comment
There was a problem hiding this comment.
Uber comment is about moving JSON to a Golang file which declares the entire struct.
The provider_map.go will be significantly reduced and optimized with the change above.
In case you are looking to guard against future modifications of the files, I suggest that you add a test file. In the test file, you can write a test which does the validation we are looking for. That way we can capture the errors during build time and ensure that our runtime code is simple.
Lastly, please add tests for provider_map.go once you have the final version.
| // Todo: Add policy enforcement for modifying service settings | ||
| modifyRequest, err := unmarshalModifyServiceSettings(req) | ||
| if err != nil { | ||
| return err |
There was a problem hiding this comment.
nit: For consistency in the method, either wrap the errors or return the errors and let caller handle them.
In this case, you can effectively wrap the error stating that unmarshall failed.
| guidToName map[string]string // STATIC | ||
| ) | ||
|
|
||
| // Log Sources JSON structure |
There was a problem hiding this comment.
We already have a well-defined LogSources structure here.
We can directly create a file default_logsources.go which includes the entire config in native Go format.
That is the preferred mechanism in Go and would also do away with parsing the json altogether.
Reference- https://github.com/kubernetes/kubernetes/blob/4221620945b1f1f73f651c7936456baffcf0327f/pkg/features/kube_features.go
There was a problem hiding this comment.
I've added the two go files for default sources and etw map. Lmk if its in line with what you had in mind
| } | ||
|
|
||
| // NormalizeGUID takes a GUID string in various formats and normalizes it to the standard 8-4-4-4-12 format with uppercase letters. It returns an error if the input string is not a valid GUID. | ||
| func NormalizeGUID(in string) (string, error) { |
There was a problem hiding this comment.
This method need not be exported if it is not used elsewhere.
| return | ||
| } | ||
|
|
||
| var cfg EtwInfo |
There was a problem hiding this comment.
If we have direct Go mapping, we can skip the logic here with parsing the JSON.
In such a case, we can remove this method and directly use the variables.
There was a problem hiding this comment.
Added a go for the map as well as default sources
| continue | ||
| } | ||
|
|
||
| // Duplicate check |
There was a problem hiding this comment.
Same here. Since these are hardcoded values, we can ensure not to add duplicate entries.
Moreover, if it's a Go Map, then the case is automatically taken care of.
There was a problem hiding this comment.
Added in a different go file
| return | ||
| } | ||
|
|
||
| // Check if the default log sources have provider names. If they do, do not include GUIDs in the |
There was a problem hiding this comment.
Again, this are hardcoded values. We can ensure that correct values are added instead of the static check here at runtime.
There was a problem hiding this comment.
I've added them as separate go files in the latest update.
internal/gcs-sidecar/handlers.go
Outdated
| settings.Settings = allowedLogSources | ||
| } | ||
| default: | ||
| log.G(req.ctx).Tracef("modifyServiceSettings for LogForwardService with RPCType: %v, skipping policy enforcement", settings.RPCType) |
There was a problem hiding this comment.
Can this ever happen? If so what sort of thing?
There was a problem hiding this comment.
Same for the other skipping cases. Maybe produce a warning if this is not expected.
There was a problem hiding this comment.
In the future if we add more RPCs and the sidecar is old and not updated (for some reason), then this could occur. But this is a stop-measure gap for the moment, till Mahati gets her changes for policy enforcement in.
Changed to raising a warning log
…d methods and addressing review comments Signed-off-by: Manish Ranjan Mahanta <mmahanta@microsoft.com>
| // ForwardLogs specifies whether to forward logs to the host or not. | ||
| ForwardLogs = "io.microsoft.virtualmachine.wcow.forwardlogs" | ||
| // Specifies whether to disable forwarding logs to the host or not. Defaults to false for (non-confidential) WCOW, meaning logs will be forwarded to the host if LogSources is set. And true for confidential containers, meaning logs will not be forwarded to the host by default. | ||
| DisableForwardLogs = "io.microsoft.virtualmachine.forwardlogs.disable" |
There was a problem hiding this comment.
nit: maybe switch up *.disable to *.enable, easier to read than double-negative.
| log.G(req.ctx).Tracef("Allowed log sources after policy enforcement: %v", allowedLogSources) | ||
|
|
||
| // Update the allowed log sources in the settings. This will be forwarded to inbox GCS which expects the log sources in a JSON string format with GUIDs for providers included. | ||
| allowedLogSources = etw.UpdateLogSources(req.ctx, allowedLogSources, false, true) |
There was a problem hiding this comment.
Given this is the func definition func UpdateLogSources(ctx context.Context, base64EncodedJSONLogConfig string, useDefaultLogSources bool, includeGUIDs bool) string {:
- Are you defaulting
useDefaultSourcestofalseas this check is already done on the shim side? Ideally it would be policy based? And until we have that, shouldn't this betrue?
| createOpts: opts, | ||
| blockCIMMounts: make(map[string]*UVMMountedBlockCIMs), | ||
| logSources: opts.LogSources, | ||
| forwardLogs: !opts.DisableLogForwarding, |
There was a problem hiding this comment.
nit: rename forwardLogs to match DisableLogForwarding to reflect this new name like you do below (or the other way around if you remove the double negative)
|
|
||
| forwardLogs bool // Indicates whether to forward logs from the UVM to the host | ||
| logSources string // ETW providers to enable for log forwarding | ||
| forwardLogs bool // Indicates whether to forward logs from the UVM to the host |
There was a problem hiding this comment.
nit: same here. naming consistency.
| @@ -0,0 +1,66 @@ | |||
| package etw | |||
|
|
|||
| // defaultLogSourcesInfo is the native Go representation of the default-logsources.json file. | |||
There was a problem hiding this comment.
nit: Comment is misleading. There is no default-logsources.json file now.
| guidToName map[string]string // STATIC | ||
| ) | ||
|
|
||
| // Log Sources JSON structure |
| if base64EncodedJSONLogConfig != "" { | ||
| jsonBytes, err := base64.StdEncoding.DecodeString(base64EncodedJSONLogConfig) | ||
| if err != nil { | ||
| log.G(ctx).Errorf("Error decoding base64 log config: %v", err) |
There was a problem hiding this comment.
Do we need to return error at all these places?
| } | ||
|
|
||
| // NormalizeGUID takes a GUID string in various formats and normalizes it to the standard 8-4-4-4-12 format with uppercase letters. It returns an error if the input string is not a valid GUID. | ||
| func normalizeGUID(in string) (string, error) { |
There was a problem hiding this comment.
use guid.FromString instead
As per the updated design below,
ModifyServiceSettingsappropriately and append GUIDs to the providers in Log Sources before forwarding the request to inbox-GCSThe user should only provide ETW Provider Name only for well-known GUIDs (in etw-map.json).
HCSShim will append the default list of providers (if the annotation is not set to disable default log sources) with or without GUID depending on whether its WCOW or CWCOW respectively and send it in the ModifyServiceSettings message over the HCSShim-GCS bridge.
For CWCOW, the sidecar GCS will intercept the message with the list of providers, check it against the policy (implementation pending) and add the GUIDs by looking up the etw-map to the allowed providers before forwarding it to the inbox GCS within the UVM.
Annotations have been updated as per the design discussion and
wcowterm has been removed from the nomenclature.io.microsoft.virtualmachine.forwardlogs.disable": "Master Switch for Enabling Log Forwarding". Annotation to disable forwarding logs to the host,Defaults to false for (non-confidential) WCOW, meaning logs will be forwarded to the host if LogSources is set.
Defaults to true for C-WCOW confidential containers, meaning logs will not be forwarded to the host by default. "Master Switch for Enabling Log Forwarding"
io.microsoft.virtualmachine.forwardlogs.defaultsources.disable" - Specifies whether to disable default providers or not.Defaults to true.
The user no longer needs to add the default log sources as a base64 encoded json in an annotation. If the user needs to add custom sources, they can use the annotation below
io.microsoft.virtualmachine.forwardlogs.sources" : Customer defined log sources can be specified as base64 encoded json. Preferably without mentioning ProviderGUID, unless the Name-GUID mapping is not present in etw-map.jsonANNOTATIONS REMOVED
io.microsoft.virtualmachine.wcow.logsources"io.microsoft.virtualmachine.wcow.forwardlogs"Design
Confidential WCOW
A user will have to specify the log settings in the pod configuration using the annotations above, and in the security policy as well (so that the request from hcshim with the log settings is allowed/verified against)
Microsoft.HyperV.*)Workflow
io.microsoft.virtualmachine.forwardlogs.sources, if any, and from "default-log-sources.json" (unlessio.microsoft.virtualmachine.forwardlogs.defaultsources.disableis set totrue). NOTE: HCSShim will remove ProviderGUID if it has a match for its corresponding ProviderName in its own map etw-map.jsonModifyServiceSettingswith this "combined list" over the HCSShim-GCS bridge.ModifyServiceSettingsmessages meant for log forward service. Otherwise,UpdateLogSources()with the ApprovedList andincludeGuids=$trueto include the ProviderGUIDs and forward the request to inbox-GCSModifyServiceSettingsmessage for Starting the Log Forwarding, which the sidecar GCS will forward to inbox GCS if Boolean master switch is set. This gets propagated to LogForwardService and it then starts forwarding the events from the Log Sources to the HcsShim on the host over HvSocket.WCOW
Since sidecar-GCS is not present for WCOW, the flow skips the sidecar-GCS part and remains same otherwise.
A user will have to specify the log setting in the pod configuration using the annotations above.
Workflow
io.microsoft.virtualmachine.forwardlogs.sources, if any, and from "default-log-sources.json" (unlessio.microsoft.virtualmachine.forwardlogs.defaultsources.disableis set totrue). HCSShim will ADD ProviderGUIDs by looking up the etw-map.jsonModifyServiceSettingswith this "combined list including the GUIDs" over the HCSShim-GCS bridge.ModifyServiceSettingsmessage for Starting the Log Forwarding, which gets propagated similarly to LogForwardService and it then starts forwarding the events from the Log Sources to the HcsShim on the host over HvSocket.