-
Notifications
You must be signed in to change notification settings - Fork 362
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
Add packetcapture api #6257
base: main
Are you sure you want to change the base?
Add packetcapture api #6257
Conversation
efdfde8
to
1f9e3c5
Compare
moved API to this MR. Thanks you previous feedback and welcome to help review this again. @luolanzone @tnqn @jianjuns @antoninbas Accoding to #5821 (comment) . |
pkg/apis/crd/v1alpha1/types.go
Outdated
// SrcPort is the source port. | ||
SrcPort int32 `json:"srcPort,omitempty"` | ||
// DstPort is the destination port. | ||
DstPort int32 `json:"dstPort,omitempty"` |
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.
I don't know how @jianjuns and @tnqn will feel about this, but since this is a new API, I think we should follow the K8s convention:
Therefore, we ask that pointers always be used with optional fields that do not have a built-in nil value.
It tends to lead to a lot of pointers, but it makes it clearer what is optional and what is not. When creating a resource with YAML, it makes no difference. When creating a resource in Go, we can use ptr.To
from the K8s libraries to make initialization less verbose. What do you think?
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.
Agreed. There maybe a small problem if we upgrade to v1beta1 later to share the same structure with Traceflow though.
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.
I'd rather do the best interface possible now for PacketCapture
, and worry about unifying later.
If we have to introduce a new v1beta2
version for Traceflow, it should still be possible to define a conversion webhook to convert between v1beta1
and v1beta2
, because of the semantics of the field?
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.
updated. Can you help review this change? I'm not very sure if i have done it right.
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.
I think @antoninbas means:
type UDPHeader struct {
// SrcPort is the source port.
SrcPort *int32 `json:"srcPort,omitempty"`
// DstPort is the destination port.
DstPort *int32 `json:"dstPort,omitempty"`
}
because they are optional.
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.
Just saw newer comments. Please ignore it.
4b65b01
to
9567b89
Compare
pkg/apis/crd/v1alpha1/types.go
Outdated
// SrcPort is the source port. | ||
SrcPort int32 `json:"srcPort,omitempty"` | ||
// DstPort is the destination port. | ||
DstPort int32 `json:"dstPort,omitempty"` |
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.
I'd rather do the best interface possible now for PacketCapture
, and worry about unifying later.
If we have to introduce a new v1beta2
version for Traceflow, it should still be possible to define a conversion webhook to convert between v1beta1
and v1beta2
, because of the semantics of the field?
packet: | ||
type: object | ||
properties: |
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.
it looks like we are missing the srcIP
/ dstIP
properties here?
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.
it's actually not missed, since we have a Source
and Destination
field in spec
, so the srcIP/dstIP
is not used. The golang structure still keep these fields in the PR, but i think we can removed them. The whole Packet
structure has changed a lot during the review compared to the original one(==Traceflow's Packet strucuture).
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.
Updated this part. Currently the package related structure looks like this:
// Packet includes header info.
type Packet struct {
IPv6Header *IPv6Header `json:"ipv6Header,omitempty"`
TransportHeader TransportHeader `json:"transportHeader"`
}
Note: remove IPv4Header
as it's unused and in another thread, we are discussing if a IPFamily
field is needed.
Also in the TransportHeader
, we have tcp/icmp/udp strcuture to allow user filter based on transport attributes. For icmp, we don't have any filter yet, so the strucutre is mainly used as a type indicator.
type ICMPEchoRequestHeader struct {
}
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.
cc @jianjuns @tnqn @luolanzone
Can you help review this MR again? Thank you
I will be actively working on this recently.
9567b89
to
7d8d4b1
Compare
pkg/apis/crd/v1alpha1/types.go
Outdated
// Pod is the source pod. | ||
Pod string `json:"pod"` | ||
// IP is the source IPv4 or IPv6 address. | ||
IP *string `json:"ip,omitempty"` |
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.
Is this field mutually exclusive with Namespace
/ Pod
?
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.
not exactly. we don't have this kind of check now. This IP
field is used for Pod->IP
or IP->Pod
filter case.
The only requirement is that at least one pod is specified.
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.
So it would be valid to provide both a destination Pod and a destination IP (which don't match)?
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.
As long as there is one pod present(no matter whether it's in the source or destination), it will work(ignore the ip field in the same endpoint). I didn't add strict validation for the IP related case, not sure what's the best approach.
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.
since it's exclusive , i have added crd validation using oneOf
in the yaml. User cannot provide ip
and pod
both in the source/dest struct in there CR.
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.
@antoninbas found a little problem with this whole omitempty
thing.
Since i'm using oneOf
to perform some validation in the crd, so the related field need to be set to omitempty
wether they are pointer or value or not , or the validation will fail. (using yaml is fine, but golang struct is not, eg in tests code)
For example. If i want to use oneOf for source.ip/pod, means only one can be spcified. the following wont work
type Source struct {
Namespace string `json:"namespace"`
Pod string `json:"pod"`
IP string `json:"ip"`
}
spec: crdv1alpha1.PacketCaptureSpec{
Source: crdv1alpha1.Source{
Namespace: "test-namespace",
Pod: "test-pod",
},
since there is no omitempty
it's actually:
spec: crdv1alpha1.PacketCaptureSpec{
Source: crdv1alpha1.Source{
Namespace: "test-namespace",
Pod: "test-pod",
IP: "",
},
So the oneOf
validation will fail. The solution would be change every affected field (including pod
) to pointer + omitempty. or keep as value + omitempty. If not set, it won't show up.
Currently i kept the value format and add some of the omitempty
tag back, as change to pointer would require some changes on the current codebase. If you still felt this is needed ( > pointer), i can update this later.
Destination Destination `json:"destination"` | ||
Packet *Packet `json:"packet,omitempty"` | ||
// FileServer specifies the sftp url config for the fileServer. Captured packets will be uploaded to this server. | ||
FileServer BundleFileServer `json:"fileServer"` |
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.
I feel like we should have the option to write the pcap to a local file as well, just for ease of use / testing
Not everyone will want to have an ftp server for this
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.
So do you think keep the files in container is enough? Since this is not a cli, it would be odd to export the files to a location on the host.
If keep it in the container, filepath + container name should be ok?
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.
If keep it in the container, filepath + container name should be ok
Just filepath I think, the container will always be antrea-agent
? If users want the file to be on the Node, they can provide a path that is mounted from the host, such as /var/log/antrea
.
But there would need to be a way for users to figure out which antrea-agent Pod has the capture file, so that would need to be included in the Status. Are packets captured at the source or the destination or both?
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.
Both could happen, in the source or destination. pod name can be exposed in the status. Just need to think about the value format for the filepath field.
SrcPort *int32 `json:"srcPort,omitempty"` | ||
// DstPort is the destination port. | ||
DstPort *int32 `json:"dstPort,omitempty"` | ||
} | ||
|
||
// TCPHeader describes spec of a TCP header. | ||
type TCPHeader struct { | ||
// SrcPort is the source port. | ||
SrcPort *int32 `json:"srcPort,omitempty"` | ||
// DstPort is the destination port. | ||
DstPort *int32 `json:"dstPort,omitempty"` |
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.
I know I suggested pointers for this originally. Given more recent discussions, I don't really feel strongly about it anymore, so given that 0 is not a valid port number typically, I would be ok with removing the pointers. I'll let @tnqn chime in as well.
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.
temporary reset to int32 type.
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.
My first impression is this should have a pointer because it's optional. if header.SrcPort != nil
is the condition in which we should capture specifc source port only, right?
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.
yes, it's optional. sounds more reasonable to set it as pointer.
|
||
type PacketCapturePhase string | ||
|
||
const ( |
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.
Is it possible to share some types/constants with Traceflow?
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.
also see discussion #6257 (comment)
for the constants part i think it's unnecessary, each CRD may have more different status in the future.
About types, since Traceflow
is in vebeta1
now, are you suggesting we define some common types in neutral place?
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.
I am not sure if we should define common types across versions. Let us see if @tnqn and @antoninbas have an opinion.
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.
I guess in theory we could have common definitions in a neutral directory, it wouldn't need to be under apis/crd/<version>
. But if it's not a versioned directory, then we would have to be confident that they are not going to change.
K8s has meta/v1
with comm types, such as Time
. I don't know how good of an analogy it is.
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.
Except those meta types in meta/v1. K8s doesn't define common types across versions. If a constant needs to be used by a version, it will just be replicated in that version. I think it's to keep every version's stability and compatability. Otherwise a change in one version would have an impact on other versions.
@jianjuns Do you think we can add a ip family and ip protocol field? so we can remove ipv6header and icmpheader. |
That works for me, if you do not see a potential requirement to support other IP header fields, esp. v4 or v6 specific fields. |
updated. |
|
||
type PacketCapturePhase string | ||
|
||
const ( |
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.
I am not sure if we should define common types across versions. Let us see if @tnqn and @antoninbas have an opinion.
2c563b3
to
57f6640
Compare
pkg/apis/crd/v1alpha1/types.go
Outdated
// SrcPort is the source port. | ||
SrcPort int32 `json:"srcPort,omitempty"` | ||
// DstPort is the destination port. | ||
DstPort int32 `json:"dstPort,omitempty"` |
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.
I think @antoninbas means:
type UDPHeader struct {
// SrcPort is the source port.
SrcPort *int32 `json:"srcPort,omitempty"`
// DstPort is the destination port.
DstPort *int32 `json:"dstPort,omitempty"`
}
because they are optional.
|
||
type PacketCapturePhase string | ||
|
||
const ( |
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.
Except those meta types in meta/v1. K8s doesn't define common types across versions. If a constant needs to be used by a version, it will just be replicated in that version. I think it's to keep every version's stability and compatability. Otherwise a change in one version would have an impact on other versions.
Signed-off-by: Hang Yan <yhang@vmware.com>
7363edc
to
3ba4312
Compare
Any new comments? |
Add packetcapture's API changes.
For the full feature, please ref to:
#5821