Skip to content
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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

hangyan
Copy link
Member

@hangyan hangyan commented Apr 23, 2024

Add packetcapture's API changes.

For the full feature, please ref to:

#5821

@hangyan
Copy link
Member Author

hangyan commented Apr 23, 2024

moved API to this MR. Thanks you previous feedback and welcome to help review this again.

@luolanzone @tnqn @jianjuns @antoninbas

Accoding to #5821 (comment) . IPHeader field was removed.

@antoninbas antoninbas added api-review Categorizes an issue or PR as actively needing an API review. kind/api-change Categorizes issue or PR as related to adding, removing, or otherwise changing an API. labels Apr 23, 2024
pkg/apis/crd/v1alpha1/types.go Outdated Show resolved Hide resolved
pkg/apis/crd/v1alpha1/types.go Outdated Show resolved Hide resolved
pkg/apis/crd/v1alpha1/types.go Outdated Show resolved Hide resolved
pkg/apis/crd/v1alpha1/types.go Outdated Show resolved Hide resolved
pkg/apis/crd/v1alpha1/types.go Outdated Show resolved Hide resolved
pkg/apis/crd/v1alpha1/types.go Outdated Show resolved Hide resolved
pkg/apis/crd/v1alpha1/types.go Outdated Show resolved Hide resolved
Comment on lines 353 to 392
// SrcPort is the source port.
SrcPort int32 `json:"srcPort,omitempty"`
// DstPort is the destination port.
DstPort int32 `json:"dstPort,omitempty"`
Copy link
Contributor

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?

Copy link
Member Author

@hangyan hangyan May 14, 2024

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.

Copy link
Contributor

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?

Copy link
Member Author

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.

Copy link
Member

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.

Copy link
Member

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.

@antoninbas antoninbas added this to the Antrea v2.1 release milestone Apr 23, 2024
@luolanzone luolanzone added the action/release-note Indicates a PR that should be included in release notes. label May 7, 2024
pkg/apis/crd/v1alpha1/types.go Outdated Show resolved Hide resolved
pkg/apis/crd/v1alpha1/types.go Outdated Show resolved Hide resolved
@hangyan hangyan force-pushed the topic/yhang/packet-capture-api branch from 4b65b01 to 9567b89 Compare May 14, 2024 08:25
Comment on lines 353 to 392
// SrcPort is the source port.
SrcPort int32 `json:"srcPort,omitempty"`
// DstPort is the destination port.
DstPort int32 `json:"dstPort,omitempty"`
Copy link
Contributor

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?

pkg/apis/crd/v1alpha1/types.go Outdated Show resolved Hide resolved
Comment on lines 88 to 107
packet:
type: object
properties:
Copy link
Contributor

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?

Copy link
Member Author

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).

Copy link
Member Author

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 {
}

Copy link
Member Author

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.

pkg/apis/crd/v1alpha1/types.go Outdated Show resolved Hide resolved
// Pod is the source pod.
Pod string `json:"pod"`
// IP is the source IPv4 or IPv6 address.
IP *string `json:"ip,omitempty"`
Copy link
Contributor

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?

Copy link
Member Author

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.

Copy link
Contributor

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)?

Copy link
Member Author

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.

Copy link
Member Author

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.

Copy link
Member Author

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.

4ef7a4b

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.

pkg/apis/crd/v1alpha1/types.go Outdated Show resolved Hide resolved
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"`
Copy link
Contributor

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

Copy link
Member Author

@hangyan hangyan Aug 30, 2024

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?

Copy link
Contributor

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?

Copy link
Member Author

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.

Comment on lines +402 to +400
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"`
Copy link
Contributor

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.

Copy link
Member Author

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.

Copy link
Member

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?

Copy link
Member Author

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.

pkg/apis/crd/v1alpha1/types.go Outdated Show resolved Hide resolved
pkg/apis/crd/v1alpha1/types.go Outdated Show resolved Hide resolved

type PacketCapturePhase string

const (
Copy link
Contributor

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?

Copy link
Member Author

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?

Copy link
Contributor

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.

Copy link
Contributor

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.

Copy link
Member

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.

pkg/apis/crd/v1alpha1/types.go Outdated Show resolved Hide resolved
@hangyan
Copy link
Member Author

hangyan commented Aug 30, 2024

@jianjuns Do you think we can add a ip family and ip protocol field? so we can remove ipv6header and icmpheader.

@jianjuns
Copy link
Contributor

jianjuns commented Aug 30, 2024

@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.
And I meant to use intstr.IntOrString for protocol.

@hangyan
Copy link
Member Author

hangyan commented Sep 3, 2024

@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. And I meant to use intstr.IntOrString for protocol.

updated.

pkg/apis/crd/v1alpha1/types.go Outdated Show resolved Hide resolved
pkg/apis/crd/v1alpha1/types.go Outdated Show resolved Hide resolved

type PacketCapturePhase string

const (
Copy link
Contributor

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.

@hangyan hangyan force-pushed the topic/yhang/packet-capture-api branch 2 times, most recently from 2c563b3 to 57f6640 Compare September 6, 2024 07:29
build/charts/antrea/crds/packetcapture.yaml Outdated Show resolved Hide resolved
build/charts/antrea/crds/packetcapture.yaml Outdated Show resolved Hide resolved
pkg/apis/crd/v1alpha1/types.go Outdated Show resolved Hide resolved
pkg/apis/crd/v1alpha1/types.go Outdated Show resolved Hide resolved
Comment on lines 353 to 392
// SrcPort is the source port.
SrcPort int32 `json:"srcPort,omitempty"`
// DstPort is the destination port.
DstPort int32 `json:"dstPort,omitempty"`
Copy link
Member

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.

pkg/apis/crd/v1alpha1/types.go Outdated Show resolved Hide resolved

type PacketCapturePhase string

const (
Copy link
Member

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>
@hangyan hangyan force-pushed the topic/yhang/packet-capture-api branch from 7363edc to 3ba4312 Compare September 14, 2024 02:12
@hangyan
Copy link
Member Author

hangyan commented Sep 14, 2024

@antoninbas @jianjuns @tnqn

Any new comments?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
action/release-note Indicates a PR that should be included in release notes. api-review Categorizes an issue or PR as actively needing an API review. kind/api-change Categorizes issue or PR as related to adding, removing, or otherwise changing an API.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants