From abf9e3f6e23ad7002cfbffa3838b793eb57b55f2 Mon Sep 17 00:00:00 2001 From: Quan Tian Date: Fri, 29 Mar 2024 10:21:32 +0800 Subject: [PATCH] Optimize package organization to reduce antctl binary size (#6037) As a client, antctl needs to know some well-known resource names and the structs of the API responses. However, the code placement makes antctl import a lot of packages which are supposed to be consumed by server side code, e.g. antrea-controller, antrea-agent. This patch refactors relevant packages, extracts well-known resources names and API structs to separate common packages, mostly apis packages. It reduces antctl binary size by 10MB, from 55MB to 45MB. The placement also makes it more explicit that these constants and structs are API related and should be changed more carefully. The major changes are as follows: 1. Move well-known CRD resource names to types.go files which declare these CRD structs. 2. Move other well-known resource names to package pkg/apis. 3. Move structs of API responses to package apis of components which provide the corresponding APIs. Signed-off-by: Quan Tian --- cmd/antrea-agent/agent.go | 2 + cmd/antrea-controller/controller.go | 8 +- pkg/agent/apis/doc.go | 16 ++ pkg/agent/apis/types.go | 192 ++++++++++++++++++ pkg/agent/apiserver/apiserver.go | 10 +- pkg/agent/apiserver/apiserver_test.go | 28 +-- .../apiserver/handlers/agentinfo/handler.go | 55 +---- .../handlers/featuregates/handler.go | 12 +- .../handlers/featuregates/handler_test.go | 3 +- .../apiserver/handlers/memberlist/handler.go | 26 +-- .../handlers/memberlist/handler_test.go | 7 +- .../apiserver/handlers/multicast/handler.go | 29 +-- .../handlers/multicast/handler_test.go | 12 +- .../apiserver/handlers/ovsflows/handler.go | 63 ++---- .../handlers/ovsflows/handler_test.go | 17 +- .../apiserver/handlers/ovstracing/handler.go | 8 +- .../handlers/ovstracing/handler_test.go | 5 +- .../handlers/podinterface/handler.go | 42 +--- .../handlers/podinterface/handler_test.go | 25 +-- .../handlers/serviceexternalip/handler.go | 25 +-- pkg/agent/client.go | 9 +- .../serviceexternalip/controller.go | 7 +- .../serviceexternalip/controller_test.go | 10 +- pkg/antctl/antctl.go | 36 ++-- pkg/antctl/client.go | 10 +- pkg/antctl/output/output.go | 6 +- pkg/antctl/output/output_test.go | 34 ++-- pkg/antctl/raw/featuregates/command.go | 15 +- pkg/antctl/raw/helper.go | 18 +- pkg/antctl/raw/helper_test.go | 16 +- pkg/antctl/runtime/runtime.go | 4 +- pkg/antctl/transform/addressgroup/response.go | 5 +- .../transform/appliedtogroup/response.go | 3 +- pkg/antctl/transform/common/response.go | 50 ----- .../transform/controllerinfo/response.go | 9 +- .../transform/networkpolicy/response.go | 9 +- pkg/antctl/transform/ovstracing/response.go | 4 +- pkg/apis/crd/v1beta1/types.go | 14 ++ pkg/apis/paths.go | 20 ++ pkg/apis/resources.go | 31 +++ pkg/apiserver/apis/doc.go | 16 ++ pkg/apiserver/apis/types.go | 43 ++++ pkg/apiserver/apiserver.go | 9 +- .../certificate/cacert_controller.go | 9 +- .../certificate/cacert_controller_test.go | 10 +- pkg/apiserver/certificate/certificate.go | 12 -- pkg/apiserver/certificate/certificate_test.go | 2 +- pkg/apiserver/certificate/config.go | 6 - .../certificate/selfsignedcert_provider.go | 3 +- pkg/apiserver/handlers/endpoint/handler.go | 30 +-- .../handlers/endpoint/handler_test.go | 11 +- .../handlers/featuregates/handler.go | 24 +-- .../handlers/featuregates/handler_test.go | 15 +- .../registry/system/controllerinfo/rest.go | 5 +- .../system/controllerinfo/rest_test.go | 6 +- .../networkpolicy/antreanetworkpolicy_test.go | 21 +- .../networkpolicy/clustergroup_test.go | 5 +- .../clusternetworkpolicy_test.go | 49 ++--- pkg/controller/networkpolicy/crd_utils.go | 4 +- .../networkpolicy/endpoint_querier.go | 4 +- .../networkpolicy/endpoint_querier_test.go | 43 ++-- .../networkpolicy_controller_test.go | 16 +- pkg/controller/networkpolicy/tier.go | 11 +- pkg/flowaggregator/apis/doc.go | 16 ++ pkg/flowaggregator/apis/types.go | 87 ++++++++ pkg/flowaggregator/apiserver/apiserver.go | 7 +- .../apiserver/handlers/flowrecords/handler.go | 44 +--- .../handlers/flowrecords/handler_test.go | 21 +- .../handlers/recordmetrics/handler.go | 37 +--- .../handlers/recordmetrics/handler_test.go | 5 +- pkg/monitor/agent_test.go | 1 + pkg/monitor/controller.go | 5 +- pkg/monitor/controller_test.go | 1 + pkg/querier/querier.go | 12 +- pkg/util/k8s/name.go | 7 + pkg/util/printers/table.go | 55 +++++ test/e2e/antreapolicy_test.go | 4 +- test/e2e/basic_test.go | 4 +- test/e2e/flowaggregator_test.go | 4 +- test/e2e/networkpolicy_test.go | 4 +- test/e2e/security_test.go | 10 +- test/e2e/service_externalip_test.go | 4 +- test/e2e/supportbundle_test.go | 8 +- 83 files changed, 864 insertions(+), 721 deletions(-) create mode 100644 pkg/agent/apis/doc.go create mode 100644 pkg/agent/apis/types.go create mode 100644 pkg/apis/paths.go create mode 100644 pkg/apis/resources.go create mode 100644 pkg/apiserver/apis/doc.go create mode 100644 pkg/apiserver/apis/types.go create mode 100644 pkg/flowaggregator/apis/doc.go create mode 100644 pkg/flowaggregator/apis/types.go create mode 100644 pkg/util/printers/table.go diff --git a/cmd/antrea-agent/agent.go b/cmd/antrea-agent/agent.go index a912db846a6..3678b665fc7 100644 --- a/cmd/antrea-agent/agent.go +++ b/cmd/antrea-agent/agent.go @@ -66,6 +66,7 @@ import ( "antrea.io/antrea/pkg/agent/stats" support "antrea.io/antrea/pkg/agent/supportbundlecollection" agenttypes "antrea.io/antrea/pkg/agent/types" + "antrea.io/antrea/pkg/apis" "antrea.io/antrea/pkg/apis/controlplane" crdinformers "antrea.io/antrea/pkg/client/informers/externalversions" crdv1alpha1informers "antrea.io/antrea/pkg/client/informers/externalversions/crd/v1alpha1" @@ -895,6 +896,7 @@ func run(o *Options) error { authorization, *o.config.EnablePrometheusMetrics, o.config.ClientConnection.Kubeconfig, + apis.APIServerLoopbackTokenPath, v4Enabled, v6Enabled) if err != nil { diff --git a/cmd/antrea-controller/controller.go b/cmd/antrea-controller/controller.go index 5e3f041f50e..00d51e1f193 100644 --- a/cmd/antrea-controller/controller.go +++ b/cmd/antrea-controller/controller.go @@ -40,7 +40,7 @@ import ( policyv1a1informers "sigs.k8s.io/network-policy-api/pkg/client/informers/externalversions" mcinformers "antrea.io/antrea/multicluster/pkg/client/informers/externalversions" - antreaapis "antrea.io/antrea/pkg/apis" + "antrea.io/antrea/pkg/apis" "antrea.io/antrea/pkg/apiserver" "antrea.io/antrea/pkg/apiserver/certificate" "antrea.io/antrea/pkg/apiserver/openapi" @@ -238,7 +238,7 @@ func run(o *Options) error { var csrLister csrlisters.CertificateSigningRequestLister if features.DefaultFeatureGate.Enabled(features.IPsecCertAuth) { csrInformer = csrinformers.NewFilteredCertificateSigningRequestInformer(client, 0, nil, func(listOptions *metav1.ListOptions) { - listOptions.FieldSelector = fields.OneTermEqualSelector("spec.signerName", antreaapis.AntreaIPsecCSRSignerName).String() + listOptions.FieldSelector = fields.OneTermEqualSelector("spec.signerName", apis.AntreaIPsecCSRSignerName).String() }) csrLister = csrlisters.NewCertificateSigningRequestLister(csrInformer.GetIndexer()) @@ -533,10 +533,10 @@ func createAPIServerConfig(kubeconfig string, return nil, err } - if err := os.MkdirAll(path.Dir(apiserver.TokenPath), os.ModeDir); err != nil { + if err := os.MkdirAll(path.Dir(apis.APIServerLoopbackTokenPath), os.ModeDir); err != nil { return nil, fmt.Errorf("error when creating dirs of token file: %v", err) } - if err := os.WriteFile(apiserver.TokenPath, []byte(serverConfig.LoopbackClientConfig.BearerToken), 0600); err != nil { + if err := os.WriteFile(apis.APIServerLoopbackTokenPath, []byte(serverConfig.LoopbackClientConfig.BearerToken), 0600); err != nil { return nil, fmt.Errorf("error when writing loopback access token to file: %v", err) } serverConfig.OpenAPIConfig = genericapiserver.DefaultOpenAPIConfig( diff --git a/pkg/agent/apis/doc.go b/pkg/agent/apis/doc.go new file mode 100644 index 00000000000..fe1eec6c6eb --- /dev/null +++ b/pkg/agent/apis/doc.go @@ -0,0 +1,16 @@ +// Copyright 2024 Antrea Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package apis contains API definitions used to interface with antrea-agent. +package apis diff --git a/pkg/agent/apis/types.go b/pkg/agent/apis/types.go new file mode 100644 index 00000000000..70cd8875b88 --- /dev/null +++ b/pkg/agent/apis/types.go @@ -0,0 +1,192 @@ +// Copyright 2024 Antrea Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package apis + +import ( + "strconv" + "strings" + + corev1 "k8s.io/api/core/v1" + + "antrea.io/antrea/pkg/apis/crd/v1beta1" + "antrea.io/antrea/pkg/util/printers" +) + +// AntreaAgentInfoResponse is the struct for the response of agentinfo command. +// It includes all fields except meta info from v1beta1.AntreaAgentInfo struct. +type AntreaAgentInfoResponse struct { + Version string `json:"version,omitempty"` // Antrea binary version + PodRef corev1.ObjectReference `json:"podRef,omitempty"` // The Pod that Antrea Agent is running in + NodeRef corev1.ObjectReference `json:"nodeRef,omitempty"` // The Node that Antrea Agent is running in + NodeSubnets []string `json:"nodeSubnets,omitempty"` // Node subnets + OVSInfo v1beta1.OVSInfo `json:"ovsInfo,omitempty"` // OVS Information + NetworkPolicyControllerInfo v1beta1.NetworkPolicyControllerInfo `json:"networkPolicyControllerInfo,omitempty"` // Antrea Agent NetworkPolicy information + LocalPodNum int32 `json:"localPodNum,omitempty"` // The number of Pods which the agent is in charge of + AgentConditions []v1beta1.AgentCondition `json:"agentConditions,omitempty"` // Agent condition contains types like AgentHealthy +} + +func (r AntreaAgentInfoResponse) GetTableHeader() []string { + return []string{"POD", "NODE", "STATUS", "NODE-SUBNET", "NETWORK-POLICIES", "ADDRESS-GROUPS", "APPLIED-TO-GROUPS", "LOCAL-PODS"} +} + +func (r AntreaAgentInfoResponse) getAgentConditionStr() string { + if r.AgentConditions == nil { + return "" + } + agentCondition := "Healthy" + for _, cond := range r.AgentConditions { + if cond.Status == corev1.ConditionUnknown { + agentCondition = "Unknown" + } + if cond.Status == corev1.ConditionFalse { + return "Unhealthy" + } + } + return agentCondition +} + +func (r AntreaAgentInfoResponse) GetTableRow(maxColumnLength int) []string { + return []string{r.PodRef.Namespace + "/" + r.PodRef.Name, + r.NodeRef.Name, + r.getAgentConditionStr(), + printers.GenerateTableElementWithSummary(r.NodeSubnets, maxColumnLength), + strconv.Itoa(int(r.NetworkPolicyControllerInfo.NetworkPolicyNum)), + strconv.Itoa(int(r.NetworkPolicyControllerInfo.AddressGroupNum)), + strconv.Itoa(int(r.NetworkPolicyControllerInfo.AppliedToGroupNum)), + strconv.Itoa(int(r.LocalPodNum))} +} + +func (r AntreaAgentInfoResponse) SortRows() bool { + return true +} + +type FeatureGateResponse struct { + Component string `json:"component,omitempty"` + Name string `json:"name,omitempty"` + Status string `json:"status,omitempty"` + Version string `json:"version,omitempty"` +} + +// MemberlistResponse describes the response struct of memberlist command. +type MemberlistResponse struct { + NodeName string `json:"nodeName,omitempty"` + IP string `json:"ip,omitempty"` + Status string `json:"status,omitempty"` +} + +func (r MemberlistResponse) GetTableHeader() []string { + return []string{"NODE", "IP", "STATUS"} +} + +func (r MemberlistResponse) GetTableRow(_ int) []string { + return []string{r.NodeName, r.IP, r.Status} +} + +func (r MemberlistResponse) SortRows() bool { + return true +} + +type MulticastResponse struct { + PodName string `json:"name,omitempty" antctl:"name,Name of the Pod"` + PodNamespace string `json:"podNamespace,omitempty"` + Inbound string `json:"inbound,omitempty"` + Outbound string `json:"outbound,omitempty"` +} + +func (r MulticastResponse) GetTableHeader() []string { + return []string{"NAMESPACE", "NAME", "INBOUND", "OUTBOUND"} +} + +func (r MulticastResponse) GetTableRow(_ int) []string { + return []string{r.PodNamespace, r.PodName, r.Inbound, r.Outbound} +} + +func (r MulticastResponse) SortRows() bool { + return true +} + +// OVSFlowResponse is the response struct of ovsflows command. +type OVSFlowResponse struct { + Flow string `json:"flow,omitempty"` +} + +func (r OVSFlowResponse) GetTableHeader() []string { + return []string{""} +} + +func (r OVSFlowResponse) GetTableRow(maxColumnLength int) []string { + return []string{r.Flow} +} + +func (r OVSFlowResponse) SortRows() bool { + return false +} + +// OVSTracingResponse is the response struct of ovstracing command. +type OVSTracingResponse struct { + Result string `json:"result,omitempty"` +} + +// PodInterfaceResponse describes the response struct of pod-interface command. +type PodInterfaceResponse struct { + PodName string `json:"name,omitempty" antctl:"name,Name of the Pod"` + PodNamespace string `json:"podNamespace,omitempty"` + InterfaceName string `json:"interfaceName,omitempty"` + IPs []string `json:"ips,omitempty"` + MAC string `json:"mac,omitempty"` + PortUUID string `json:"portUUID,omitempty"` + OFPort int32 `json:"ofPort,omitempty"` + ContainerID string `json:"containerID,omitempty"` +} + +func (r PodInterfaceResponse) GetTableHeader() []string { + return []string{"NAMESPACE", "NAME", "INTERFACE-NAME", "IP", "MAC", "PORT-UUID", "OF-PORT", "CONTAINER-ID"} +} + +func (r PodInterfaceResponse) getContainerIDStr() string { + if len(r.ContainerID) > 12 { + return r.ContainerID[0:11] + } + return r.ContainerID +} + +func (r PodInterfaceResponse) GetTableRow(_ int) []string { + return []string{r.PodNamespace, r.PodName, r.InterfaceName, strings.Join(r.IPs, ", "), r.MAC, r.PortUUID, strconv.Itoa(int(r.OFPort)), r.getContainerIDStr()} +} + +func (r PodInterfaceResponse) SortRows() bool { + return true +} + +// ServiceExternalIPInfo contains the essential information for Services with type of Loadbalancer managed by Antrea. +type ServiceExternalIPInfo struct { + ServiceName string `json:"serviceName,omitempty" antctl:"name,Name of the Service"` + Namespace string `json:"namespace,omitempty"` + ExternalIP string `json:"externalIP,omitempty"` + ExternalIPPool string `json:"externalIPPool,omitempty"` + AssignedNode string `json:"assignedNode,omitempty"` +} + +func (r ServiceExternalIPInfo) GetTableHeader() []string { + return []string{"NAMESPACE", "NAME", "EXTERNAL-IP-POOL", "EXTERNAL-IP", "ASSIGNED-NODE"} +} + +func (r ServiceExternalIPInfo) GetTableRow(_ int) []string { + return []string{r.Namespace, r.ServiceName, r.ExternalIPPool, r.ExternalIP, r.AssignedNode} +} + +func (r ServiceExternalIPInfo) SortRows() bool { + return true +} diff --git a/pkg/agent/apiserver/apiserver.go b/pkg/agent/apiserver/apiserver.go index ab16057f9cb..e19c5c6acef 100644 --- a/pkg/agent/apiserver/apiserver.go +++ b/pkg/agent/apiserver/apiserver.go @@ -60,8 +60,6 @@ const CertPairName = "antrea-agent-api" var ( scheme = runtime.NewScheme() codecs = serializer.NewCodecFactory(scheme) - // #nosec G101: false positive triggered by variable name which includes "token" - TokenPath = "/var/run/antrea/apiserver/loopback-client-token" ) func init() { @@ -121,10 +119,11 @@ func New(aq agentquerier.AgentQuerier, authorization *genericoptions.DelegatingAuthorizationOptions, enableMetrics bool, kubeconfig string, + loopbackClientTokenPath string, v4Enabled, v6Enabled bool, ) (*agentAPIServer, error) { - cfg, err := newConfig(aq, npq, secureServing, authentication, authorization, enableMetrics, kubeconfig) + cfg, err := newConfig(aq, npq, secureServing, authentication, authorization, enableMetrics, kubeconfig, loopbackClientTokenPath) if err != nil { return nil, err } @@ -146,6 +145,7 @@ func newConfig(aq agentquerier.AgentQuerier, authorization *genericoptions.DelegatingAuthorizationOptions, enableMetrics bool, kubeconfig string, + loopbackClientTokenPath string, ) (*genericapiserver.CompletedConfig, error) { // kubeconfig file is useful when antrea-agent isn't running as a Pod. if len(kubeconfig) > 0 { @@ -170,10 +170,10 @@ func newConfig(aq agentquerier.AgentQuerier, if err := authorization.ApplyTo(&serverConfig.Authorization); err != nil { return nil, err } - if err := os.MkdirAll(path.Dir(TokenPath), os.ModeDir); err != nil { + if err := os.MkdirAll(path.Dir(loopbackClientTokenPath), os.ModeDir); err != nil { return nil, fmt.Errorf("error when creating dirs of token file: %v", err) } - if err := os.WriteFile(TokenPath, []byte(serverConfig.LoopbackClientConfig.BearerToken), 0600); err != nil { + if err := os.WriteFile(loopbackClientTokenPath, []byte(serverConfig.LoopbackClientConfig.BearerToken), 0600); err != nil { return nil, fmt.Errorf("error when writing loopback access token to file: %v", err) } v := antreaversion.GetVersion() diff --git a/pkg/agent/apiserver/apiserver_test.go b/pkg/agent/apiserver/apiserver_test.go index 7600dc64aea..0cc37c222f4 100644 --- a/pkg/agent/apiserver/apiserver_test.go +++ b/pkg/agent/apiserver/apiserver_test.go @@ -19,6 +19,7 @@ import ( "net/http" "net/http/httptest" "os" + "path/filepath" "sync" "testing" "time" @@ -44,15 +45,9 @@ type fakeAgentAPIServer struct { } func newFakeAPIServer(t *testing.T) *fakeAgentAPIServer { - kubeConfigFile, err := os.CreateTemp("", "kubeconfig") - if err != nil { - t.Fatal(err) - } - defer func() { - kubeConfigFile.Close() - os.Remove(kubeConfigFile.Name()) - }() - if _, err := kubeConfigFile.Write([]byte(` + tempDir := t.TempDir() + kubeConfigPath := filepath.Join(tempDir, "kubeconfig") + kubeConfigContent := ` apiVersion: v1 kind: Config clusters: @@ -64,18 +59,11 @@ contexts: cluster: cluster name: cluster current-context: cluster -`)); err != nil { +` + if err := os.WriteFile(kubeConfigPath, []byte(kubeConfigContent), 0600); err != nil { t.Fatal(err) } - originalTokenPath := TokenPath - tokenFile, err := os.CreateTemp("", "token") - require.NoError(t, err) - TokenPath = tokenFile.Name() - defer func() { - TokenPath = originalTokenPath - tokenFile.Close() - os.Remove(tokenFile.Name()) - }() + tokenPath := filepath.Join(tempDir, "token") version.Version = "v1.2.3" ctrl := gomock.NewController(t) agentQuerier := aqtest.NewMockAgentQuerier(ctrl) @@ -91,7 +79,7 @@ current-context: cluster // InClusterLookup is skipped when testing, otherwise it would always fail as there is no real cluster. authentication.SkipInClusterLookup = true authorization := options.NewDelegatingAuthorizationOptions().WithAlwaysAllowPaths("/healthz", "/livez", "/readyz") - apiServer, err := New(agentQuerier, npQuerier, nil, nil, secureServing, authentication, authorization, true, kubeConfigFile.Name(), true, true) + apiServer, err := New(agentQuerier, npQuerier, nil, nil, secureServing, authentication, authorization, true, kubeConfigPath, tokenPath, true, true) require.NoError(t, err) fakeAPIServer := &fakeAgentAPIServer{ agentAPIServer: apiServer, diff --git a/pkg/agent/apiserver/handlers/agentinfo/handler.go b/pkg/agent/apiserver/handlers/agentinfo/handler.go index 2580fe18b73..502a7e63fe0 100644 --- a/pkg/agent/apiserver/handlers/agentinfo/handler.go +++ b/pkg/agent/apiserver/handlers/agentinfo/handler.go @@ -18,34 +18,20 @@ import ( "encoding/json" "net/http" - corev1 "k8s.io/api/core/v1" "k8s.io/klog/v2" + "antrea.io/antrea/pkg/agent/apis" "antrea.io/antrea/pkg/agent/querier" - "antrea.io/antrea/pkg/antctl/transform/common" "antrea.io/antrea/pkg/apis/crd/v1beta1" ) -// AntreaAgentInfoResponse is the struct for the response of agentinfo command. -// It includes all fields except meta info from v1beta1.AntreaAgentInfo struct. -type AntreaAgentInfoResponse struct { - Version string `json:"version,omitempty"` // Antrea binary version - PodRef corev1.ObjectReference `json:"podRef,omitempty"` // The Pod that Antrea Agent is running in - NodeRef corev1.ObjectReference `json:"nodeRef,omitempty"` // The Node that Antrea Agent is running in - NodeSubnets []string `json:"nodeSubnets,omitempty"` // Node subnets - OVSInfo v1beta1.OVSInfo `json:"ovsInfo,omitempty"` // OVS Information - NetworkPolicyControllerInfo v1beta1.NetworkPolicyControllerInfo `json:"networkPolicyControllerInfo,omitempty"` // Antrea Agent NetworkPolicy information - LocalPodNum int32 `json:"localPodNum,omitempty"` // The number of Pods which the agent is in charge of - AgentConditions []v1beta1.AgentCondition `json:"agentConditions,omitempty"` // Agent condition contains types like AgentHealthy -} - // HandleFunc returns the function which can handle queries issued by agentinfo commands. // The handler function populates Antrea agent information to the response. func HandleFunc(aq querier.AgentQuerier) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { agentInfo := new(v1beta1.AntreaAgentInfo) aq.GetAgentInfo(agentInfo, false) - info := &AntreaAgentInfoResponse{ + info := &apis.AntreaAgentInfoResponse{ Version: agentInfo.Version, PodRef: agentInfo.PodRef, NodeRef: agentInfo.NodeRef, @@ -62,40 +48,3 @@ func HandleFunc(aq querier.AgentQuerier) http.HandlerFunc { } } } - -var _ common.TableOutput = new(AntreaAgentInfoResponse) - -func (r AntreaAgentInfoResponse) GetTableHeader() []string { - return []string{"POD", "NODE", "STATUS", "NODE-SUBNET", "NETWORK-POLICIES", "ADDRESS-GROUPS", "APPLIED-TO-GROUPS", "LOCAL-PODS"} -} - -func (r AntreaAgentInfoResponse) GetAgentConditionStr() string { - if r.AgentConditions == nil { - return "" - } - agentCondition := "Healthy" - for _, cond := range r.AgentConditions { - if cond.Status == corev1.ConditionUnknown { - agentCondition = "Unknown" - } - if cond.Status == corev1.ConditionFalse { - return "Unhealthy" - } - } - return agentCondition -} - -func (r AntreaAgentInfoResponse) GetTableRow(maxColumnLength int) []string { - return []string{r.PodRef.Namespace + "/" + r.PodRef.Name, - r.NodeRef.Name, - r.GetAgentConditionStr(), - common.GenerateTableElementWithSummary(r.NodeSubnets, maxColumnLength), - common.Int32ToString(r.NetworkPolicyControllerInfo.NetworkPolicyNum), - common.Int32ToString(r.NetworkPolicyControllerInfo.AddressGroupNum), - common.Int32ToString(r.NetworkPolicyControllerInfo.AppliedToGroupNum), - common.Int32ToString(r.LocalPodNum)} -} - -func (r AntreaAgentInfoResponse) SortRows() bool { - return true -} diff --git a/pkg/agent/apiserver/handlers/featuregates/handler.go b/pkg/agent/apiserver/handlers/featuregates/handler.go index be8049d6dd0..6ff60bad949 100644 --- a/pkg/agent/apiserver/handlers/featuregates/handler.go +++ b/pkg/agent/apiserver/handlers/featuregates/handler.go @@ -21,24 +21,18 @@ import ( "k8s.io/klog/v2" + "antrea.io/antrea/pkg/agent/apis" "antrea.io/antrea/pkg/features" ) -type Response struct { - Component string `json:"component,omitempty"` - Name string `json:"name,omitempty"` - Status string `json:"status,omitempty"` - Version string `json:"version,omitempty"` -} - // HandleFunc returns the function which can handle queries issued by 'antctl get featuregates' command. // The handler function populates Antrea Agent feature gates information to the response. func HandleFunc() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - var featureGates []Response + var featureGates []apis.FeatureGateResponse for df := range features.DefaultAntreaFeatureGates { if features.AgentGates.Has(df) { - featureGates = append(featureGates, Response{ + featureGates = append(featureGates, apis.FeatureGateResponse{ Component: "agent", Name: string(df), Status: features.GetStatus(features.DefaultFeatureGate.Enabled(df)), diff --git a/pkg/agent/apiserver/handlers/featuregates/handler_test.go b/pkg/agent/apiserver/handlers/featuregates/handler_test.go index 4b57408f9bc..207d606da76 100644 --- a/pkg/agent/apiserver/handlers/featuregates/handler_test.go +++ b/pkg/agent/apiserver/handlers/featuregates/handler_test.go @@ -24,6 +24,7 @@ import ( "github.com/stretchr/testify/require" "k8s.io/component-base/featuregate" + "antrea.io/antrea/pkg/agent/apis" "antrea.io/antrea/pkg/features" ) @@ -41,7 +42,7 @@ func TestHandleFunc(t *testing.T) { handler.ServeHTTP(recorder, req) require.Equal(t, http.StatusOK, recorder.Code) - var resp []Response + var resp []apis.FeatureGateResponse err = json.Unmarshal(recorder.Body.Bytes(), &resp) require.Nil(t, err) diff --git a/pkg/agent/apiserver/handlers/memberlist/handler.go b/pkg/agent/apiserver/handlers/memberlist/handler.go index ddfe6127385..04c4f85e975 100644 --- a/pkg/agent/apiserver/handlers/memberlist/handler.go +++ b/pkg/agent/apiserver/handlers/memberlist/handler.go @@ -24,22 +24,16 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "k8s.io/klog/v2" + "antrea.io/antrea/pkg/agent/apis" "antrea.io/antrea/pkg/agent/querier" ) -// Response describes the response struct of memberlist command. -type Response struct { - NodeName string `json:"nodeName,omitempty"` - IP string `json:"ip,omitempty"` - Status string `json:"status,omitempty"` -} - -func generateResponse(node *v1.Node, aliveNodes sets.Set[string]) Response { +func generateResponse(node *v1.Node, aliveNodes sets.Set[string]) apis.MemberlistResponse { status := "Dead" if aliveNodes.Has(node.Name) { status = "Alive" } - return Response{ + return apis.MemberlistResponse{ NodeName: node.Name, Status: status, IP: node.Status.Addresses[0].Address, @@ -55,7 +49,7 @@ func HandleFunc(aq querier.AgentQuerier) http.HandlerFunc { http.Error(w, "memberlist is not enabled", http.StatusServiceUnavailable) return } - var memberlist []Response + var memberlist []apis.MemberlistResponse allNodes, _ := aq.GetNodeLister().List(labels.Everything()) aliveNodes := memberlistCluster.AliveNodes() for _, node := range allNodes { @@ -69,15 +63,3 @@ func HandleFunc(aq querier.AgentQuerier) http.HandlerFunc { } } } - -func (r Response) GetTableHeader() []string { - return []string{"NODE", "IP", "STATUS"} -} - -func (r Response) GetTableRow(_ int) []string { - return []string{r.NodeName, r.IP, r.Status} -} - -func (r Response) SortRows() bool { - return true -} diff --git a/pkg/agent/apiserver/handlers/memberlist/handler_test.go b/pkg/agent/apiserver/handlers/memberlist/handler_test.go index ff62d75092a..885ba852805 100644 --- a/pkg/agent/apiserver/handlers/memberlist/handler_test.go +++ b/pkg/agent/apiserver/handlers/memberlist/handler_test.go @@ -30,6 +30,7 @@ import ( "k8s.io/client-go/kubernetes/fake" corelisters "k8s.io/client-go/listers/core/v1" + "antrea.io/antrea/pkg/agent/apis" "antrea.io/antrea/pkg/agent/memberlist" memberlisttest "antrea.io/antrea/pkg/agent/memberlist/testing" queriertest "antrea.io/antrea/pkg/agent/querier/testing" @@ -75,7 +76,7 @@ func TestMemberlistQuery(t *testing.T) { memberlistInterface func(*gomock.Controller) memberlist.Interface nodeLister corelisters.NodeLister expectedStatus int - expectedResponse []Response + expectedResponse []apis.MemberlistResponse }{ { name: "memberlist not running", @@ -95,7 +96,7 @@ func TestMemberlistQuery(t *testing.T) { }, nodeLister: nodeLister, expectedStatus: http.StatusOK, - expectedResponse: []Response{ + expectedResponse: []apis.MemberlistResponse{ { NodeName: "node1", IP: "172.16.0.11", @@ -128,7 +129,7 @@ func TestMemberlistQuery(t *testing.T) { assert.Equal(t, tt.expectedStatus, recorder.Code) if tt.expectedStatus == http.StatusOK { - var received []Response + var received []apis.MemberlistResponse err = json.Unmarshal(recorder.Body.Bytes(), &received) require.NoError(t, err) assert.ElementsMatch(t, tt.expectedResponse, received) diff --git a/pkg/agent/apiserver/handlers/multicast/handler.go b/pkg/agent/apiserver/handlers/multicast/handler.go index 0bd891e4fc4..25658372ada 100644 --- a/pkg/agent/apiserver/handlers/multicast/handler.go +++ b/pkg/agent/apiserver/handlers/multicast/handler.go @@ -20,20 +20,13 @@ import ( "reflect" "strconv" + "antrea.io/antrea/pkg/agent/apis" "antrea.io/antrea/pkg/agent/multicast" - "antrea.io/antrea/pkg/antctl/transform/common" "antrea.io/antrea/pkg/querier" ) -type Response struct { - PodName string `json:"name,omitempty" antctl:"name,Name of the Pod"` - PodNamespace string `json:"podNamespace,omitempty"` - Inbound string `json:"inbound,omitempty"` - Outbound string `json:"outbound,omitempty"` -} - -func generateResponse(podName string, podNamespace string, trafficStats *multicast.PodTrafficStats) Response { - return Response{ +func generateResponse(podName string, podNamespace string, trafficStats *multicast.PodTrafficStats) apis.MulticastResponse { + return apis.MulticastResponse{ PodName: podName, PodNamespace: podNamespace, Inbound: strconv.FormatUint(trafficStats.Inbound, 10), @@ -52,7 +45,7 @@ func HandleFunc(mq querier.AgentMulticastInfoQuerier) http.HandlerFunc { name := r.URL.Query().Get("name") ns := r.URL.Query().Get("namespace") - responses := []Response{} + responses := []apis.MulticastResponse{} if name != "" && ns != "" { podStats := mq.GetPodStats(name, ns) if podStats == nil { @@ -78,17 +71,3 @@ func HandleFunc(mq querier.AgentMulticastInfoQuerier) http.HandlerFunc { } } } - -var _ common.TableOutput = new(Response) - -func (r Response) GetTableHeader() []string { - return []string{"NAMESPACE", "NAME", "INBOUND", "OUTBOUND"} -} - -func (r Response) GetTableRow(_ int) []string { - return []string{r.PodNamespace, r.PodName, r.Inbound, r.Outbound} -} - -func (r Response) SortRows() bool { - return true -} diff --git a/pkg/agent/apiserver/handlers/multicast/handler_test.go b/pkg/agent/apiserver/handlers/multicast/handler_test.go index 31da2b9fa7b..41647d3600b 100644 --- a/pkg/agent/apiserver/handlers/multicast/handler_test.go +++ b/pkg/agent/apiserver/handlers/multicast/handler_test.go @@ -24,10 +24,10 @@ import ( "github.com/stretchr/testify/assert" "go.uber.org/mock/gomock" + "antrea.io/antrea/pkg/agent/apis" "antrea.io/antrea/pkg/agent/interfacestore" "antrea.io/antrea/pkg/agent/multicast" "antrea.io/antrea/pkg/features" - queriertest "antrea.io/antrea/pkg/querier/testing" ) @@ -40,7 +40,7 @@ func TestPodMulticastStatsQuery(t *testing.T) { name string namespace string expectedStatus int - expectedContent []Response + expectedContent []apis.MulticastResponse getPodStatsResult *multicast.PodTrafficStats gettAllPodsStatsResult map[*interfacestore.InterfaceConfig]*multicast.PodTrafficStats }{ @@ -48,7 +48,7 @@ func TestPodMulticastStatsQuery(t *testing.T) { name: "pod1", namespace: "namespaceA", expectedStatus: http.StatusOK, - expectedContent: []Response{ + expectedContent: []apis.MulticastResponse{ { PodName: "pod1", PodNamespace: "namespaceA", @@ -77,7 +77,7 @@ func TestPodMulticastStatsQuery(t *testing.T) { {ContainerInterfaceConfig: &interfacestore.ContainerInterfaceConfig{PodName: "pod1", PodNamespace: "test1"}}: {Inbound: 22, Outbound: 33}, {ContainerInterfaceConfig: &interfacestore.ContainerInterfaceConfig{PodName: "pod2", PodNamespace: "namespaceA"}}: {Inbound: 44, Outbound: 69}, }, - expectedContent: []Response{ + expectedContent: []apis.MulticastResponse{ { PodName: "pod2", PodNamespace: "namespaceA", @@ -94,7 +94,7 @@ func TestPodMulticastStatsQuery(t *testing.T) { {ContainerInterfaceConfig: &interfacestore.ContainerInterfaceConfig{PodName: "pod1", PodNamespace: "test1"}}: {Inbound: 22, Outbound: 33}, {ContainerInterfaceConfig: &interfacestore.ContainerInterfaceConfig{PodName: "pod2", PodNamespace: "test2"}}: {Inbound: 44, Outbound: 66}, }, - expectedContent: []Response{ + expectedContent: []apis.MulticastResponse{ { PodName: "pod1", PodNamespace: "test1", @@ -125,7 +125,7 @@ func TestPodMulticastStatsQuery(t *testing.T) { assert.Equal(t, tc.expectedStatus, recorder.Code, k) if tc.expectedStatus == http.StatusOK { - var received []Response + var received []apis.MulticastResponse err = json.Unmarshal(recorder.Body.Bytes(), &received) assert.Nil(t, err) assert.ElementsMatch(t, tc.expectedContent, received) diff --git a/pkg/agent/apiserver/handlers/ovsflows/handler.go b/pkg/agent/apiserver/handlers/ovsflows/handler.go index 2ae2d777f8a..22c3b46f07d 100644 --- a/pkg/agent/apiserver/handlers/ovsflows/handler.go +++ b/pkg/agent/apiserver/handlers/ovsflows/handler.go @@ -23,9 +23,9 @@ import ( "k8s.io/klog/v2" + "antrea.io/antrea/pkg/agent/apis" "antrea.io/antrea/pkg/agent/openflow" agentquerier "antrea.io/antrea/pkg/agent/querier" - "antrea.io/antrea/pkg/antctl/transform/common" binding "antrea.io/antrea/pkg/ovs/openflow" "antrea.io/antrea/pkg/querier" ) @@ -37,13 +37,8 @@ var ( getFlowTableList = openflow.GetTableList ) -// Response is the response struct of ovsflows command. -type Response struct { - Flow string `json:"flow,omitempty"` -} - -func dumpMatchedFlows(aq agentquerier.AgentQuerier, flowKeys []string) ([]Response, error) { - resps := []Response{} +func dumpMatchedFlows(aq agentquerier.AgentQuerier, flowKeys []string) ([]apis.OVSFlowResponse, error) { + resps := []apis.OVSFlowResponse{} for _, f := range flowKeys { flowStr, err := aq.GetOVSCtlClient().DumpMatchedFlow(f) if err != nil { @@ -51,14 +46,14 @@ func dumpMatchedFlows(aq agentquerier.AgentQuerier, flowKeys []string) ([]Respon return nil, err } if flowStr != "" { - resps = append(resps, Response{flowStr}) + resps = append(resps, apis.OVSFlowResponse{Flow: flowStr}) } } return resps, nil } -func dumpFlows(aq agentquerier.AgentQuerier, table uint8) ([]Response, error) { - resps := []Response{} +func dumpFlows(aq agentquerier.AgentQuerier, table uint8) ([]apis.OVSFlowResponse, error) { + resps := []apis.OVSFlowResponse{} var flowStrs []string var err error if table != binding.TableIDAll { @@ -70,13 +65,13 @@ func dumpFlows(aq agentquerier.AgentQuerier, table uint8) ([]Response, error) { return nil, err } for _, s := range flowStrs { - resps = append(resps, Response{s}) + resps = append(resps, apis.OVSFlowResponse{Flow: s}) } return resps, nil } -func dumpMatchedGroups(aq agentquerier.AgentQuerier, groupIDs []binding.GroupIDType) ([]Response, error) { - resps := []Response{} +func dumpMatchedGroups(aq agentquerier.AgentQuerier, groupIDs []binding.GroupIDType) ([]apis.OVSFlowResponse, error) { + resps := []apis.OVSFlowResponse{} for _, g := range groupIDs { groupStr, err := aq.GetOVSCtlClient().DumpGroup(uint32(g)) if err != nil { @@ -84,7 +79,7 @@ func dumpMatchedGroups(aq agentquerier.AgentQuerier, groupIDs []binding.GroupIDT return nil, err } if groupStr != "" { - resps = append(resps, Response{groupStr}) + resps = append(resps, apis.OVSFlowResponse{Flow: groupStr}) } } return resps, nil @@ -92,8 +87,8 @@ func dumpMatchedGroups(aq agentquerier.AgentQuerier, groupIDs []binding.GroupIDT // nil is returned if the flow table can not be found (the passed table name or // number is invalid). -func getTableFlows(aq agentquerier.AgentQuerier, tables string) ([]Response, error) { - var resps []Response +func getTableFlows(aq agentquerier.AgentQuerier, tables string) ([]apis.OVSFlowResponse, error) { + var resps []apis.OVSFlowResponse for _, tableSeg := range strings.Split(tables, ",") { tableSeg = strings.TrimSpace(tableSeg) var tableNumber uint8 @@ -120,15 +115,15 @@ func getTableFlows(aq agentquerier.AgentQuerier, tables string) ([]Response, err } // nil is returned if the passed group IDs are invalid. -func getGroups(aq agentquerier.AgentQuerier, groups string) ([]Response, error) { +func getGroups(aq agentquerier.AgentQuerier, groups string) ([]apis.OVSFlowResponse, error) { if strings.EqualFold(groups, "all") { groupStrs, err := aq.GetOVSCtlClient().DumpGroups() if err != nil { return nil, err } - resps := make([]Response, 0, len(groupStrs)) + resps := make([]apis.OVSFlowResponse, 0, len(groupStrs)) for _, s := range groupStrs { - resps = append(resps, Response{s}) + resps = append(resps, apis.OVSFlowResponse{Flow: s}) } return resps, nil } @@ -149,7 +144,7 @@ func getGroups(aq agentquerier.AgentQuerier, groups string) ([]Response, error) return dumpMatchedGroups(aq, groupIDs) } -func getPodFlows(aq agentquerier.AgentQuerier, podName, namespace string) ([]Response, error) { +func getPodFlows(aq agentquerier.AgentQuerier, podName, namespace string) ([]apis.OVSFlowResponse, error) { interfaces := aq.GetInterfaceStore().GetContainerInterfacesByPod(podName, namespace) if len(interfaces) == 0 { return nil, nil @@ -159,7 +154,7 @@ func getPodFlows(aq agentquerier.AgentQuerier, podName, namespace string) ([]Res return dumpMatchedFlows(aq, flowKeys) } -func getServiceFlows(aq agentquerier.AgentQuerier, serviceName, namespace string) ([]Response, error) { +func getServiceFlows(aq agentquerier.AgentQuerier, serviceName, namespace string) ([]apis.OVSFlowResponse, error) { flowKeys, groupIDs, found := aq.GetProxier().GetServiceFlowKeys(serviceName, namespace) if !found { return nil, nil @@ -175,7 +170,7 @@ func getServiceFlows(aq agentquerier.AgentQuerier, serviceName, namespace string return append(resps, groupResps...), nil } -func getNetworkPolicyFlows(aq agentquerier.AgentQuerier, npName, namespace string) ([]Response, error) { +func getNetworkPolicyFlows(aq agentquerier.AgentQuerier, npName, namespace string) ([]apis.OVSFlowResponse, error) { if len(aq.GetNetworkPolicyInfoQuerier().GetNetworkPolicies(&querier.NetworkPolicyQueryFilter{SourceName: npName, Namespace: namespace})) == 0 { // NetworkPolicy not found. return nil, nil @@ -185,15 +180,15 @@ func getNetworkPolicyFlows(aq agentquerier.AgentQuerier, npName, namespace strin return dumpMatchedFlows(aq, flowKeys) } -func getTableNames(aq agentquerier.AgentQuerier) []Response { - resps := []Response{} +func getTableNames(aq agentquerier.AgentQuerier) []apis.OVSFlowResponse { + resps := []apis.OVSFlowResponse{} names := []string{} for _, t := range getFlowTableList() { names = append(names, t.GetName()) } sort.Strings(names) for _, name := range names { - resps = append(resps, Response{name}) + resps = append(resps, apis.OVSFlowResponse{Flow: name}) } return resps } @@ -202,7 +197,7 @@ func getTableNames(aq agentquerier.AgentQuerier) []Response { func HandleFunc(aq agentquerier.AgentQuerier) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var err error - var resps []Response + var resps []apis.OVSFlowResponse pod := r.URL.Query().Get("pod") service := r.URL.Query().Get("service") networkPolicy := r.URL.Query().Get("networkpolicy") @@ -272,17 +267,3 @@ func HandleFunc(aq agentquerier.AgentQuerier) http.HandlerFunc { encodeResp() } } - -var _ common.TableOutput = new(Response) - -func (r Response) GetTableHeader() []string { - return []string{""} -} - -func (r Response) GetTableRow(maxColumnLength int) []string { - return []string{r.Flow} -} - -func (r Response) SortRows() bool { - return false -} diff --git a/pkg/agent/apiserver/handlers/ovsflows/handler_test.go b/pkg/agent/apiserver/handlers/ovsflows/handler_test.go index f2c20323edc..99ebc33bf58 100644 --- a/pkg/agent/apiserver/handlers/ovsflows/handler_test.go +++ b/pkg/agent/apiserver/handlers/ovsflows/handler_test.go @@ -23,6 +23,7 @@ import ( "github.com/stretchr/testify/assert" "go.uber.org/mock/gomock" + "antrea.io/antrea/pkg/agent/apis" "antrea.io/antrea/pkg/agent/interfacestore" interfacestoretest "antrea.io/antrea/pkg/agent/interfacestore/testing" oftest "antrea.io/antrea/pkg/agent/openflow/testing" @@ -41,8 +42,8 @@ var ( testDumpFlows = []string{"flow1", "flow2"} testGroupIDs = []binding.GroupIDType{1, 2} testDumpGroups = []string{"group1", "group2"} - testResponses = []Response{{"flow1"}, {"flow2"}} - testGroupResponses = []Response{{"group1"}, {"group2"}} + testResponses = []apis.OVSFlowResponse{{Flow: "flow1"}, {Flow: "flow2"}} + testGroupResponses = []apis.OVSFlowResponse{{Flow: "group1"}, {Flow: "group2"}} ) type testCase struct { @@ -51,7 +52,7 @@ type testCase struct { namespace string query string expectedStatus int - resps []Response + resps []apis.OVSFlowResponse } func TestBadRequests(t *testing.T) { @@ -247,7 +248,7 @@ func TestTableNamesOnly(t *testing.T) { test: "Get table names only", query: "?table-names-only", expectedStatus: http.StatusOK, - resps: []Response{{"table0"}, {"table1"}}, + resps: []apis.OVSFlowResponse{{Flow: "table0"}, {Flow: "table1"}}, } q := aqtest.NewMockAgentQuerier(ctrl) runHTTPTest(t, &tc, q) @@ -295,7 +296,7 @@ func TestGroups(t *testing.T) { test: "Group 1234", query: "?groups=1234", expectedStatus: http.StatusOK, - resps: []Response{{"group1234"}}, + resps: []apis.OVSFlowResponse{{Flow: "group1234"}}, }, groupIDs: []uint32{1234}, dumpedGroups: []string{"group1234"}, @@ -305,7 +306,7 @@ func TestGroups(t *testing.T) { test: "Non-existing group 1234", query: "?groups=1234", expectedStatus: http.StatusOK, - resps: []Response{}, + resps: []apis.OVSFlowResponse{}, }, groupIDs: []uint32{1234}, dumpedGroups: []string{""}, @@ -315,7 +316,7 @@ func TestGroups(t *testing.T) { test: "Group 10, 100, and 1000", query: "?groups=10,100,1000", expectedStatus: http.StatusOK, - resps: []Response{{"group10"}, {"group1000"}}, + resps: []apis.OVSFlowResponse{{Flow: "group10"}, {Flow: "group1000"}}, }, groupIDs: []uint32{10, 100, 1000}, dumpedGroups: []string{"group10", "", "group1000"}, @@ -350,7 +351,7 @@ func runHTTPTest(t *testing.T, tc *testCase, aq agentquerier.AgentQuerier) { assert.Equal(t, tc.expectedStatus, recorder.Code, tc.test) if tc.expectedStatus == http.StatusOK { - var received []Response + var received []apis.OVSFlowResponse err = json.Unmarshal(recorder.Body.Bytes(), &received) assert.Nil(t, err) if tc.resps != nil { diff --git a/pkg/agent/apiserver/handlers/ovstracing/handler.go b/pkg/agent/apiserver/handlers/ovstracing/handler.go index 584e8cc866f..1ab3d342fa5 100644 --- a/pkg/agent/apiserver/handlers/ovstracing/handler.go +++ b/pkg/agent/apiserver/handlers/ovstracing/handler.go @@ -29,6 +29,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/klog/v2" + "antrea.io/antrea/pkg/agent/apis" "antrea.io/antrea/pkg/agent/apiserver/handlers" "antrea.io/antrea/pkg/agent/interfacestore" "antrea.io/antrea/pkg/agent/querier" @@ -36,11 +37,6 @@ import ( "antrea.io/antrea/pkg/ovs/ovsctl" ) -// Response is the response struct of ovsflows command. -type Response struct { - Result string `json:"result,omitempty"` -} - type tracingPeer struct { ovsPort string // Name of a Pod or Service @@ -390,7 +386,7 @@ func HandleFunc(aq querier.AgentQuerier) http.HandlerFunc { } } - err = json.NewEncoder(w).Encode(Response{out}) + err = json.NewEncoder(w).Encode(apis.OVSTracingResponse{Result: out}) if err != nil { w.WriteHeader(http.StatusInternalServerError) } diff --git a/pkg/agent/apiserver/handlers/ovstracing/handler_test.go b/pkg/agent/apiserver/handlers/ovstracing/handler_test.go index ea3c01c068a..066856ef797 100644 --- a/pkg/agent/apiserver/handlers/ovstracing/handler_test.go +++ b/pkg/agent/apiserver/handlers/ovstracing/handler_test.go @@ -27,6 +27,7 @@ import ( "github.com/stretchr/testify/assert" "go.uber.org/mock/gomock" + "antrea.io/antrea/pkg/agent/apis" "antrea.io/antrea/pkg/agent/config" "antrea.io/antrea/pkg/agent/interfacestore" interfacestoretest "antrea.io/antrea/pkg/agent/interfacestore/testing" @@ -39,7 +40,7 @@ import ( var ( testTraceResult = "tracing result" - testResponse = Response{testTraceResult} + testResponse = apis.OVSTracingResponse{Result: testTraceResult} tunnelVirtualMAC, _ = net.ParseMAC("aa:bb:cc:dd:ee:ff") gatewayMAC, _ = net.ParseMAC("00:00:00:00:00:01") @@ -287,7 +288,7 @@ func runHTTPTest(t *testing.T, tc *testCase, aq querier.AgentQuerier) { assert.Equal(t, tc.expectedStatus, recorder.Code, tc.test) if tc.expectedStatus == http.StatusOK { - var received Response + var received apis.OVSTracingResponse err = json.Unmarshal(recorder.Body.Bytes(), &received) assert.Nil(t, err) assert.Equal(t, testResponse, received) diff --git a/pkg/agent/apiserver/handlers/podinterface/handler.go b/pkg/agent/apiserver/handlers/podinterface/handler.go index c086e703474..9cf4c8eb599 100644 --- a/pkg/agent/apiserver/handlers/podinterface/handler.go +++ b/pkg/agent/apiserver/handlers/podinterface/handler.go @@ -18,27 +18,14 @@ import ( "encoding/json" "net" "net/http" - "strings" + "antrea.io/antrea/pkg/agent/apis" "antrea.io/antrea/pkg/agent/interfacestore" "antrea.io/antrea/pkg/agent/querier" - "antrea.io/antrea/pkg/antctl/transform/common" ) -// Response describes the response struct of pod-interface command. -type Response struct { - PodName string `json:"name,omitempty" antctl:"name,Name of the Pod"` - PodNamespace string `json:"podNamespace,omitempty"` - InterfaceName string `json:"interfaceName,omitempty"` - IPs []string `json:"ips,omitempty"` - MAC string `json:"mac,omitempty"` - PortUUID string `json:"portUUID,omitempty"` - OFPort int32 `json:"ofPort,omitempty"` - ContainerID string `json:"containerID,omitempty"` -} - -func generateResponse(i *interfacestore.InterfaceConfig) Response { - return Response{ +func generateResponse(i *interfacestore.InterfaceConfig) apis.PodInterfaceResponse { + return apis.PodInterfaceResponse{ PodName: i.ContainerInterfaceConfig.PodName, PodNamespace: i.ContainerInterfaceConfig.PodNamespace, InterfaceName: i.InterfaceName, @@ -64,7 +51,7 @@ func HandleFunc(aq querier.AgentQuerier) http.HandlerFunc { name := r.URL.Query().Get("name") ns := r.URL.Query().Get("namespace") - var pods []Response + var pods []apis.PodInterfaceResponse for _, v := range aq.GetInterfaceStore().GetInterfacesByType(interfacestore.ContainerInterface) { podName := (*v.ContainerInterfaceConfig).PodName podNS := (*v.ContainerInterfaceConfig).PodNamespace @@ -83,24 +70,3 @@ func HandleFunc(aq querier.AgentQuerier) http.HandlerFunc { } } } - -var _ common.TableOutput = new(Response) - -func (r Response) GetTableHeader() []string { - return []string{"NAMESPACE", "NAME", "INTERFACE-NAME", "IP", "MAC", "PORT-UUID", "OF-PORT", "CONTAINER-ID"} -} - -func (r Response) GetContainerIDStr() string { - if len(r.ContainerID) > 12 { - return r.ContainerID[0:11] - } - return r.ContainerID -} - -func (r Response) GetTableRow(_ int) []string { - return []string{r.PodNamespace, r.PodName, r.InterfaceName, strings.Join(r.IPs, ", "), r.MAC, r.PortUUID, common.Int32ToString(r.OFPort), r.GetContainerIDStr()} -} - -func (r Response) SortRows() bool { - return true -} diff --git a/pkg/agent/apiserver/handlers/podinterface/handler_test.go b/pkg/agent/apiserver/handlers/podinterface/handler_test.go index 2ef63608d26..dc82e8e26f8 100644 --- a/pkg/agent/apiserver/handlers/podinterface/handler_test.go +++ b/pkg/agent/apiserver/handlers/podinterface/handler_test.go @@ -24,6 +24,7 @@ import ( "github.com/stretchr/testify/assert" "go.uber.org/mock/gomock" + "antrea.io/antrea/pkg/agent/apis" "antrea.io/antrea/pkg/agent/interfacestore" interfacestoretest "antrea.io/antrea/pkg/agent/interfacestore/testing" queriertest "antrea.io/antrea/pkg/agent/querier/testing" @@ -55,7 +56,7 @@ var podNames = []string{ "pod1", } -var responses = []Response{ +var responses = []apis.PodInterfaceResponse{ { PodName: podNames[0], PodNamespace: "namespaceA", @@ -143,27 +144,27 @@ func TestPodInterfaceQuery(t *testing.T) { testcases := map[string]struct { query string expectedStatus int - expectedContent []Response + expectedContent []apis.PodInterfaceResponse }{ "Hit Pod interface query, namespace provided": { query: "?name=pod1&&namespace=namespaceA", expectedStatus: http.StatusOK, - expectedContent: []Response{responses[1]}, + expectedContent: []apis.PodInterfaceResponse{responses[1]}, }, "Miss Pod interface query, namespace provided": { query: "?name=pod1&&namespace=namespaceB", expectedStatus: http.StatusNotFound, - expectedContent: []Response{}, + expectedContent: []apis.PodInterfaceResponse{}, }, "Hit Pod interface list query, namespace not provided": { query: "?name=pod0", expectedStatus: http.StatusOK, - expectedContent: []Response{responses[0], responses[2]}, + expectedContent: []apis.PodInterfaceResponse{responses[0], responses[2]}, }, "Miss Pod interface list query, namespace not provided": { query: "?name=pod2", expectedStatus: http.StatusNotFound, - expectedContent: []Response{}, + expectedContent: []apis.PodInterfaceResponse{}, }, } @@ -183,7 +184,7 @@ func TestPodInterfaceQuery(t *testing.T) { assert.Equal(t, tc.expectedStatus, recorder.Code, k) if tc.expectedStatus == http.StatusOK { - var received []Response + var received []apis.PodInterfaceResponse err = json.Unmarshal(recorder.Body.Bytes(), &received) assert.Nil(t, err) assert.Equal(t, tc.expectedContent, received) @@ -196,22 +197,22 @@ func TestPodInterfaceListQuery(t *testing.T) { testcases := map[string]struct { query string expectedStatus int - expectedContent []Response + expectedContent []apis.PodInterfaceResponse }{ "Hit pod interfaces in a namespace list query": { query: "?name=&&namespace=namespaceA", expectedStatus: http.StatusOK, - expectedContent: []Response{responses[0], responses[1]}, + expectedContent: []apis.PodInterfaceResponse{responses[0], responses[1]}, }, "Miss pod interfaces in a namespaces list query": { query: "?name=&&namespace=namespaceC", expectedStatus: http.StatusOK, - expectedContent: []Response(nil), + expectedContent: []apis.PodInterfaceResponse(nil), }, "Hit all pod interfaces in all namespace list query": { query: "?name=&&namespace=", expectedStatus: http.StatusOK, - expectedContent: []Response{responses[0], responses[1], responses[2]}, + expectedContent: []apis.PodInterfaceResponse{responses[0], responses[1], responses[2]}, }, } @@ -231,7 +232,7 @@ func TestPodInterfaceListQuery(t *testing.T) { assert.Equal(t, tc.expectedStatus, recorder.Code, k) if tc.expectedStatus == http.StatusOK { - var received []Response + var received []apis.PodInterfaceResponse err = json.Unmarshal(recorder.Body.Bytes(), &received) assert.Nil(t, err) assert.Equal(t, tc.expectedContent, received) diff --git a/pkg/agent/apiserver/handlers/serviceexternalip/handler.go b/pkg/agent/apiserver/handlers/serviceexternalip/handler.go index c397f24f505..8b8c580dd4a 100644 --- a/pkg/agent/apiserver/handlers/serviceexternalip/handler.go +++ b/pkg/agent/apiserver/handlers/serviceexternalip/handler.go @@ -18,7 +18,7 @@ import ( "encoding/json" "net/http" - "antrea.io/antrea/pkg/antctl/transform/common" + "antrea.io/antrea/pkg/agent/apis" "antrea.io/antrea/pkg/features" "antrea.io/antrea/pkg/querier" ) @@ -34,10 +34,10 @@ func HandleFunc(sq querier.ServiceExternalIPStatusQuerier) http.HandlerFunc { return } result := sq.GetServiceExternalIPStatus() - var response []Response + var response []apis.ServiceExternalIPInfo for _, r := range result { if (len(name) == 0 || name == r.ServiceName) && (len(ns) == 0 || ns == r.Namespace) { - response = append(response, Response{r}) + response = append(response, r) } } if len(name) > 0 && len(response) == 0 { @@ -49,22 +49,3 @@ func HandleFunc(sq querier.ServiceExternalIPStatusQuerier) http.HandlerFunc { } } } - -// Response describes the response struct of serviceexternalip command. -type Response struct { - querier.ServiceExternalIPInfo -} - -var _ common.TableOutput = (*Response)(nil) - -func (r Response) GetTableHeader() []string { - return []string{"NAMESPACE", "NAME", "EXTERNAL-IP-POOL", "EXTERNAL-IP", "ASSIGNED-NODE"} -} - -func (r Response) GetTableRow(_ int) []string { - return []string{r.Namespace, r.ServiceName, r.ExternalIPPool, r.ExternalIP, r.AssignedNode} -} - -func (r Response) SortRows() bool { - return true -} diff --git a/pkg/agent/client.go b/pkg/agent/client.go index 14bee852b30..57d87baa92e 100644 --- a/pkg/agent/client.go +++ b/pkg/agent/client.go @@ -28,8 +28,11 @@ import ( "k8s.io/component-base/config" "k8s.io/klog/v2" + "antrea.io/antrea/pkg/apis" cert "antrea.io/antrea/pkg/apiserver/certificate" "antrea.io/antrea/pkg/client/clientset/versioned" + "antrea.io/antrea/pkg/util/env" + "antrea.io/antrea/pkg/util/k8s" ) // AntreaClientProvider provides a method to get Antrea client. @@ -57,8 +60,8 @@ func NewAntreaClientProvider(config config.ClientConnectionConfiguration, kubeCl antreaCAProvider, _ := dynamiccertificates.NewDynamicCAFromConfigMapController( "antrea-ca", cert.GetCAConfigMapNamespace(), - cert.AntreaCAConfigMapName, - cert.CAConfigMapKey, + apis.AntreaCAConfigMapName, + apis.CAConfigMapKey, kubeClient) antreaClientProvider := &antreaClientProvider{ config: config, @@ -154,7 +157,7 @@ func inClusterConfig(caBundle []byte) (*rest.Config, error) { tlsClientConfig := rest.TLSClientConfig{ CAData: caBundle, - ServerName: cert.GetAntreaServerNames(cert.AntreaServiceName)[0], + ServerName: k8s.GetServiceDNSNames(env.GetAntreaNamespace(), apis.AntreaServiceName)[0], } return &rest.Config{ diff --git a/pkg/agent/controller/serviceexternalip/controller.go b/pkg/agent/controller/serviceexternalip/controller.go index 290558da961..7c28845b5db 100644 --- a/pkg/agent/controller/serviceexternalip/controller.go +++ b/pkg/agent/controller/serviceexternalip/controller.go @@ -31,6 +31,7 @@ import ( "k8s.io/client-go/util/workqueue" "k8s.io/klog/v2" + "antrea.io/antrea/pkg/agent/apis" "antrea.io/antrea/pkg/agent/ipassigner" "antrea.io/antrea/pkg/agent/memberlist" "antrea.io/antrea/pkg/agent/types" @@ -439,12 +440,12 @@ func (c *ServiceExternalIPController) nodesHasHealthyServiceEndpoint(service *co return nodes, nil } -func (c *ServiceExternalIPController) GetServiceExternalIPStatus() []querier.ServiceExternalIPInfo { +func (c *ServiceExternalIPController) GetServiceExternalIPStatus() []apis.ServiceExternalIPInfo { c.externalIPStatesMutex.RLock() defer c.externalIPStatesMutex.RUnlock() - info := make([]querier.ServiceExternalIPInfo, 0, len(c.externalIPStates)) + info := make([]apis.ServiceExternalIPInfo, 0, len(c.externalIPStates)) for k, v := range c.externalIPStates { - info = append(info, querier.ServiceExternalIPInfo{ + info = append(info, apis.ServiceExternalIPInfo{ ServiceName: k.Name, Namespace: k.Namespace, ExternalIP: v.ip, diff --git a/pkg/agent/controller/serviceexternalip/controller_test.go b/pkg/agent/controller/serviceexternalip/controller_test.go index 9c5a32a1246..caa1a07ce8d 100644 --- a/pkg/agent/controller/serviceexternalip/controller_test.go +++ b/pkg/agent/controller/serviceexternalip/controller_test.go @@ -30,10 +30,10 @@ import ( "k8s.io/client-go/kubernetes/fake" "k8s.io/client-go/util/workqueue" + "antrea.io/antrea/pkg/agent/apis" ipassignertest "antrea.io/antrea/pkg/agent/ipassigner/testing" "antrea.io/antrea/pkg/agent/memberlist" "antrea.io/antrea/pkg/agent/types" - "antrea.io/antrea/pkg/querier" ) const ( @@ -707,19 +707,19 @@ func TestServiceExternalIPController_GetServiceExternalIPStatus(t *testing.T) { tests := []struct { name string externalIPStates map[apimachinerytypes.NamespacedName]externalIPState - expectedServiceExternalIPInfo []querier.ServiceExternalIPInfo + expectedServiceExternalIPInfo []apis.ServiceExternalIPInfo }{ { name: "no Service available should return empty slice", externalIPStates: map[apimachinerytypes.NamespacedName]externalIPState{}, - expectedServiceExternalIPInfo: []querier.ServiceExternalIPInfo{}, + expectedServiceExternalIPInfo: []apis.ServiceExternalIPInfo{}, }, { name: "one Service processed", externalIPStates: map[apimachinerytypes.NamespacedName]externalIPState{ keyFor(servicePolicyCluster): {fakeServiceExternalIP1, fakeExternalIPPoolName, fakeNode1}, }, - expectedServiceExternalIPInfo: []querier.ServiceExternalIPInfo{ + expectedServiceExternalIPInfo: []apis.ServiceExternalIPInfo{ { ServiceName: servicePolicyCluster.Name, @@ -736,7 +736,7 @@ func TestServiceExternalIPController_GetServiceExternalIPStatus(t *testing.T) { keyFor(servicePolicyCluster): {fakeServiceExternalIP1, fakeExternalIPPoolName, fakeNode1}, keyFor(servicePolicyLocal): {fakeServiceExternalIP2, fakeExternalIPPoolName, fakeNode2}, }, - expectedServiceExternalIPInfo: []querier.ServiceExternalIPInfo{ + expectedServiceExternalIPInfo: []apis.ServiceExternalIPInfo{ { ServiceName: servicePolicyCluster.Name, diff --git a/pkg/antctl/antctl.go b/pkg/antctl/antctl.go index eef5a490d91..c5244adcc75 100644 --- a/pkg/antctl/antctl.go +++ b/pkg/antctl/antctl.go @@ -17,12 +17,7 @@ package antctl import ( "reflect" - "antrea.io/antrea/pkg/agent/apiserver/handlers/agentinfo" - "antrea.io/antrea/pkg/agent/apiserver/handlers/memberlist" - "antrea.io/antrea/pkg/agent/apiserver/handlers/multicast" - "antrea.io/antrea/pkg/agent/apiserver/handlers/ovsflows" - "antrea.io/antrea/pkg/agent/apiserver/handlers/podinterface" - "antrea.io/antrea/pkg/agent/apiserver/handlers/serviceexternalip" + agentapis "antrea.io/antrea/pkg/agent/apis" fallbackversion "antrea.io/antrea/pkg/antctl/fallback/version" "antrea.io/antrea/pkg/antctl/raw/featuregates" "antrea.io/antrea/pkg/antctl/raw/multicluster" @@ -38,12 +33,11 @@ import ( "antrea.io/antrea/pkg/antctl/transform/ovstracing" "antrea.io/antrea/pkg/antctl/transform/version" cpv1beta "antrea.io/antrea/pkg/apis/controlplane/v1beta2" + crdv1b1 "antrea.io/antrea/pkg/apis/crd/v1beta1" systemv1beta1 "antrea.io/antrea/pkg/apis/system/v1beta1" - endpointserver "antrea.io/antrea/pkg/apiserver/handlers/endpoint" - controllerinforest "antrea.io/antrea/pkg/apiserver/registry/system/controllerinfo" + controllerapis "antrea.io/antrea/pkg/apiserver/apis" "antrea.io/antrea/pkg/client/clientset/versioned/scheme" - "antrea.io/antrea/pkg/flowaggregator/apiserver/handlers/flowrecords" - "antrea.io/antrea/pkg/flowaggregator/apiserver/handlers/recordmetrics" + aggregatorapis "antrea.io/antrea/pkg/flowaggregator/apis" ) // CommandList defines all commands that could be used in the antctl for agents, @@ -58,7 +52,7 @@ var CommandList = &commandList{ commandGroup: flat, controllerEndpoint: &endpoint{ resourceEndpoint: &resourceEndpoint{ - resourceName: controllerinforest.ControllerInfoResourceName, + resourceName: crdv1b1.AntreaControllerInfoResourceName, groupVersionResource: &systemv1beta1.ControllerInfoVersionResource, }, addonTransform: version.ControllerTransform, @@ -111,7 +105,7 @@ $ antctl get podmulticaststats pod -n namespace`, }, }, - transformedResponse: reflect.TypeOf(multicast.Response{}), + transformedResponse: reflect.TypeOf(agentapis.MulticastResponse{}), }, { use: "log-level", @@ -305,7 +299,7 @@ $ antctl get podmulticaststats pod -n namespace`, long: "Print Antrea controller's basic information including version, deployment, NetworkPolicy controller, ControllerConditions, etc.", controllerEndpoint: &endpoint{ resourceEndpoint: &resourceEndpoint{ - resourceName: controllerinforest.ControllerInfoResourceName, + resourceName: crdv1b1.AntreaControllerInfoResourceName, groupVersionResource: &systemv1beta1.ControllerInfoVersionResource, }, addonTransform: controllerinfo.Transform, @@ -325,7 +319,7 @@ $ antctl get podmulticaststats pod -n namespace`, }, }, commandGroup: get, - transformedResponse: reflect.TypeOf(agentinfo.AntreaAgentInfoResponse{}), + transformedResponse: reflect.TypeOf(agentapis.AntreaAgentInfoResponse{}), }, { use: "podinterface", @@ -359,7 +353,7 @@ $ antctl get podmulticaststats pod -n namespace`, }, }, commandGroup: get, - transformedResponse: reflect.TypeOf(podinterface.Response{}), + transformedResponse: reflect.TypeOf(agentapis.PodInterfaceResponse{}), }, { use: "ovsflows", @@ -426,7 +420,7 @@ $ antctl get podmulticaststats pod -n namespace`, }, }, commandGroup: get, - transformedResponse: reflect.TypeOf(ovsflows.Response{}), + transformedResponse: reflect.TypeOf(agentapis.OVSFlowResponse{}), }, { use: "trace-packet", @@ -510,7 +504,7 @@ $ antctl get podmulticaststats pod -n namespace`, outputType: single, }, }, - transformedResponse: reflect.TypeOf(endpointserver.EndpointQueryResponse{}), + transformedResponse: reflect.TypeOf(controllerapis.EndpointQueryResponse{}), }, { use: "networkpolicyevaluation", @@ -582,7 +576,7 @@ $ antctl get podmulticaststats pod -n namespace`, outputType: multiple, }, }, - transformedResponse: reflect.TypeOf(flowrecords.Response{}), + transformedResponse: reflect.TypeOf(aggregatorapis.FlowRecordsResponse{}), }, { use: "recordmetrics", @@ -595,7 +589,7 @@ $ antctl get podmulticaststats pod -n namespace`, outputType: single, }, }, - transformedResponse: reflect.TypeOf(recordmetrics.Response{}), + transformedResponse: reflect.TypeOf(aggregatorapis.RecordMetricsResponse{}), }, { use: "serviceexternalip", @@ -621,7 +615,7 @@ $ antctl get podmulticaststats pod -n namespace`, outputType: multiple, }, }, - transformedResponse: reflect.TypeOf(serviceexternalip.Response{}), + transformedResponse: reflect.TypeOf(agentapis.ServiceExternalIPInfo{}), }, { use: "memberlist", @@ -635,7 +629,7 @@ $ antctl get podmulticaststats pod -n namespace`, outputType: multiple, }, }, - transformedResponse: reflect.TypeOf(memberlist.Response{}), + transformedResponse: reflect.TypeOf(agentapis.MemberlistResponse{}), }, }, rawCommands: []rawCommand{ diff --git a/pkg/antctl/client.go b/pkg/antctl/client.go index 410d0db38d3..f8385fc3b94 100644 --- a/pkg/antctl/client.go +++ b/pkg/antctl/client.go @@ -25,14 +25,10 @@ import ( "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime/serializer" - genericapiserver "k8s.io/apiserver/pkg/server" "k8s.io/client-go/rest" - agentapiserver "antrea.io/antrea/pkg/agent/apiserver" "antrea.io/antrea/pkg/antctl/runtime" "antrea.io/antrea/pkg/apis" - controllerapiserver "antrea.io/antrea/pkg/apiserver" - flowaggregatorapiserver "antrea.io/antrea/pkg/flowaggregator/apiserver" ) // requestOption describes options to issue requests. @@ -77,15 +73,13 @@ func (c *client) resolveKubeconfig(opt *requestOption) (*rest.Config, error) { kubeconfig.Insecure = true kubeconfig.CAFile = "" kubeconfig.CAData = nil + kubeconfig.BearerTokenFile = apis.APIServerLoopbackTokenPath if runtime.Mode == runtime.ModeAgent { kubeconfig.Host = net.JoinHostPort("127.0.0.1", fmt.Sprint(apis.AntreaAgentAPIPort)) - kubeconfig.BearerTokenFile = agentapiserver.TokenPath } else if runtime.Mode == runtime.ModeController { kubeconfig.Host = net.JoinHostPort("127.0.0.1", fmt.Sprint(apis.AntreaControllerAPIPort)) - kubeconfig.BearerTokenFile = controllerapiserver.TokenPath } else if runtime.Mode == runtime.ModeFlowAggregator { kubeconfig.Host = net.JoinHostPort("127.0.0.1", fmt.Sprint(apis.FlowAggregatorAPIPort)) - kubeconfig.BearerTokenFile = flowaggregatorapiserver.TokenPath } } else { var err error @@ -152,7 +146,7 @@ func (c *client) resourceRequest(e *resourceEndpoint, opt *requestOption) (io.Re } gv := e.groupVersionResource.GroupVersion() kubeconfig.GroupVersion = &gv - kubeconfig.APIPath = genericapiserver.APIGroupPrefix + kubeconfig.APIPath = "/apis" restClient, err := rest.RESTClientFor(kubeconfig) if err != nil { diff --git a/pkg/antctl/output/output.go b/pkg/antctl/output/output.go index 34bacbd03d6..312bad3f9a8 100644 --- a/pkg/antctl/output/output.go +++ b/pkg/antctl/output/output.go @@ -28,7 +28,7 @@ import ( "gopkg.in/yaml.v2" "antrea.io/antrea/pkg/antctl/transform/common" - endpointserver "antrea.io/antrea/pkg/apiserver/handlers/endpoint" + "antrea.io/antrea/pkg/apiserver/apis" ) const ( @@ -319,7 +319,7 @@ func TableOutputForQueryEndpoint(obj interface{}, writer io.Writer) error { } // transform egress and ingress rules to string representation - toStringRep := func(effectiveRules []endpointserver.Rule) [][]string { + toStringRep := func(effectiveRules []apis.Rule) [][]string { ruleStrings := make([][]string, 0) for _, rule := range effectiveRules { ruleStrings = append(ruleStrings, []string{rule.PolicyRef.Name, rule.PolicyRef.Namespace, strconv.Itoa(rule.RuleIndex), string(rule.PolicyRef.UID)}) @@ -327,7 +327,7 @@ func TableOutputForQueryEndpoint(obj interface{}, writer io.Writer) error { return ruleStrings } // iterate through each endpoint and construct response - endpointQueryResponse := obj.(*endpointserver.EndpointQueryResponse) + endpointQueryResponse := obj.(*apis.EndpointQueryResponse) for _, endpoint := range endpointQueryResponse.Endpoints { // indicate each endpoint Namespace/Name if err := writeSingleLine("Endpoint "+endpoint.Namespace+"/"+endpoint.Name, writer); err != nil { diff --git a/pkg/antctl/output/output_test.go b/pkg/antctl/output/output_test.go index 839547e3258..b8cdafeeeb5 100644 --- a/pkg/antctl/output/output_test.go +++ b/pkg/antctl/output/output_test.go @@ -24,9 +24,7 @@ import ( v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "antrea.io/antrea/pkg/agent/apiserver/handlers/agentinfo" - "antrea.io/antrea/pkg/agent/apiserver/handlers/memberlist" - "antrea.io/antrea/pkg/agent/apiserver/handlers/podinterface" + agentapis "antrea.io/antrea/pkg/agent/apis" "antrea.io/antrea/pkg/antctl/transform/addressgroup" "antrea.io/antrea/pkg/antctl/transform/appliedtogroup" "antrea.io/antrea/pkg/antctl/transform/common" @@ -34,7 +32,7 @@ import ( "antrea.io/antrea/pkg/antctl/transform/networkpolicy" cpv1beta "antrea.io/antrea/pkg/apis/controlplane/v1beta2" "antrea.io/antrea/pkg/apis/crd/v1beta1" - endpointserver "antrea.io/antrea/pkg/apiserver/handlers/endpoint" + "antrea.io/antrea/pkg/apiserver/apis" ) type Foobar struct { @@ -89,7 +87,7 @@ kube-system/antrea-controller-55b9bcd59f-h9ll4 node-control-plane Healthy 1 }, { name: "StructureData-AgentInfo-Single", - rawResponseData: agentinfo.AntreaAgentInfoResponse{ + rawResponseData: agentapis.AntreaAgentInfoResponse{ Version: "v0.4.0", PodRef: v1.ObjectReference{ Kind: "Pod", @@ -283,7 +281,7 @@ GroupName }, { name: "StructureData-PodInterface-List", - rawResponseData: []podinterface.Response{ + rawResponseData: []agentapis.PodInterfaceResponse{ { PodName: "nginx-6db489d4b7-vgv7v", PodNamespace: "default", @@ -312,7 +310,7 @@ default nginx-6db489d4b7-vgv7v Interface 127.0.0.1 07-16-76-00-02-86 port }, { name: "StructuredData-Memberlist-State", - rawResponseData: []memberlist.Response{ + rawResponseData: []agentapis.MemberlistResponse{ { NodeName: "node1", IP: "192.168.1.2", @@ -350,9 +348,9 @@ func TestTableOutputForQueryEndpoint(t *testing.T) { }{ { name: "Pod selected by no policy", - rawResponseData: &endpointserver.EndpointQueryResponse{ - Endpoints: []endpointserver.Endpoint{ - {Namespace: "testNamespace", Name: "podA", AppliedPolicies: []cpv1beta.NetworkPolicyReference{}, EgressDstRules: []endpointserver.Rule{}, IngressSrcRules: []endpointserver.Rule{}}, + rawResponseData: &apis.EndpointQueryResponse{ + Endpoints: []apis.Endpoint{ + {Namespace: "testNamespace", Name: "podA", AppliedPolicies: []cpv1beta.NetworkPolicyReference{}, EgressDstRules: []apis.Rule{}, IngressSrcRules: []apis.Rule{}}, }, }, expected: `Endpoint testNamespace/podA @@ -366,16 +364,16 @@ Ingress Rules Referencing Endpoint as Source: None }, { name: "Pod selected by 1 policy", - rawResponseData: &endpointserver.EndpointQueryResponse{ - Endpoints: []endpointserver.Endpoint{ + rawResponseData: &apis.EndpointQueryResponse{ + Endpoints: []apis.Endpoint{ { Namespace: "testNamespace", Name: "podA", AppliedPolicies: []cpv1beta.NetworkPolicyReference{policyRef0}, - EgressDstRules: []endpointserver.Rule{ + EgressDstRules: []apis.Rule{ {PolicyRef: policyRef0, Direction: cpv1beta.DirectionOut, RuleIndex: 0}, }, - IngressSrcRules: []endpointserver.Rule{ + IngressSrcRules: []apis.Rule{ {PolicyRef: policyRef0, Direction: cpv1beta.DirectionIn, RuleIndex: 0}, }, }, @@ -398,18 +396,18 @@ test-ingress-egress testNamespace 0 uid-1 }, { name: "Pod selected by 2 different policies", - rawResponseData: &endpointserver.EndpointQueryResponse{ - Endpoints: []endpointserver.Endpoint{ + rawResponseData: &apis.EndpointQueryResponse{ + Endpoints: []apis.Endpoint{ { Namespace: "testNamespace", Name: "podA", AppliedPolicies: []cpv1beta.NetworkPolicyReference{ policyRef0, policyRef1, }, - EgressDstRules: []endpointserver.Rule{ + EgressDstRules: []apis.Rule{ {PolicyRef: policyRef0, Direction: cpv1beta.DirectionOut, RuleIndex: 0}, }, - IngressSrcRules: []endpointserver.Rule{ + IngressSrcRules: []apis.Rule{ {PolicyRef: policyRef0, Direction: cpv1beta.DirectionIn, RuleIndex: 0}, }, }, diff --git a/pkg/antctl/raw/featuregates/command.go b/pkg/antctl/raw/featuregates/command.go index 1b646d70f08..acad10de989 100644 --- a/pkg/antctl/raw/featuregates/command.go +++ b/pkg/antctl/raw/featuregates/command.go @@ -28,6 +28,7 @@ import ( "antrea.io/antrea/pkg/antctl/raw" "antrea.io/antrea/pkg/antctl/runtime" + "antrea.io/antrea/pkg/apiserver/apis" "antrea.io/antrea/pkg/apiserver/handlers/featuregates" antrea "antrea.io/antrea/pkg/client/clientset/versioned" ) @@ -82,13 +83,13 @@ func featureGateRequest(cmd *cobra.Command, mode string) error { return err } - var resp []featuregates.Response + var resp []apis.FeatureGateResponse if resp, err = getFeatureGatesRequest(client); err != nil { return err } - var agentGates []featuregates.Response - var agentWindowsGates []featuregates.Response - var controllerGates []featuregates.Response + var agentGates []apis.FeatureGateResponse + var agentWindowsGates []apis.FeatureGateResponse + var controllerGates []apis.FeatureGateResponse for _, v := range resp { switch v.Component { case featuregates.AgentMode: @@ -156,8 +157,8 @@ func getControllerClient(ctx context.Context, k8sClientset kubernetes.Interface, return controllerClient, nil } -func getFeatureGatesRequest(client *rest.RESTClient) ([]featuregates.Response, error) { - var resp []featuregates.Response +func getFeatureGatesRequest(client *rest.RESTClient) ([]apis.FeatureGateResponse, error) { + var resp []apis.FeatureGateResponse u := url.URL{Path: "/featuregates"} getter := client.Get().RequestURI(u.RequestURI()) rawResp, err := getter.DoRaw(context.TODO()) @@ -171,7 +172,7 @@ func getFeatureGatesRequest(client *rest.RESTClient) ([]featuregates.Response, e return resp, nil } -func output(resps []featuregates.Response, component string, output io.Writer) { +func output(resps []apis.FeatureGateResponse, component string, output io.Writer) { switch component { case featuregates.AgentMode: output.Write([]byte("Antrea Agent Feature Gates\n")) diff --git a/pkg/antctl/raw/helper.go b/pkg/antctl/raw/helper.go index 50313642591..cad3808217c 100644 --- a/pkg/antctl/raw/helper.go +++ b/pkg/antctl/raw/helper.go @@ -28,12 +28,9 @@ import ( "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" - agentapiserver "antrea.io/antrea/pkg/agent/apiserver" "antrea.io/antrea/pkg/antctl/runtime" "antrea.io/antrea/pkg/apis" "antrea.io/antrea/pkg/apis/crd/v1beta1" - controllerapiserver "antrea.io/antrea/pkg/apiserver" - cert "antrea.io/antrea/pkg/apiserver/certificate" antrea "antrea.io/antrea/pkg/client/clientset/versioned" antreascheme "antrea.io/antrea/pkg/client/clientset/versioned/scheme" "antrea.io/antrea/pkg/util/ip" @@ -80,23 +77,22 @@ func SetupLocalKubeconfig(kubeconfig *rest.Config) { kubeconfig.Insecure = true kubeconfig.CAFile = "" kubeconfig.CAData = nil + kubeconfig.BearerTokenFile = apis.APIServerLoopbackTokenPath if runtime.Mode == runtime.ModeAgent { kubeconfig.Host = net.JoinHostPort("127.0.0.1", strconv.Itoa(apis.AntreaAgentAPIPort)) - kubeconfig.BearerTokenFile = agentapiserver.TokenPath } else { kubeconfig.Host = net.JoinHostPort("127.0.0.1", strconv.Itoa(apis.AntreaControllerAPIPort)) - kubeconfig.BearerTokenFile = controllerapiserver.TokenPath } } -func GetControllerCACert(ctx context.Context, client kubernetes.Interface) ([]byte, error) { - cm, err := client.CoreV1().ConfigMaps(cert.GetCAConfigMapNamespace()).Get(ctx, cert.AntreaCAConfigMapName, metav1.GetOptions{}) +func GetControllerCACert(ctx context.Context, client kubernetes.Interface, controllerInfo *v1beta1.AntreaControllerInfo) ([]byte, error) { + cm, err := client.CoreV1().ConfigMaps(controllerInfo.PodRef.Namespace).Get(ctx, apis.AntreaCAConfigMapName, metav1.GetOptions{}) if err != nil { return nil, err } - ca, ok := cm.Data[cert.CAConfigMapKey] + ca, ok := cm.Data[apis.CAConfigMapKey] if !ok { - return nil, fmt.Errorf("missing key '%s' in ConfigMap", cert.CAConfigMapKey) + return nil, fmt.Errorf("missing key '%s' in ConfigMap", apis.CAConfigMapKey) } return []byte(ca), nil } @@ -201,14 +197,14 @@ func CreateControllerClientCfg( cfg.CAFile = "" cfg.CAData = nil } else { - caCert, err := GetControllerCACert(ctx, k8sClientset) + caCert, err := GetControllerCACert(ctx, k8sClientset, controllerInfo) if err != nil { fmt.Println("Failed to retrieve certificate for Antrea Controller, which is required to establish a secure connection") fmt.Println("You can try running the command again with '--insecure'") return nil, fmt.Errorf("error when getting cert: %w", err) } cfg.Insecure = false - cfg.ServerName = cert.GetAntreaServerNames(cert.AntreaServiceName)[0] + cfg.ServerName = k8s.GetServiceDNSNames(controllerInfo.PodRef.Namespace, apis.AntreaServiceName)[0] cfg.CAData = caCert } diff --git a/pkg/antctl/raw/helper_test.go b/pkg/antctl/raw/helper_test.go index a3cfae584ac..5bd830061b5 100644 --- a/pkg/antctl/raw/helper_test.go +++ b/pkg/antctl/raw/helper_test.go @@ -29,9 +29,10 @@ import ( "k8s.io/client-go/rest" "antrea.io/antrea/pkg/apis" - v1beta1 "antrea.io/antrea/pkg/apis/crd/v1beta1" + "antrea.io/antrea/pkg/apis/crd/v1beta1" cert "antrea.io/antrea/pkg/apiserver/certificate" antreafakeclient "antrea.io/antrea/pkg/client/clientset/versioned/fake" + "antrea.io/antrea/pkg/util/k8s" ) const nodeIP = "8.8.8.8" @@ -58,6 +59,11 @@ var ( Kind: "Node", Name: node.Name, }, + PodRef: corev1.ObjectReference{ + Kind: "Pod", + Namespace: "kube-system", + Name: "antrea-controller-foo", + }, APIPort: apis.AntreaControllerAPIPort, } agentInfo = &v1beta1.AntreaAgentInfo{ @@ -142,16 +148,16 @@ func TestCreateControllerClientCfg(t *testing.T) { goodCM := &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Namespace: cert.GetCAConfigMapNamespace(), - Name: cert.AntreaCAConfigMapName, + Name: apis.AntreaCAConfigMapName, }, Data: map[string]string{ - cert.CAConfigMapKey: fakeCAData, + apis.CAConfigMapKey: fakeCAData, }, } badCM := &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Namespace: cert.GetCAConfigMapNamespace(), - Name: cert.AntreaCAConfigMapName, + Name: apis.AntreaCAConfigMapName, }, Data: map[string]string{ "foo": "bar", @@ -206,7 +212,7 @@ func TestCreateControllerClientCfg(t *testing.T) { require.NotNil(t, cfg) assert.Equal(t, tc.insecure, cfg.Insecure) if !tc.insecure { - assert.Equal(t, cert.GetAntreaServerNames(cert.AntreaServiceName)[0], cfg.ServerName) + assert.Equal(t, k8s.GetServiceDNSNames("kube-system", apis.AntreaServiceName)[0], cfg.ServerName) assert.Equal(t, []byte(fakeCAData), cfg.CAData) assert.Equal(t, apiHost, cfg.Host) } else { diff --git a/pkg/antctl/runtime/runtime.go b/pkg/antctl/runtime/runtime.go index b1be1853dae..93b181bf0f8 100644 --- a/pkg/antctl/runtime/runtime.go +++ b/pkg/antctl/runtime/runtime.go @@ -22,7 +22,7 @@ import ( "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" - agentapiserver "antrea.io/antrea/pkg/agent/apiserver" + "antrea.io/antrea/pkg/apis" "antrea.io/antrea/pkg/util/runtime" ) @@ -59,7 +59,7 @@ func init() { strings.HasPrefix(podName, "flow-aggregator")) if runtime.IsWindowsPlatform() && !InPod { - if _, err := os.Stat(agentapiserver.TokenPath); err == nil { + if _, err := os.Stat(apis.APIServerLoopbackTokenPath); err == nil { InPod = true Mode = ModeAgent return diff --git a/pkg/antctl/transform/addressgroup/response.go b/pkg/antctl/transform/addressgroup/response.go index 670cde57f12..2f567d9fec1 100644 --- a/pkg/antctl/transform/addressgroup/response.go +++ b/pkg/antctl/transform/addressgroup/response.go @@ -25,6 +25,7 @@ import ( "antrea.io/antrea/pkg/antctl/transform" "antrea.io/antrea/pkg/antctl/transform/common" cpv1beta "antrea.io/antrea/pkg/apis/controlplane/v1beta2" + "antrea.io/antrea/pkg/util/printers" ) type Response struct { @@ -91,7 +92,7 @@ func (r Response) GetPodIPs(maxColumnLength int) string { for i, pod := range r.Pods { list[i] = pod.IP } - return common.GenerateTableElementWithSummary(list, maxColumnLength) + return printers.GenerateTableElementWithSummary(list, maxColumnLength) } func (r Response) GetNodeIPs(maxColumnLength int) string { @@ -99,7 +100,7 @@ func (r Response) GetNodeIPs(maxColumnLength int) string { for i, node := range r.Nodes { list[i] = node.IP } - return common.GenerateTableElementWithSummary(list, maxColumnLength) + return printers.GenerateTableElementWithSummary(list, maxColumnLength) } func (r Response) GetTableRow(maxColumnLength int) []string { diff --git a/pkg/antctl/transform/appliedtogroup/response.go b/pkg/antctl/transform/appliedtogroup/response.go index 3074ed99807..d47163d1da0 100644 --- a/pkg/antctl/transform/appliedtogroup/response.go +++ b/pkg/antctl/transform/appliedtogroup/response.go @@ -25,6 +25,7 @@ import ( "antrea.io/antrea/pkg/antctl/transform" "antrea.io/antrea/pkg/antctl/transform/common" cpv1beta "antrea.io/antrea/pkg/apis/controlplane/v1beta2" + "antrea.io/antrea/pkg/util/printers" ) type Response struct { @@ -85,7 +86,7 @@ func (r Response) GetPodNames(maxColumnLength int) string { for i, pod := range r.Pods { list[i] = pod.Pod.Namespace + "/" + pod.Pod.Name } - return common.GenerateTableElementWithSummary(list, maxColumnLength) + return printers.GenerateTableElementWithSummary(list, maxColumnLength) } func (r Response) GetTableRow(maxColumnLength int) []string { diff --git a/pkg/antctl/transform/common/response.go b/pkg/antctl/transform/common/response.go index 9f9a1dd7e4c..effb52da0f0 100644 --- a/pkg/antctl/transform/common/response.go +++ b/pkg/antctl/transform/common/response.go @@ -15,10 +15,7 @@ package common import ( - "fmt" "net" - "sort" - "strconv" cpv1beta "antrea.io/antrea/pkg/apis/controlplane/v1beta2" ) @@ -48,50 +45,3 @@ type TableOutput interface { GetTableRow(maxColumnLength int) []string SortRows() bool } - -func Int32ToString(val int32) string { - return strconv.Itoa(int(val)) -} - -func Int64ToString(val int64) string { - return strconv.Itoa(int(val)) -} - -func BoolToString(val bool) string { - return strconv.FormatBool(val) -} - -func GenerateTableElementWithSummary(list []string, maxColumnLength int) string { - element := "" - sort.Strings(list) - for i, ele := range list { - val := ele - if i != 0 { - val = "," + val - } - - // If we can't show the information in one line, generate a summary. - summary := fmt.Sprintf(" + %d more...", len(list)-i) - if len(element)+len(val) > maxColumnLength { - element += summary - if len(element) > maxColumnLength { - newEle := "" - for i, ele := range list { - val := ele - if i != 0 { - val = "," + val - } - if i != 0 && len(newEle)+len(val)+len(summary) > maxColumnLength { - break - } - newEle += val - } - newEle += summary - return newEle - } - break - } - element += val - } - return element -} diff --git a/pkg/antctl/transform/controllerinfo/response.go b/pkg/antctl/transform/controllerinfo/response.go index 54f1c9acb2b..ce1061cf0e8 100644 --- a/pkg/antctl/transform/controllerinfo/response.go +++ b/pkg/antctl/transform/controllerinfo/response.go @@ -17,6 +17,7 @@ package controllerinfo import ( "encoding/json" "io" + "strconv" corev1 "k8s.io/api/core/v1" "k8s.io/klog/v2" @@ -86,10 +87,10 @@ func (r Response) GetTableRow(maxColumnLength int) []string { return []string{r.PodRef.Namespace + "/" + r.PodRef.Name, r.NodeRef.Name, r.GetControllerConditionStr(), - common.Int32ToString(r.NetworkPolicyControllerInfo.NetworkPolicyNum), - common.Int32ToString(r.NetworkPolicyControllerInfo.AddressGroupNum), - common.Int32ToString(r.NetworkPolicyControllerInfo.AppliedToGroupNum), - common.Int32ToString(r.ConnectedAgentNum)} + strconv.Itoa(int(r.NetworkPolicyControllerInfo.NetworkPolicyNum)), + strconv.Itoa(int(r.NetworkPolicyControllerInfo.AddressGroupNum)), + strconv.Itoa(int(r.NetworkPolicyControllerInfo.AppliedToGroupNum)), + strconv.Itoa(int(r.ConnectedAgentNum))} } func (r Response) SortRows() bool { diff --git a/pkg/antctl/transform/networkpolicy/response.go b/pkg/antctl/transform/networkpolicy/response.go index 94b59381502..53991b5edfb 100644 --- a/pkg/antctl/transform/networkpolicy/response.go +++ b/pkg/antctl/transform/networkpolicy/response.go @@ -29,7 +29,8 @@ import ( "antrea.io/antrea/pkg/antctl/transform" "antrea.io/antrea/pkg/antctl/transform/common" cpv1beta "antrea.io/antrea/pkg/apis/controlplane/v1beta2" - "antrea.io/antrea/pkg/controller/networkpolicy" + "antrea.io/antrea/pkg/apis/crd/v1beta1" + "antrea.io/antrea/pkg/util/printers" ) const sortByEffectivePriority = "effectivePriority" @@ -40,7 +41,7 @@ type Response struct { // Compute a tierPriority value in between the application tier and the baseline tier, // which can be used to sort all policies by tier. -var effectiveTierPriorityK8sNP = (networkpolicy.DefaultTierPriority + networkpolicy.BaselineTierPriority) / 2 +var effectiveTierPriorityK8sNP = (v1beta1.DefaultTierPriority + v1beta1.BaselineTierPriority) / 2 type NPSorter struct { networkPolicies []cpv1beta.NetworkPolicy @@ -153,7 +154,7 @@ func (r Response) GetTableHeader() []string { func (r Response) GetTableRow(maxColumnLength int) []string { return []string{ - r.Name, common.GenerateTableElementWithSummary(r.AppliedToGroups, maxColumnLength), + r.Name, printers.GenerateTableElementWithSummary(r.AppliedToGroups, maxColumnLength), strconv.Itoa(len(r.Rules)), r.SourceRef.ToString(), priorityToString(r.TierPriority), priorityToString(r.Priority), } @@ -189,7 +190,7 @@ func (r EvaluationResponse) GetTableRow(_ int) []string { r.Response.NetworkPolicy.Name, r.Response.NetworkPolicy.Namespace, string(r.Response.NetworkPolicy.Type), - common.Int32ToString(r.Response.RuleIndex), + strconv.Itoa(int(r.Response.RuleIndex)), string(r.Response.Rule.Direction), } } diff --git a/pkg/antctl/transform/ovstracing/response.go b/pkg/antctl/transform/ovstracing/response.go index 590c0d4f2e1..c2abad8e18a 100644 --- a/pkg/antctl/transform/ovstracing/response.go +++ b/pkg/antctl/transform/ovstracing/response.go @@ -18,7 +18,7 @@ import ( "encoding/json" "io" - "antrea.io/antrea/pkg/agent/apiserver/handlers/ovstracing" + "antrea.io/antrea/pkg/agent/apis" ) func Transform(reader io.Reader, _ bool, _ map[string]string) (interface{}, error) { @@ -26,7 +26,7 @@ func Transform(reader io.Reader, _ bool, _ map[string]string) (interface{}, erro if err != nil { return nil, err } - resp := new(ovstracing.Response) + resp := new(apis.OVSTracingResponse) err = json.Unmarshal(b, resp) if err != nil { return nil, err diff --git a/pkg/apis/crd/v1beta1/types.go b/pkg/apis/crd/v1beta1/types.go index cdee4779428..e891cc6fd37 100644 --- a/pkg/apis/crd/v1beta1/types.go +++ b/pkg/apis/crd/v1beta1/types.go @@ -94,6 +94,11 @@ type AntreaAgentInfoList struct { Items []AntreaAgentInfo `json:"items"` } +const ( + // AntreaControllerInfoResourceName is the name of the sole AntreaControllerInfo resource. + AntreaControllerInfoResourceName = "antrea-controller" +) + // +genclient // +genclient:nonNamespaced // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -156,6 +161,15 @@ type ControllerCondition struct { Message string `json:"message,omitempty"` } +const ( + // DefaultTierPriority maintains the priority for the system generated default Tier. + // This is the lowest priority for tiers that will be enforced before K8s NetworkPolicies. + DefaultTierPriority = int32(250) + // BaselineTierPriority maintains the priority for the system generated baseline Tier. + // This is the tier that will be enforced after K8s NetworkPolicies. + BaselineTierPriority = int32(253) +) + // +genclient // +genclient:nonNamespaced // +genclient:noStatus diff --git a/pkg/apis/paths.go b/pkg/apis/paths.go new file mode 100644 index 00000000000..0c7bb81100f --- /dev/null +++ b/pkg/apis/paths.go @@ -0,0 +1,20 @@ +// Copyright 2024 Antrea Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package apis + +const ( + // #nosec G101: false positive triggered by variable name which includes "token" + APIServerLoopbackTokenPath = "/var/run/antrea/apiserver/loopback-client-token" +) diff --git a/pkg/apis/resources.go b/pkg/apis/resources.go new file mode 100644 index 00000000000..14483e98ded --- /dev/null +++ b/pkg/apis/resources.go @@ -0,0 +1,31 @@ +// Copyright 2024 Antrea Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package apis + +const ( + // AntreaCAConfigMapName is the name of the ConfigMap that holds the CA certificate that validates the TLS + // certificate of antrea-controller. + AntreaCAConfigMapName = "antrea-ca" + + // AntreaControllerTLSSecretName is the name of the Secret that holds the self-signed TLS certificate and key of + // antrea-controller. + AntreaControllerTLSSecretName = "antrea-controller-tls" + + // AntreaServiceName is the name of the Service that exposes antrea-controller. + AntreaServiceName = "antrea" + + // CAConfigMapKey is the key that holds the CA certificate. + CAConfigMapKey = "ca.crt" +) diff --git a/pkg/apiserver/apis/doc.go b/pkg/apiserver/apis/doc.go new file mode 100644 index 00000000000..6f9600ba493 --- /dev/null +++ b/pkg/apiserver/apis/doc.go @@ -0,0 +1,16 @@ +// Copyright 2024 Antrea Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package apis contains API definitions used to interface with antrea-controller. +package apis diff --git a/pkg/apiserver/apis/types.go b/pkg/apiserver/apis/types.go new file mode 100644 index 00000000000..87947000bbb --- /dev/null +++ b/pkg/apiserver/apis/types.go @@ -0,0 +1,43 @@ +// Copyright 2024 Antrea Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package apis + +import "antrea.io/antrea/pkg/apis/controlplane/v1beta2" + +// EndpointQueryResponse is the reply struct for anctl endpoint queries +type EndpointQueryResponse struct { + Endpoints []Endpoint `json:"endpoints,omitempty"` +} + +type Rule struct { + PolicyRef v1beta2.NetworkPolicyReference `json:"policyref,omitempty"` + Direction v1beta2.Direction `json:"direction,omitempty"` + RuleIndex int `json:"ruleindex,omitempty"` +} + +type Endpoint struct { + Namespace string `json:"namespace,omitempty"` + Name string `json:"name,omitempty"` + AppliedPolicies []v1beta2.NetworkPolicyReference `json:"policies,omitempty"` + IngressSrcRules []Rule `json:"ingresssrcrules,omitempty"` + EgressDstRules []Rule `json:"egressdstrules,omitempty"` +} + +type FeatureGateResponse struct { + Component string `json:"component,omitempty"` + Name string `json:"name,omitempty"` + Status string `json:"status,omitempty"` + Version string `json:"version,omitempty"` +} diff --git a/pkg/apiserver/apiserver.go b/pkg/apiserver/apiserver.go index b87cd9d524c..1ce26c162d5 100644 --- a/pkg/apiserver/apiserver.go +++ b/pkg/apiserver/apiserver.go @@ -31,6 +31,7 @@ import ( "k8s.io/klog/v2" "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset" + "antrea.io/antrea/pkg/apis" "antrea.io/antrea/pkg/apis/controlplane" cpinstall "antrea.io/antrea/pkg/apis/controlplane/install" apistats "antrea.io/antrea/pkg/apis/stats" @@ -81,8 +82,6 @@ var ( // ParameterCodec defines methods for serializing and deserializing url values // to versioned API objects and back. parameterCodec = runtime.NewParameterCodec(Scheme) - // #nosec G101: false positive triggered by variable name which includes "token" - TokenPath = "/var/run/antrea/apiserver/loopback-client-token" // antreaServedLabelSelector selects resources served by antrea-controller. antreaServedLabelSelector = &metav1.LabelSelector{ @@ -347,8 +346,8 @@ func installHandlers(c *ExtraConfig, s *genericapiserver.GenericAPIServer) { func DefaultCAConfig() *certificate.CAConfig { return &certificate.CAConfig{ - CAConfigMapName: certificate.AntreaCAConfigMapName, - TLSSecretName: certificate.AntreaControllerTLSSecretName, + CAConfigMapName: apis.AntreaCAConfigMapName, + TLSSecretName: apis.AntreaControllerTLSSecretName, APIServiceSelector: antreaServedLabelSelector, ValidatingWebhookSelector: antreaServedLabelSelector, MutationWebhookSelector: antreaServedLabelSelector, @@ -357,7 +356,7 @@ func DefaultCAConfig() *certificate.CAConfig { SelfSignedCertDir: "/var/run/antrea/antrea-controller-self-signed", CertReadyTimeout: 2 * time.Minute, MinValidDuration: time.Hour * 24 * 90, // Rotate the certificate 90 days in advance. - ServiceName: certificate.AntreaServiceName, + ServiceName: apis.AntreaServiceName, PairName: "antrea-controller", } } diff --git a/pkg/apiserver/certificate/cacert_controller.go b/pkg/apiserver/certificate/cacert_controller.go index 49c29a6ea7d..0e65f20543f 100644 --- a/pkg/apiserver/certificate/cacert_controller.go +++ b/pkg/apiserver/certificate/cacert_controller.go @@ -33,13 +33,10 @@ import ( "k8s.io/klog/v2" "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset" + "antrea.io/antrea/pkg/apis" "antrea.io/antrea/pkg/util/env" ) -const ( - CAConfigMapKey = "ca.crt" -) - // CACertController is responsible for taking the CA certificate from the // caContentProvider and publishing it to the ConfigMap and the APIServices. type CACertController struct { @@ -279,12 +276,12 @@ func (c *CACertController) syncConfigMap(caCert []byte) error { }, } } - if caConfigMap.Data != nil && caConfigMap.Data[CAConfigMapKey] == string(caCert) { + if caConfigMap.Data != nil && caConfigMap.Data[apis.CAConfigMapKey] == string(caCert) { return nil } klog.InfoS("Syncing CA certificate with ConfigMap", "name", klog.KObj(caConfigMap)) caConfigMap.Data = map[string]string{ - CAConfigMapKey: string(caCert), + apis.CAConfigMapKey: string(caCert), } if exists { if _, err := c.client.CoreV1().ConfigMaps(caConfigMapNamespace).Update(context.TODO(), caConfigMap, metav1.UpdateOptions{}); err != nil { diff --git a/pkg/apiserver/certificate/cacert_controller_test.go b/pkg/apiserver/certificate/cacert_controller_test.go index 99fd374093b..17ce095af87 100644 --- a/pkg/apiserver/certificate/cacert_controller_test.go +++ b/pkg/apiserver/certificate/cacert_controller_test.go @@ -89,7 +89,7 @@ func TestSyncConfigMap(t *testing.T) { }, } caConfig := &CAConfig{ - ServiceName: AntreaServiceName, + ServiceName: "antrea", PairName: "antrea-controller", CAConfigMapName: "antrea-ca", } @@ -174,7 +174,7 @@ func TestSyncAPIServices(t *testing.T) { }, } caConfig := &CAConfig{ - ServiceName: AntreaServiceName, + ServiceName: "antrea", PairName: "antrea-controller", CAConfigMapName: "antrea-ca", APIServiceSelector: &metav1.LabelSelector{ @@ -263,7 +263,7 @@ func TestSyncValidatingWebhooks(t *testing.T) { }, } caConfig := &CAConfig{ - ServiceName: AntreaServiceName, + ServiceName: "antrea", PairName: "antrea-controller", CAConfigMapName: "antrea-ca", ValidatingWebhookSelector: &metav1.LabelSelector{ @@ -385,7 +385,7 @@ func TestSyncMutatingWebhooks(t *testing.T) { }, } caConfig := &CAConfig{ - ServiceName: AntreaServiceName, + ServiceName: "antrea", PairName: "antrea-controller", CAConfigMapName: "antrea-ca", MutationWebhookSelector: &metav1.LabelSelector{ @@ -498,7 +498,7 @@ func TestSyncConversionWebhooks(t *testing.T) { }, } caConfig := &CAConfig{ - ServiceName: AntreaServiceName, + ServiceName: "antrea", PairName: "antrea-controller", CAConfigMapName: "antrea-ca", CRDConversionWebhookSelector: &metav1.LabelSelector{ diff --git a/pkg/apiserver/certificate/certificate.go b/pkg/apiserver/certificate/certificate.go index 130b9ec2be6..92377aba398 100644 --- a/pkg/apiserver/certificate/certificate.go +++ b/pkg/apiserver/certificate/certificate.go @@ -28,8 +28,6 @@ import ( "k8s.io/client-go/kubernetes" "k8s.io/klog/v2" "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset" - - "antrea.io/antrea/pkg/util/env" ) const ( @@ -39,16 +37,6 @@ const ( TLSKeyFile = "tls.key" ) -// GetAntreaServerNames returns the DNS names that the TLS certificate will be signed with. -func GetAntreaServerNames(serviceName string) []string { - namespace := env.GetAntreaNamespace() - antreaServerName := serviceName + "." + namespace + ".svc" - // TODO: Although antrea-agent and kube-aggregator only verify the server name "antrea..svc", - // We should add the whole FQDN "antrea..svc." as an alternate DNS name when - // other clients need to access it directly with that name. - return []string{antreaServerName} -} - func ApplyServerCert(selfSignedCert bool, client kubernetes.Interface, aggregatorClient clientset.Interface, diff --git a/pkg/apiserver/certificate/certificate_test.go b/pkg/apiserver/certificate/certificate_test.go index 988f230e595..56884acf17b 100644 --- a/pkg/apiserver/certificate/certificate_test.go +++ b/pkg/apiserver/certificate/certificate_test.go @@ -159,7 +159,7 @@ func TestApplyServerCert(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() caConfig := &CAConfig{ - ServiceName: AntreaServiceName, + ServiceName: "antrea", PairName: "antrea-controller", } var err error diff --git a/pkg/apiserver/certificate/config.go b/pkg/apiserver/certificate/config.go index c9d0ff9614a..f7b49853aad 100644 --- a/pkg/apiserver/certificate/config.go +++ b/pkg/apiserver/certificate/config.go @@ -20,12 +20,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -const ( - AntreaCAConfigMapName = "antrea-ca" - AntreaControllerTLSSecretName = "antrea-controller-tls" - AntreaServiceName = "antrea" -) - type CAConfig struct { // Name of the ConfigMap that will hold the CA certificate that validates the TLS // certificate of antrea-controller. diff --git a/pkg/apiserver/certificate/selfsignedcert_provider.go b/pkg/apiserver/certificate/selfsignedcert_provider.go index 7ae466ee54c..6074b2f205a 100644 --- a/pkg/apiserver/certificate/selfsignedcert_provider.go +++ b/pkg/apiserver/certificate/selfsignedcert_provider.go @@ -42,6 +42,7 @@ import ( clockutils "k8s.io/utils/clock" "antrea.io/antrea/pkg/util/env" + "antrea.io/antrea/pkg/util/k8s" ) var loopbackAddresses = []net.IP{net.ParseIP("127.0.0.1"), net.IPv6loopback} @@ -256,7 +257,7 @@ func (p *selfSignedCertProvider) rotateSelfSignedCertificate() error { } if p.shouldRotateCertificate(cert) { klog.InfoS("Generating self-signed cert") - if cert, key, err = p.generateSelfSignedCertKey(p.caConfig.ServiceName, loopbackAddresses, GetAntreaServerNames(p.caConfig.ServiceName)); err != nil { + if cert, key, err = p.generateSelfSignedCertKey(p.caConfig.ServiceName, loopbackAddresses, k8s.GetServiceDNSNames(env.GetPodNamespace(), p.caConfig.ServiceName)); err != nil { return fmt.Errorf("unable to generate self-signed cert: %v", err) } // If Secret is specified, we should save the new certificate and key to it. diff --git a/pkg/apiserver/handlers/endpoint/handler.go b/pkg/apiserver/handlers/endpoint/handler.go index 41bcd949027..fae1b29a796 100644 --- a/pkg/apiserver/handlers/endpoint/handler.go +++ b/pkg/apiserver/handlers/endpoint/handler.go @@ -19,29 +19,11 @@ import ( "net/http" "antrea.io/antrea/pkg/apis/controlplane/v1beta2" + "antrea.io/antrea/pkg/apiserver/apis" "antrea.io/antrea/pkg/controller/networkpolicy" antreatypes "antrea.io/antrea/pkg/controller/types" ) -// EndpointQueryResponse is the reply struct for anctl endpoint queries -type EndpointQueryResponse struct { - Endpoints []Endpoint `json:"endpoints,omitempty"` -} - -type Rule struct { - PolicyRef v1beta2.NetworkPolicyReference `json:"policyref,omitempty"` - Direction v1beta2.Direction `json:"direction,omitempty"` - RuleIndex int `json:"ruleindex,omitempty"` -} - -type Endpoint struct { - Namespace string `json:"namespace,omitempty"` - Name string `json:"name,omitempty"` - AppliedPolicies []v1beta2.NetworkPolicyReference `json:"policies,omitempty"` - IngressSrcRules []Rule `json:"ingresssrcrules,omitempty"` - EgressDstRules []Rule `json:"egressdstrules,omitempty"` -} - // HandleFunc creates a http.HandlerFunc which uses an AgentNetworkPolicyInfoQuerier // to query network policy rules in current agent. func HandleFunc(eq networkpolicy.EndpointQuerier) http.HandlerFunc { @@ -72,11 +54,11 @@ func HandleFunc(eq networkpolicy.EndpointQuerier) http.HandlerFunc { responsePolicies = append(responsePolicies, responsePolicy) } // create rules based on effective rules on this endpoint - extractRules := func(effectiveRules []*antreatypes.RuleInfo) []Rule { - var responseRules []Rule + extractRules := func(effectiveRules []*antreatypes.RuleInfo) []apis.Rule { + var responseRules []apis.Rule for _, rule := range effectiveRules { v1beta2.Convert_controlplane_NetworkPolicyReference_To_v1beta2_NetworkPolicyReference(rule.Policy.SourceRef, &responsePolicy, nil) - newRule := Rule{ + newRule := apis.Rule{ PolicyRef: responsePolicy, Direction: v1beta2.Direction(rule.Rule.Direction), RuleIndex: rule.Index, @@ -86,14 +68,14 @@ func HandleFunc(eq networkpolicy.EndpointQuerier) http.HandlerFunc { return responseRules } // for now, selector only selects a single endpoint (pod, namespace) - endpoint := Endpoint{ + endpoint := apis.Endpoint{ Namespace: namespace, Name: podName, AppliedPolicies: responsePolicies, IngressSrcRules: extractRules(endpointNetworkPolicyRules.EndpointAsIngressSrcRules), EgressDstRules: extractRules(endpointNetworkPolicyRules.EndpointAsEgressDstRules), } - endpointQueryResponse := &EndpointQueryResponse{[]Endpoint{endpoint}} + endpointQueryResponse := &apis.EndpointQueryResponse{Endpoints: []apis.Endpoint{endpoint}} if err := json.NewEncoder(w).Encode(*endpointQueryResponse); err != nil { http.Error(w, "failed to encode response: "+err.Error(), http.StatusInternalServerError) diff --git a/pkg/apiserver/handlers/endpoint/handler_test.go b/pkg/apiserver/handlers/endpoint/handler_test.go index 1ac99b389f9..054e5d3f065 100644 --- a/pkg/apiserver/handlers/endpoint/handler_test.go +++ b/pkg/apiserver/handlers/endpoint/handler_test.go @@ -25,6 +25,7 @@ import ( "antrea.io/antrea/pkg/apis/controlplane" "antrea.io/antrea/pkg/apis/controlplane/v1beta2" + "antrea.io/antrea/pkg/apiserver/apis" queriermock "antrea.io/antrea/pkg/controller/networkpolicy/testing" antreatypes "antrea.io/antrea/pkg/controller/types" ) @@ -34,7 +35,7 @@ type TestCase struct { handlerRequest string expectedStatus int // expected result written by handler function - expectedResponse *EndpointQueryResponse + expectedResponse *apis.EndpointQueryResponse // arguments of call to mock argsMock []string @@ -97,12 +98,12 @@ func TestSinglePolicyResponse(t *testing.T) { "Responds with list of single element": { handlerRequest: "?namespace=namespace&pod=pod", expectedStatus: http.StatusOK, - expectedResponse: &EndpointQueryResponse{Endpoints: []Endpoint{ + expectedResponse: &apis.EndpointQueryResponse{Endpoints: []apis.Endpoint{ { AppliedPolicies: []v1beta2.NetworkPolicyReference{ {Name: "policy1"}, }, - IngressSrcRules: []Rule{ + IngressSrcRules: []apis.Rule{ {PolicyRef: v1beta2.NetworkPolicyReference{Name: "policy2"}}, }, }, @@ -143,7 +144,7 @@ func TestMultiPolicyResponse(t *testing.T) { "Responds with list of single element": { handlerRequest: "?namespace=namespace&pod=pod", expectedStatus: http.StatusOK, - expectedResponse: &EndpointQueryResponse{Endpoints: []Endpoint{ + expectedResponse: &apis.EndpointQueryResponse{Endpoints: []apis.Endpoint{ { AppliedPolicies: []v1beta2.NetworkPolicyReference{ {Name: "policy1"}, {Name: "policy2"}, @@ -184,7 +185,7 @@ func evaluateTestCases(testCases map[string]TestCase, mockCtrl *gomock.Controlle return } // check response is expected - var received EndpointQueryResponse + var received apis.EndpointQueryResponse err = json.Unmarshal(recorder.Body.Bytes(), &received) assert.Nil(t, err) for i, policy := range tc.expectedResponse.Endpoints[0].AppliedPolicies { diff --git a/pkg/apiserver/handlers/featuregates/handler.go b/pkg/apiserver/handlers/featuregates/handler.go index ddd4202c5e9..254e3aca3d5 100644 --- a/pkg/apiserver/handlers/featuregates/handler.go +++ b/pkg/apiserver/handlers/featuregates/handler.go @@ -27,23 +27,15 @@ import ( clientset "k8s.io/client-go/kubernetes" "k8s.io/klog/v2" + "antrea.io/antrea/pkg/apiserver/apis" "antrea.io/antrea/pkg/features" "antrea.io/antrea/pkg/util/env" ) -type ( - Config struct { - // FeatureGates is a map of feature names to bools that enable or disable experimental features. - FeatureGates map[string]bool `yaml:"featureGates,omitempty"` - } - - Response struct { - Component string `json:"component,omitempty"` - Name string `json:"name,omitempty"` - Status string `json:"status,omitempty"` - Version string `json:"version,omitempty"` - } -) +type Config struct { + // FeatureGates is a map of feature names to bools that enable or disable experimental features. + FeatureGates map[string]bool `yaml:"featureGates,omitempty"` +} const ( AgentMode = "agent" @@ -126,8 +118,8 @@ func HandleFunc(k8sclient clientset.Interface) http.HandlerFunc { } } -func getFeatureGatesResponse(cfg *Config, component string) []Response { - gatesResp := []Response{} +func getFeatureGatesResponse(cfg *Config, component string) []apis.FeatureGateResponse { + gatesResp := []apis.FeatureGateResponse{} for df := range features.DefaultAntreaFeatureGates { if component == AgentMode && features.AgentGates.Has(df) || component == AgentWindowsMode && features.AgentGates.Has(df) && features.SupportedOnWindows(df) || @@ -138,7 +130,7 @@ func getFeatureGatesResponse(cfg *Config, component string) []Response { status = features.DefaultFeatureGate.Enabled(df) } featureStatus := features.GetStatus(status) - gatesResp = append(gatesResp, Response{ + gatesResp = append(gatesResp, apis.FeatureGateResponse{ Component: component, Name: string(df), Status: featureStatus, diff --git a/pkg/apiserver/handlers/featuregates/handler_test.go b/pkg/apiserver/handlers/featuregates/handler_test.go index 172b3a8a242..51f49a68ff5 100644 --- a/pkg/apiserver/handlers/featuregates/handler_test.go +++ b/pkg/apiserver/handlers/featuregates/handler_test.go @@ -27,6 +27,7 @@ import ( "k8s.io/client-go/kubernetes/fake" "k8s.io/component-base/featuregate" + "antrea.io/antrea/pkg/apiserver/apis" "antrea.io/antrea/pkg/features" "antrea.io/antrea/pkg/util/runtime" ) @@ -40,7 +41,7 @@ func Test_getGatesResponse(t *testing.T) { tests := []struct { name string cfg *Config - want []Response + want []apis.FeatureGateResponse }{ { name: "mutated AntreaPolicy feature gate, agent mode", @@ -49,7 +50,7 @@ func Test_getGatesResponse(t *testing.T) { "AntreaPolicy": false, }, }, - want: []Response{ + want: []apis.FeatureGateResponse{ {Component: "agent", Name: "AntreaIPAM", Status: "Disabled", Version: "ALPHA"}, {Component: "agent", Name: "AntreaPolicy", Status: "Disabled", Version: "BETA"}, {Component: "agent", Name: "AntreaProxy", Status: "Enabled", Version: "GA"}, @@ -90,7 +91,7 @@ func Test_getGatesWindowsResponse(t *testing.T) { tests := []struct { name string cfg *Config - want []Response + want []apis.FeatureGateResponse }{ { name: "mutated AntreaPolicy feature gate, agent windows mode", @@ -99,7 +100,7 @@ func Test_getGatesWindowsResponse(t *testing.T) { "AntreaPolicy": false, }, }, - want: []Response{ + want: []apis.FeatureGateResponse{ {Component: "agent-windows", Name: "AntreaPolicy", Status: "Disabled", Version: "BETA"}, {Component: "agent-windows", Name: "AntreaProxy", Status: "Enabled", Version: "GA"}, {Component: "agent-windows", Name: "EndpointSlice", Status: "Enabled", Version: "GA"}, @@ -170,7 +171,7 @@ func TestHandleFunc(t *testing.T) { handler.ServeHTTP(recorder, req) require.Equal(t, http.StatusOK, recorder.Code) - var resp []Response + var resp []apis.FeatureGateResponse err = json.Unmarshal(recorder.Body.Bytes(), &resp) require.Nil(t, err) @@ -185,11 +186,11 @@ func TestHandleFunc(t *testing.T) { func Test_getControllerGatesResponse(t *testing.T) { tests := []struct { name string - want []Response + want []apis.FeatureGateResponse }{ { name: "good path", - want: []Response{ + want: []apis.FeatureGateResponse{ {Component: "controller", Name: "AdminNetworkPolicy", Status: "Disabled", Version: "ALPHA"}, {Component: "controller", Name: "AntreaIPAM", Status: "Disabled", Version: "ALPHA"}, {Component: "controller", Name: "AntreaPolicy", Status: "Enabled", Version: "BETA"}, diff --git a/pkg/apiserver/registry/system/controllerinfo/rest.go b/pkg/apiserver/registry/system/controllerinfo/rest.go index e25d72943d1..c42023cc48f 100644 --- a/pkg/apiserver/registry/system/controllerinfo/rest.go +++ b/pkg/apiserver/registry/system/controllerinfo/rest.go @@ -34,9 +34,6 @@ type REST struct { controllerQuerier querier.ControllerQuerier } -// Name of the AntreaControllerInfo resource. -const ControllerInfoResourceName = "antrea-controller" - var ( _ rest.Scoper = &REST{} _ rest.Getter = &REST{} @@ -60,7 +57,7 @@ func (r *REST) getControllerInfo() *crdv1beta1.AntreaControllerInfo { // Now AntreaControllerInfo has a single instance. info := new(crdv1beta1.AntreaControllerInfo) r.controllerQuerier.GetControllerInfo(info, false) - info.Name = ControllerInfoResourceName + info.Name = crdv1beta1.AntreaControllerInfoResourceName return info } diff --git a/pkg/apiserver/registry/system/controllerinfo/rest_test.go b/pkg/apiserver/registry/system/controllerinfo/rest_test.go index afbd40b7cee..6dd173c03f4 100644 --- a/pkg/apiserver/registry/system/controllerinfo/rest_test.go +++ b/pkg/apiserver/registry/system/controllerinfo/rest_test.go @@ -52,10 +52,10 @@ func TestRESTGet(t *testing.T) { }{ { name: "name matches", - objName: ControllerInfoResourceName, + objName: v1beta1.AntreaControllerInfoResourceName, expectedObj: &v1beta1.AntreaControllerInfo{ ObjectMeta: v1.ObjectMeta{ - Name: ControllerInfoResourceName, + Name: v1beta1.AntreaControllerInfoResourceName, }, }, }, @@ -93,7 +93,7 @@ func TestRESTList(t *testing.T) { Items: []v1beta1.AntreaControllerInfo{ { ObjectMeta: v1.ObjectMeta{ - Name: ControllerInfoResourceName, + Name: v1beta1.AntreaControllerInfoResourceName, }, }, }, diff --git a/pkg/controller/networkpolicy/antreanetworkpolicy_test.go b/pkg/controller/networkpolicy/antreanetworkpolicy_test.go index 62554de4402..7f0aedefa6c 100644 --- a/pkg/controller/networkpolicy/antreanetworkpolicy_test.go +++ b/pkg/controller/networkpolicy/antreanetworkpolicy_test.go @@ -21,6 +21,7 @@ import ( "github.com/stretchr/testify/require" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/utils/ptr" "antrea.io/antrea/multicluster/controllers/multicluster/common" "antrea.io/antrea/pkg/apis/controlplane" @@ -115,7 +116,7 @@ func TestProcessAntreaNetworkPolicy(t *testing.T) { UID: "uidA", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(crdv1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionIn, @@ -200,7 +201,7 @@ func TestProcessAntreaNetworkPolicy(t *testing.T) { UID: "uidB", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(crdv1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionIn, @@ -293,7 +294,7 @@ func TestProcessAntreaNetworkPolicy(t *testing.T) { UID: "uidC", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(crdv1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionIn, @@ -374,7 +375,7 @@ func TestProcessAntreaNetworkPolicy(t *testing.T) { UID: "uidD", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(crdv1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionIn, @@ -429,7 +430,7 @@ func TestProcessAntreaNetworkPolicy(t *testing.T) { UID: "uidE", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(crdv1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionOut, @@ -482,7 +483,7 @@ func TestProcessAntreaNetworkPolicy(t *testing.T) { UID: "uidE2", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(crdv1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionOut, @@ -539,7 +540,7 @@ func TestProcessAntreaNetworkPolicy(t *testing.T) { UID: "uidF", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(crdv1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionOut, @@ -600,7 +601,7 @@ func TestProcessAntreaNetworkPolicy(t *testing.T) { UID: "uidG", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(crdv1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionOut, @@ -656,7 +657,7 @@ func TestProcessAntreaNetworkPolicy(t *testing.T) { UID: "uidH", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(crdv1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionIn, @@ -712,7 +713,7 @@ func TestProcessAntreaNetworkPolicy(t *testing.T) { UID: "uidI", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(crdv1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionIn, diff --git a/pkg/controller/networkpolicy/clustergroup_test.go b/pkg/controller/networkpolicy/clustergroup_test.go index e957d024318..4378a73fa95 100644 --- a/pkg/controller/networkpolicy/clustergroup_test.go +++ b/pkg/controller/networkpolicy/clustergroup_test.go @@ -25,6 +25,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/utils/ptr" "antrea.io/antrea/pkg/apis/controlplane" crdv1alpha2 "antrea.io/antrea/pkg/apis/crd/v1alpha2" @@ -988,7 +989,7 @@ func TestSyncInternalGroup(t *testing.T) { UID: "uid1", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(crdv1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionIn, @@ -1039,7 +1040,7 @@ func TestSyncInternalGroup(t *testing.T) { UID: "uid2", }, Priority: &p20, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(crdv1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionIn, diff --git a/pkg/controller/networkpolicy/clusternetworkpolicy_test.go b/pkg/controller/networkpolicy/clusternetworkpolicy_test.go index 3241723ec1a..5279e14a23f 100644 --- a/pkg/controller/networkpolicy/clusternetworkpolicy_test.go +++ b/pkg/controller/networkpolicy/clusternetworkpolicy_test.go @@ -26,6 +26,7 @@ import ( "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/utils/ptr" "antrea.io/antrea/multicluster/controllers/multicluster/common" "antrea.io/antrea/pkg/apis/controlplane" @@ -163,7 +164,7 @@ func TestProcessClusterNetworkPolicy(t *testing.T) { UID: "uidA", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(crdv1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionIn, @@ -247,7 +248,7 @@ func TestProcessClusterNetworkPolicy(t *testing.T) { UID: "uidB", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(crdv1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionIn, @@ -367,7 +368,7 @@ func TestProcessClusterNetworkPolicy(t *testing.T) { UID: "uidD", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(crdv1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionIn, @@ -421,7 +422,7 @@ func TestProcessClusterNetworkPolicy(t *testing.T) { UID: "uidE", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(crdv1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionIn, @@ -495,7 +496,7 @@ func TestProcessClusterNetworkPolicy(t *testing.T) { UID: "uidH", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(crdv1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionIn, @@ -587,7 +588,7 @@ func TestProcessClusterNetworkPolicy(t *testing.T) { UID: "uidI", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(crdv1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionIn, @@ -680,7 +681,7 @@ func TestProcessClusterNetworkPolicy(t *testing.T) { UID: "uidI", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(crdv1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionIn, @@ -771,7 +772,7 @@ func TestProcessClusterNetworkPolicy(t *testing.T) { UID: "uidI", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(crdv1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionIn, @@ -906,7 +907,7 @@ func TestProcessClusterNetworkPolicy(t *testing.T) { UID: "uidJ", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(crdv1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionIn, @@ -1003,7 +1004,7 @@ func TestProcessClusterNetworkPolicy(t *testing.T) { UID: "uidS", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(crdv1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionIn, @@ -1067,7 +1068,7 @@ func TestProcessClusterNetworkPolicy(t *testing.T) { UID: "uidK", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(crdv1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionOut, @@ -1120,7 +1121,7 @@ func TestProcessClusterNetworkPolicy(t *testing.T) { UID: "uidM", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(crdv1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionOut, @@ -1177,7 +1178,7 @@ func TestProcessClusterNetworkPolicy(t *testing.T) { UID: "uidL", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(crdv1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionOut, @@ -1233,7 +1234,7 @@ func TestProcessClusterNetworkPolicy(t *testing.T) { UID: "uidP", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(crdv1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionOut, @@ -1284,7 +1285,7 @@ func TestProcessClusterNetworkPolicy(t *testing.T) { UID: "uidQ", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(crdv1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionOut, @@ -1347,7 +1348,7 @@ func TestProcessClusterNetworkPolicy(t *testing.T) { UID: "uidR", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(crdv1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionOut, @@ -1426,7 +1427,7 @@ func TestProcessClusterNetworkPolicy(t *testing.T) { UID: "uidL", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(crdv1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionIn, @@ -1515,7 +1516,7 @@ func TestProcessClusterNetworkPolicy(t *testing.T) { UID: "uid-icmp", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(crdv1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionIn, @@ -1584,7 +1585,7 @@ func TestProcessClusterNetworkPolicy(t *testing.T) { UID: "uidL", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(crdv1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionIn, @@ -1643,7 +1644,7 @@ func TestProcessClusterNetworkPolicy(t *testing.T) { UID: "uidL", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(crdv1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionOut, @@ -1707,7 +1708,7 @@ func TestProcessClusterNetworkPolicy(t *testing.T) { UID: "uidM", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(crdv1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionIn, @@ -1773,7 +1774,7 @@ func TestProcessClusterNetworkPolicy(t *testing.T) { UID: "uidN", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(crdv1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionIn, @@ -1849,7 +1850,7 @@ func TestProcessClusterNetworkPolicy(t *testing.T) { UID: "uidZ", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(crdv1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionIn, @@ -1957,7 +1958,7 @@ func TestGetTierPriority(t *testing.T) { { name: "empty-tier-name", inputTier: nil, - expPrio: DefaultTierPriority, + expPrio: crdv1beta1.DefaultTierPriority, }, { name: "tier10", diff --git a/pkg/controller/networkpolicy/crd_utils.go b/pkg/controller/networkpolicy/crd_utils.go index f58c82ed51f..d520177d47c 100644 --- a/pkg/controller/networkpolicy/crd_utils.go +++ b/pkg/controller/networkpolicy/crd_utils.go @@ -330,7 +330,7 @@ func (n *NetworkPolicyController) createAppliedToGroupForGroup(namespace, group // is returned. func (n *NetworkPolicyController) getTierPriority(tier string) int32 { if tier == "" { - return DefaultTierPriority + return crdv1beta1.DefaultTierPriority } // If the tier name is part of the static tier name set, we need to convert // tier name to lowercase to match the corresponding Tier CRD name. This is @@ -345,7 +345,7 @@ func (n *NetworkPolicyController) getTierPriority(tier string) int32 { if err != nil { // This error should ideally not occur as we perform validation. klog.Errorf("Failed to retrieve Tier %s. Setting default tier priority: %v", tier, err) - return DefaultTierPriority + return crdv1beta1.DefaultTierPriority } return t.Spec.Priority } diff --git a/pkg/controller/networkpolicy/endpoint_querier.go b/pkg/controller/networkpolicy/endpoint_querier.go index 5ee46c69328..031a31cb554 100644 --- a/pkg/controller/networkpolicy/endpoint_querier.go +++ b/pkg/controller/networkpolicy/endpoint_querier.go @@ -231,7 +231,7 @@ func predictEndpointsRules(srcEndpointRules, dstEndpointRules *antreatypes.Endpo // sort the common rules based on multiple closures, the top rule has the highest precedence tierPriority := func(r1, r2 *antreatypes.RuleInfo) int { - effectiveTierPriorityK8sNP := (DefaultTierPriority + BaselineTierPriority) / 2 + effectiveTierPriorityK8sNP := (crdv1beta1.DefaultTierPriority + crdv1beta1.BaselineTierPriority) / 2 r1Priority, r2Priority := effectiveTierPriorityK8sNP, effectiveTierPriorityK8sNP if r1.Policy.TierPriority != nil { r1Priority = *r1.Policy.TierPriority @@ -282,7 +282,7 @@ func predictEndpointsRules(srcEndpointRules, dstEndpointRules *antreatypes.Endpo if isPass(commonRule.Rule) { for _, rule := range commonRules[1:] { if rule.Policy.SourceRef.Type == controlplane.K8sNetworkPolicy || - (rule.Policy.TierPriority != nil && *rule.Policy.TierPriority == BaselineTierPriority && !isPass(rule.Rule)) { + (rule.Policy.TierPriority != nil && *rule.Policy.TierPriority == crdv1beta1.BaselineTierPriority && !isPass(rule.Rule)) { commonRule = rule break } diff --git a/pkg/controller/networkpolicy/endpoint_querier_test.go b/pkg/controller/networkpolicy/endpoint_querier_test.go index f4994cccc2b..9edbc317550 100644 --- a/pkg/controller/networkpolicy/endpoint_querier_test.go +++ b/pkg/controller/networkpolicy/endpoint_querier_test.go @@ -28,6 +28,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" + "k8s.io/utils/ptr" "antrea.io/antrea/pkg/apis/controlplane" crdv1beta1 "antrea.io/antrea/pkg/apis/crd/v1beta1" @@ -430,10 +431,10 @@ func TestQueryNetworkPolicyEvaluation(t *testing.T) { name: "Pass rule fallthrough", request: accessRequest, mockQueryResponse: []mockResponse{ - {response: generateResponse(1, generatePolicies(uid1, controlplane.AntreaNetworkPolicy, controlplane.DirectionOut, &BaselineTierPriority, nil, 1, &allowAction), + {response: generateResponse(1, generatePolicies(uid1, controlplane.AntreaNetworkPolicy, controlplane.DirectionOut, ptr.To(crdv1beta1.BaselineTierPriority), nil, 1, &allowAction), generateRuleInfo(generatePolicies(uid2, controlplane.AntreaNetworkPolicy, controlplane.DirectionIn, &tierEmergency, nil, 1, &passAction)[0]))}, {response: generateResponse(2, generatePolicies(uid2, controlplane.AntreaNetworkPolicy, controlplane.DirectionIn, &tierEmergency, nil, 1, &passAction), - generateRuleInfo(generatePolicies(uid1, controlplane.AntreaNetworkPolicy, controlplane.DirectionOut, &BaselineTierPriority, nil, 1, &allowAction)[0]))}, + generateRuleInfo(generatePolicies(uid1, controlplane.AntreaNetworkPolicy, controlplane.DirectionOut, ptr.To(crdv1beta1.BaselineTierPriority), nil, 1, &allowAction)[0]))}, }, expectedResult: &expectedResponse111, }, @@ -442,8 +443,8 @@ func TestQueryNetworkPolicyEvaluation(t *testing.T) { request: accessRequest, mockQueryResponse: []mockResponse{ {response: generateResponse(1, generatePolicies(uid1, controlplane.AntreaNetworkPolicy, controlplane.DirectionOut, &tierEmergency, nil, 1, &allowAction), - generateRuleInfo(generatePolicies(uid2, controlplane.AntreaNetworkPolicy, controlplane.DirectionIn, &DefaultTierPriority, nil, 1, &allowAction)[0]))}, - {response: generateResponse(2, generatePolicies(uid2, controlplane.AntreaNetworkPolicy, controlplane.DirectionIn, &DefaultTierPriority, nil, 1, &allowAction), + generateRuleInfo(generatePolicies(uid2, controlplane.AntreaNetworkPolicy, controlplane.DirectionIn, ptr.To(crdv1beta1.DefaultTierPriority), nil, 1, &allowAction)[0]))}, + {response: generateResponse(2, generatePolicies(uid2, controlplane.AntreaNetworkPolicy, controlplane.DirectionIn, ptr.To(crdv1beta1.DefaultTierPriority), nil, 1, &allowAction), generateRuleInfo(generatePolicies(uid1, controlplane.AntreaNetworkPolicy, controlplane.DirectionOut, &tierEmergency, nil, 1, &allowAction)[0]))}, }, expectedResult: &expectedResponse111, @@ -452,10 +453,10 @@ func TestQueryNetworkPolicyEvaluation(t *testing.T) { name: "Different policy priorities 1", request: accessRequest, mockQueryResponse: []mockResponse{ - {response: generateResponse(1, generatePolicies(uid1, controlplane.AntreaNetworkPolicy, controlplane.DirectionOut, &DefaultTierPriority, &priority1, 1, &allowAction), - generateRuleInfo(generatePolicies(uid2, controlplane.AntreaNetworkPolicy, controlplane.DirectionIn, &DefaultTierPriority, &priority2, 1, &allowAction)[0]))}, - {response: generateResponse(2, generatePolicies(uid2, controlplane.AntreaNetworkPolicy, controlplane.DirectionIn, &DefaultTierPriority, &priority2, 1, &allowAction), - generateRuleInfo(generatePolicies(uid1, controlplane.AntreaNetworkPolicy, controlplane.DirectionOut, &DefaultTierPriority, &priority1, 1, &allowAction)[0]))}, + {response: generateResponse(1, generatePolicies(uid1, controlplane.AntreaNetworkPolicy, controlplane.DirectionOut, ptr.To(crdv1beta1.DefaultTierPriority), &priority1, 1, &allowAction), + generateRuleInfo(generatePolicies(uid2, controlplane.AntreaNetworkPolicy, controlplane.DirectionIn, ptr.To(crdv1beta1.DefaultTierPriority), &priority2, 1, &allowAction)[0]))}, + {response: generateResponse(2, generatePolicies(uid2, controlplane.AntreaNetworkPolicy, controlplane.DirectionIn, ptr.To(crdv1beta1.DefaultTierPriority), &priority2, 1, &allowAction), + generateRuleInfo(generatePolicies(uid1, controlplane.AntreaNetworkPolicy, controlplane.DirectionOut, ptr.To(crdv1beta1.DefaultTierPriority), &priority1, 1, &allowAction)[0]))}, }, expectedResult: &expectedResponse111, }, @@ -463,10 +464,10 @@ func TestQueryNetworkPolicyEvaluation(t *testing.T) { name: "Different policy priorities 2", request: accessRequest, mockQueryResponse: []mockResponse{ - {response: generateResponse(1, generatePolicies(uid1, controlplane.AntreaNetworkPolicy, controlplane.DirectionOut, &DefaultTierPriority, &priority2, 1, &allowAction), - generateRuleInfo(generatePolicies(uid2, controlplane.AntreaNetworkPolicy, controlplane.DirectionIn, &DefaultTierPriority, &priority1, 1, &allowAction)[0]))}, - {response: generateResponse(2, generatePolicies(uid2, controlplane.AntreaNetworkPolicy, controlplane.DirectionIn, &DefaultTierPriority, &priority1, 1, &allowAction), - generateRuleInfo(generatePolicies(uid1, controlplane.AntreaNetworkPolicy, controlplane.DirectionOut, &DefaultTierPriority, &priority2, 1, &allowAction)[0]))}, + {response: generateResponse(1, generatePolicies(uid1, controlplane.AntreaNetworkPolicy, controlplane.DirectionOut, ptr.To(crdv1beta1.DefaultTierPriority), &priority2, 1, &allowAction), + generateRuleInfo(generatePolicies(uid2, controlplane.AntreaNetworkPolicy, controlplane.DirectionIn, ptr.To(crdv1beta1.DefaultTierPriority), &priority1, 1, &allowAction)[0]))}, + {response: generateResponse(2, generatePolicies(uid2, controlplane.AntreaNetworkPolicy, controlplane.DirectionIn, ptr.To(crdv1beta1.DefaultTierPriority), &priority1, 1, &allowAction), + generateRuleInfo(generatePolicies(uid1, controlplane.AntreaNetworkPolicy, controlplane.DirectionOut, ptr.To(crdv1beta1.DefaultTierPriority), &priority2, 1, &allowAction)[0]))}, }, expectedResult: &expectedResponse222, }, @@ -474,8 +475,8 @@ func TestQueryNetworkPolicyEvaluation(t *testing.T) { name: "Different rule priorities", request: accessRequest, mockQueryResponse: []mockResponse{ - {response: generateResponse(1, nil, generateRuleInfo(generatePolicies(uid2, controlplane.AntreaNetworkPolicy, controlplane.DirectionIn, &DefaultTierPriority, &priority1, 2, &allowAction)[0]))}, - {response: generateResponse(2, generatePolicies(uid2, controlplane.AntreaNetworkPolicy, controlplane.DirectionIn, &DefaultTierPriority, &priority1, 2, &allowAction), nil)}, + {response: generateResponse(1, nil, generateRuleInfo(generatePolicies(uid2, controlplane.AntreaNetworkPolicy, controlplane.DirectionIn, ptr.To(crdv1beta1.DefaultTierPriority), &priority1, 2, &allowAction)[0]))}, + {response: generateResponse(2, generatePolicies(uid2, controlplane.AntreaNetworkPolicy, controlplane.DirectionIn, ptr.To(crdv1beta1.DefaultTierPriority), &priority1, 2, &allowAction), nil)}, }, expectedResult: &expectedResponse222, }, @@ -483,10 +484,10 @@ func TestQueryNetworkPolicyEvaluation(t *testing.T) { name: "Different policy names", request: accessRequest, mockQueryResponse: []mockResponse{ - {response: generateResponse(1, generatePolicies(uid1, controlplane.AntreaNetworkPolicy, controlplane.DirectionOut, &DefaultTierPriority, &priority1, 1, &allowAction), - generateRuleInfo(generatePolicies(uid2, controlplane.AntreaNetworkPolicy, controlplane.DirectionIn, &DefaultTierPriority, &priority1, 1, &allowAction)[0]))}, - {response: generateResponse(2, generatePolicies(uid2, controlplane.AntreaNetworkPolicy, controlplane.DirectionIn, &DefaultTierPriority, &priority1, 1, &allowAction), - generateRuleInfo(generatePolicies(uid1, controlplane.AntreaNetworkPolicy, controlplane.DirectionOut, &DefaultTierPriority, &priority1, 1, &allowAction)[0]))}, + {response: generateResponse(1, generatePolicies(uid1, controlplane.AntreaNetworkPolicy, controlplane.DirectionOut, ptr.To(crdv1beta1.DefaultTierPriority), &priority1, 1, &allowAction), + generateRuleInfo(generatePolicies(uid2, controlplane.AntreaNetworkPolicy, controlplane.DirectionIn, ptr.To(crdv1beta1.DefaultTierPriority), &priority1, 1, &allowAction)[0]))}, + {response: generateResponse(2, generatePolicies(uid2, controlplane.AntreaNetworkPolicy, controlplane.DirectionIn, ptr.To(crdv1beta1.DefaultTierPriority), &priority1, 1, &allowAction), + generateRuleInfo(generatePolicies(uid1, controlplane.AntreaNetworkPolicy, controlplane.DirectionOut, ptr.To(crdv1beta1.DefaultTierPriority), &priority1, 1, &allowAction)[0]))}, }, expectedResult: &expectedResponse111, }, @@ -494,10 +495,10 @@ func TestQueryNetworkPolicyEvaluation(t *testing.T) { name: "KNP and baseline ANP", request: accessRequest, mockQueryResponse: []mockResponse{ - {response: generateResponse(1, generatePolicies(uid1, controlplane.AntreaNetworkPolicy, controlplane.DirectionOut, &BaselineTierPriority, nil, 1, &allowAction), + {response: generateResponse(1, generatePolicies(uid1, controlplane.AntreaNetworkPolicy, controlplane.DirectionOut, ptr.To(crdv1beta1.BaselineTierPriority), nil, 1, &allowAction), generateRuleInfo(generatePolicies(uid2, controlplane.K8sNetworkPolicy, controlplane.DirectionIn, nil, &defaultPriority, 1, nil)[0]))}, {response: generateResponse(2, generatePolicies(uid2, controlplane.K8sNetworkPolicy, controlplane.DirectionIn, nil, &defaultPriority, 1, nil), - generateRuleInfo(generatePolicies(uid1, controlplane.AntreaNetworkPolicy, controlplane.DirectionOut, &BaselineTierPriority, nil, 1, &allowAction)[0]))}, + generateRuleInfo(generatePolicies(uid1, controlplane.AntreaNetworkPolicy, controlplane.DirectionOut, ptr.To(crdv1beta1.BaselineTierPriority), nil, 1, &allowAction)[0]))}, }, expectedResult: &controlplane.NetworkPolicyEvaluationResponse{ NetworkPolicy: controlplane.NetworkPolicyReference{Type: controlplane.K8sNetworkPolicy, Namespace: namespace, Name: "Policy222", UID: uid2}, @@ -549,7 +550,7 @@ func TestQueryNetworkPolicyEvaluation(t *testing.T) { name: "No common rule found", request: accessRequest, mockQueryResponse: []mockResponse{ - {response: generateResponse(1, generatePolicies(uid1, controlplane.AntreaNetworkPolicy, controlplane.DirectionOut, &DefaultTierPriority, nil, 1, &allowAction), nil)}, + {response: generateResponse(1, generatePolicies(uid1, controlplane.AntreaNetworkPolicy, controlplane.DirectionOut, ptr.To(crdv1beta1.DefaultTierPriority), nil, 1, &allowAction), nil)}, {response: generateResponse(2, nil, nil)}, }, }, diff --git a/pkg/controller/networkpolicy/networkpolicy_controller_test.go b/pkg/controller/networkpolicy/networkpolicy_controller_test.go index 74b12c182e0..2fdde8597d2 100644 --- a/pkg/controller/networkpolicy/networkpolicy_controller_test.go +++ b/pkg/controller/networkpolicy/networkpolicy_controller_test.go @@ -3213,7 +3213,7 @@ func TestSyncInternalNetworkPolicy(t *testing.T) { UID: "uidA", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(v1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionIn, @@ -3546,7 +3546,7 @@ func TestSyncInternalNetworkPolicyWithGroups(t *testing.T) { UID: "uidA", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(v1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionIn, @@ -3595,7 +3595,7 @@ func TestSyncInternalNetworkPolicyWithGroups(t *testing.T) { UID: "uidA", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(v1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionIn, @@ -3639,7 +3639,7 @@ func TestSyncInternalNetworkPolicyWithGroups(t *testing.T) { UID: "uidA", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(v1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionIn, @@ -3688,7 +3688,7 @@ func TestSyncInternalNetworkPolicyWithGroups(t *testing.T) { UID: "uidA", }, Priority: &p10, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(v1beta1.DefaultTierPriority), Rules: []controlplane.NetworkPolicyRule{ { Direction: controlplane.DirectionIn, @@ -3948,7 +3948,7 @@ func TestClusterNetworkPolicyWithClusterGroup(t *testing.T) { }, }, AppliedToGroups: []string{cgA.Name}, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(v1beta1.DefaultTierPriority), } expectedAppliedToGroup := &antreatypes.AppliedToGroup{ SpanMeta: antreatypes.SpanMeta{NodeNames: sets.New(podA.Spec.NodeName)}, @@ -4015,7 +4015,7 @@ func TestClusterNetworkPolicyWithClusterGroup(t *testing.T) { {Direction: controlplane.DirectionIn, Action: &allowAction}, }, AppliedToGroups: []string{cgA.Name}, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(v1beta1.DefaultTierPriority), } checkResources(expectedPolicy2, expectedAppliedToGroup, nil) @@ -4032,7 +4032,7 @@ func TestClusterNetworkPolicyWithClusterGroup(t *testing.T) { {Direction: controlplane.DirectionIn, Action: &allowAction}, }, AppliedToGroups: []string{}, - TierPriority: &DefaultTierPriority, + TierPriority: ptr.To(v1beta1.DefaultTierPriority), } checkResources(expectedPolicy3, nil, nil) diff --git a/pkg/controller/networkpolicy/tier.go b/pkg/controller/networkpolicy/tier.go index 66fd318ff63..fae1e68d1d1 100644 --- a/pkg/controller/networkpolicy/tier.go +++ b/pkg/controller/networkpolicy/tier.go @@ -33,12 +33,7 @@ var ( // maxSupportedTiers is the soft limit on the maximum number of supported // Tiers. maxSupportedTiers = 20 - // DefaultTierPriority maintains the priority for the system generated default Tier. - // This is the lowest priority for tiers that will be enforced before K8s NetworkPolicies. - DefaultTierPriority = int32(250) - // BaselineTierPriority maintains the priority for the system generated baseline Tier. - // This is the tier that will be enforced after K8s NetworkPolicies. - BaselineTierPriority = int32(253) + // defaultTierName maintains the name of the default Tier in Antrea. defaultTierName = "application" // emergencyTierName maintains the name of the Emergency Tier in Antrea. @@ -50,8 +45,8 @@ var ( // priorityMap maintains the Tier priority associated with system generated // Tier names. priorityMap = map[string]int32{ - baselineTierName: BaselineTierPriority, - defaultTierName: DefaultTierPriority, + baselineTierName: secv1beta1.BaselineTierPriority, + defaultTierName: secv1beta1.DefaultTierPriority, platformTierName: int32(200), networkOpsTierName: int32(150), securityOpsTierName: int32(100), diff --git a/pkg/flowaggregator/apis/doc.go b/pkg/flowaggregator/apis/doc.go new file mode 100644 index 00000000000..f5d618ecccb --- /dev/null +++ b/pkg/flowaggregator/apis/doc.go @@ -0,0 +1,16 @@ +// Copyright 2024 Antrea Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package apis contains API definitions used to interface with flow-aggregator. +package apis diff --git a/pkg/flowaggregator/apis/types.go b/pkg/flowaggregator/apis/types.go new file mode 100644 index 00000000000..3daaf2ba6e9 --- /dev/null +++ b/pkg/flowaggregator/apis/types.go @@ -0,0 +1,87 @@ +// Copyright 2024 Antrea Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package apis + +import ( + "fmt" + "strconv" +) + +// FlowRecordsResponse is the response struct of flowrecords command. +type FlowRecordsResponse map[string]interface{} + +func (r FlowRecordsResponse) GetTableHeader() []string { + return []string{"SRC_IP", "DST_IP", "SPORT", "DPORT", "PROTO", "SRC_POD", "DST_POD", "SRC_NS", "DST_NS", "SERVICE"} +} + +func (r FlowRecordsResponse) GetTableRow(maxColumnLength int) []string { + var sourceAddress, destinationAddress interface{} + if r["sourceIPv4Address"] != nil { + sourceAddress = r["sourceIPv4Address"] + destinationAddress = r["destinationIPv4Address"] + } else { + sourceAddress = r["sourceIPv6Address"] + destinationAddress = r["destinationIPv6Address"] + } + return []string{ + fmt.Sprintf("%v", sourceAddress), + fmt.Sprintf("%v", destinationAddress), + fmt.Sprintf("%v", r["sourceTransportPort"]), + fmt.Sprintf("%v", r["destinationTransportPort"]), + fmt.Sprintf("%v", r["protocolIdentifier"]), + fmt.Sprintf("%v", r["sourcePodName"]), + fmt.Sprintf("%v", r["destinationPodName"]), + fmt.Sprintf("%v", r["sourcePodNamespace"]), + fmt.Sprintf("%v", r["destinationPodNamespace"]), + fmt.Sprintf("%v", r["destinationServicePortName"]), + } +} + +func (r FlowRecordsResponse) SortRows() bool { + return false +} + +// RecordMetricsResponse is the response struct of recordmetrics command. +type RecordMetricsResponse struct { + NumRecordsExported int64 `json:"numRecordsExported,omitempty"` + NumRecordsReceived int64 `json:"numRecordsReceived,omitempty"` + NumFlows int64 `json:"numFlows,omitempty"` + NumConnToCollector int64 `json:"numConnToCollector,omitempty"` + WithClickHouseExporter bool `json:"withClickHouseExporter,omitempty"` + WithS3Exporter bool `json:"withS3Exporter,omitempty"` + WithLogExporter bool `json:"withLogExporter,omitempty"` + WithIPFIXExporter bool `json:"withIPFIXExporter,omitempty"` +} + +func (r RecordMetricsResponse) GetTableHeader() []string { + return []string{"RECORDS-EXPORTED", "RECORDS-RECEIVED", "FLOWS", "EXPORTERS-CONNECTED", "CLICKHOUSE-EXPORTER", "S3-EXPORTER", "LOG-EXPORTER", "IPFIX-EXPORTER"} +} + +func (r RecordMetricsResponse) GetTableRow(maxColumnLength int) []string { + return []string{ + strconv.Itoa(int(r.NumRecordsExported)), + strconv.Itoa(int(r.NumRecordsReceived)), + strconv.Itoa(int(r.NumFlows)), + strconv.Itoa(int(r.NumConnToCollector)), + strconv.FormatBool(r.WithClickHouseExporter), + strconv.FormatBool(r.WithS3Exporter), + strconv.FormatBool(r.WithLogExporter), + strconv.FormatBool(r.WithIPFIXExporter), + } +} + +func (r RecordMetricsResponse) SortRows() bool { + return true +} diff --git a/pkg/flowaggregator/apiserver/apiserver.go b/pkg/flowaggregator/apiserver/apiserver.go index 01e4a2668d5..9aa8b6f922c 100644 --- a/pkg/flowaggregator/apiserver/apiserver.go +++ b/pkg/flowaggregator/apiserver/apiserver.go @@ -28,6 +28,7 @@ import ( genericapiserver "k8s.io/apiserver/pkg/server" genericoptions "k8s.io/apiserver/pkg/server/options" + "antrea.io/antrea/pkg/apis" systeminstall "antrea.io/antrea/pkg/apis/system/install" "antrea.io/antrea/pkg/apiserver/handlers/loglevel" "antrea.io/antrea/pkg/flowaggregator/apiserver/handlers/flowrecords" @@ -51,8 +52,6 @@ var ( // Codecs provides methods for retrieving codecs and serializers for specific // versions and content types. codecs = serializer.NewCodecFactory(scheme) - // #nosec G101: false positive triggered by variable name which includes "token" - TokenPath = "/var/run/antrea/apiserver/loopback-client-token" ) func init() { @@ -116,10 +115,10 @@ func newConfig(bindPort int) (*genericapiserver.CompletedConfig, error) { if err := authorization.ApplyTo(&serverConfig.Authorization); err != nil { return nil, err } - if err := os.MkdirAll(path.Dir(TokenPath), os.ModeDir); err != nil { + if err := os.MkdirAll(path.Dir(apis.APIServerLoopbackTokenPath), os.ModeDir); err != nil { return nil, fmt.Errorf("error when creating dirs of token file: %v", err) } - if err := os.WriteFile(TokenPath, []byte(serverConfig.LoopbackClientConfig.BearerToken), 0600); err != nil { + if err := os.WriteFile(apis.APIServerLoopbackTokenPath, []byte(serverConfig.LoopbackClientConfig.BearerToken), 0600); err != nil { return nil, fmt.Errorf("error when writing loopback access token to file: %v", err) } v := antreaversion.GetVersion() diff --git a/pkg/flowaggregator/apiserver/handlers/flowrecords/handler.go b/pkg/flowaggregator/apiserver/handlers/flowrecords/handler.go index 0b9abe9a8ca..d3c27774c64 100644 --- a/pkg/flowaggregator/apiserver/handlers/flowrecords/handler.go +++ b/pkg/flowaggregator/apiserver/handlers/flowrecords/handler.go @@ -16,28 +16,25 @@ package flowrecords import ( "encoding/json" - "fmt" "net/http" "strconv" - ipfixintermediate "github.com/vmware/go-ipfix/pkg/intermediate" + "github.com/vmware/go-ipfix/pkg/intermediate" + "antrea.io/antrea/pkg/flowaggregator/apis" "antrea.io/antrea/pkg/flowaggregator/querier" ) -// Response is the response struct of flowrecords command. -type Response map[string]interface{} - // HandleFunc returns the function which can handle the /flowrecords API request. func HandleFunc(faq querier.FlowAggregatorQuerier) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - var resps []Response + var resps []apis.FlowRecordsResponse sourceAddress := r.URL.Query().Get("srcip") destinationAddress := r.URL.Query().Get("dstip") protocol := r.URL.Query().Get("proto") sourcePort := r.URL.Query().Get("srcport") destinationPort := r.URL.Query().Get("dstport") - var flowKey *ipfixintermediate.FlowKey + var flowKey *intermediate.FlowKey if sourceAddress == "" && destinationAddress == "" && protocol == "" && sourcePort == "" && destinationPort == "" { flowKey = nil } else { @@ -62,7 +59,7 @@ func HandleFunc(faq querier.FlowAggregatorQuerier) http.HandlerFunc { } } - flowKey = &ipfixintermediate.FlowKey{ + flowKey = &intermediate.FlowKey{ SourceAddress: sourceAddress, DestinationAddress: destinationAddress, Protocol: uint8(protocolNum), @@ -80,34 +77,3 @@ func HandleFunc(faq querier.FlowAggregatorQuerier) http.HandlerFunc { } } } - -func (r Response) GetTableHeader() []string { - return []string{"SRC_IP", "DST_IP", "SPORT", "DPORT", "PROTO", "SRC_POD", "DST_POD", "SRC_NS", "DST_NS", "SERVICE"} -} - -func (r Response) GetTableRow(maxColumnLength int) []string { - var sourceAddress, destinationAddress interface{} - if r["sourceIPv4Address"] != nil { - sourceAddress = r["sourceIPv4Address"] - destinationAddress = r["destinationIPv4Address"] - } else { - sourceAddress = r["sourceIPv6Address"] - destinationAddress = r["destinationIPv6Address"] - } - return []string{ - fmt.Sprintf("%v", sourceAddress), - fmt.Sprintf("%v", destinationAddress), - fmt.Sprintf("%v", r["sourceTransportPort"]), - fmt.Sprintf("%v", r["destinationTransportPort"]), - fmt.Sprintf("%v", r["protocolIdentifier"]), - fmt.Sprintf("%v", r["sourcePodName"]), - fmt.Sprintf("%v", r["destinationPodName"]), - fmt.Sprintf("%v", r["sourcePodNamespace"]), - fmt.Sprintf("%v", r["destinationPodNamespace"]), - fmt.Sprintf("%v", r["destinationServicePortName"]), - } -} - -func (r Response) SortRows() bool { - return false -} diff --git a/pkg/flowaggregator/apiserver/handlers/flowrecords/handler_test.go b/pkg/flowaggregator/apiserver/handlers/flowrecords/handler_test.go index 5b1226620c6..f624dc3951e 100644 --- a/pkg/flowaggregator/apiserver/handlers/flowrecords/handler_test.go +++ b/pkg/flowaggregator/apiserver/handlers/flowrecords/handler_test.go @@ -21,9 +21,10 @@ import ( "testing" "github.com/stretchr/testify/assert" - ipfixintermediate "github.com/vmware/go-ipfix/pkg/intermediate" + "github.com/vmware/go-ipfix/pkg/intermediate" "go.uber.org/mock/gomock" + "antrea.io/antrea/pkg/flowaggregator/apis" queriertest "antrea.io/antrea/pkg/flowaggregator/querier/testing" ) @@ -79,9 +80,9 @@ type testCase struct { name string records []map[string]interface{} query string - flowKey *ipfixintermediate.FlowKey + flowKey *intermediate.FlowKey expectedStatus int - expectedResponse []Response + expectedResponse []apis.FlowRecordsResponse expectedTableRows [][]string } @@ -93,36 +94,36 @@ func TestGetFlowRecordsQuery(t *testing.T) { query: "", flowKey: nil, expectedStatus: http.StatusOK, - expectedResponse: []Response{record1, record2, record3}, + expectedResponse: []apis.FlowRecordsResponse{record1, record2, record3}, expectedTableRows: [][]string{recordTableRows1, recordTableRows2, recordTableRows3}, }, { name: "Get records by IP address", records: []map[string]interface{}{record2}, query: "?srcip=10.0.0.2&&dstip=10.0.0.1", - flowKey: &ipfixintermediate.FlowKey{ + flowKey: &intermediate.FlowKey{ SourceAddress: "10.0.0.2", DestinationAddress: "10.0.0.1", }, expectedStatus: http.StatusOK, - expectedResponse: []Response{record2}, + expectedResponse: []apis.FlowRecordsResponse{record2}, expectedTableRows: [][]string{recordTableRows2}, }, { name: "Get records by ports", records: []map[string]interface{}{record1, record3}, query: "?srcport=8080", - flowKey: &ipfixintermediate.FlowKey{ + flowKey: &intermediate.FlowKey{ SourcePort: 8080, }, expectedStatus: http.StatusOK, - expectedResponse: []Response{record1, record3}, + expectedResponse: []apis.FlowRecordsResponse{record1, record3}, expectedTableRows: [][]string{recordTableRows1, recordTableRows3}, }, { name: "Records not found", query: "?srcip=10.0.0.10", - flowKey: &ipfixintermediate.FlowKey{ + flowKey: &intermediate.FlowKey{ SourceAddress: "10.0.0.10", }, expectedStatus: http.StatusOK, @@ -158,7 +159,7 @@ func TestGetFlowRecordsQuery(t *testing.T) { assert.Equal(t, tc.expectedStatus, recorder.Code) if tc.expectedStatus == http.StatusOK { - var received []Response + var received []apis.FlowRecordsResponse err = json.Unmarshal(recorder.Body.Bytes(), &received) assert.Nil(t, err) assert.ElementsMatch(t, tc.expectedResponse, received) diff --git a/pkg/flowaggregator/apiserver/handlers/recordmetrics/handler.go b/pkg/flowaggregator/apiserver/handlers/recordmetrics/handler.go index b41448f08a0..68c1cfac8e6 100644 --- a/pkg/flowaggregator/apiserver/handlers/recordmetrics/handler.go +++ b/pkg/flowaggregator/apiserver/handlers/recordmetrics/handler.go @@ -20,27 +20,15 @@ import ( "k8s.io/klog/v2" - "antrea.io/antrea/pkg/antctl/transform/common" + "antrea.io/antrea/pkg/flowaggregator/apis" "antrea.io/antrea/pkg/flowaggregator/querier" ) -// Response is the response struct of recordmetrics command. -type Response struct { - NumRecordsExported int64 `json:"numRecordsExported,omitempty"` - NumRecordsReceived int64 `json:"numRecordsReceived,omitempty"` - NumFlows int64 `json:"numFlows,omitempty"` - NumConnToCollector int64 `json:"numConnToCollector,omitempty"` - WithClickHouseExporter bool `json:"withClickHouseExporter,omitempty"` - WithS3Exporter bool `json:"withS3Exporter,omitempty"` - WithLogExporter bool `json:"withLogExporter,omitempty"` - WithIPFIXExporter bool `json:"withIPFIXExporter,omitempty"` -} - // HandleFunc returns the function which can handle the /recordmetrics API request. func HandleFunc(faq querier.FlowAggregatorQuerier) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { metrics := faq.GetRecordMetrics() - metricsResponse := Response{ + metricsResponse := apis.RecordMetricsResponse{ NumRecordsExported: metrics.NumRecordsExported, NumRecordsReceived: metrics.NumRecordsReceived, NumFlows: metrics.NumFlows, @@ -57,24 +45,3 @@ func HandleFunc(faq querier.FlowAggregatorQuerier) http.HandlerFunc { } } } - -func (r Response) GetTableHeader() []string { - return []string{"RECORDS-EXPORTED", "RECORDS-RECEIVED", "FLOWS", "EXPORTERS-CONNECTED", "CLICKHOUSE-EXPORTER", "S3-EXPORTER", "LOG-EXPORTER", "IPFIX-EXPORTER"} -} - -func (r Response) GetTableRow(maxColumnLength int) []string { - return []string{ - common.Int64ToString(r.NumRecordsExported), - common.Int64ToString(r.NumRecordsReceived), - common.Int64ToString(r.NumFlows), - common.Int64ToString(r.NumConnToCollector), - common.BoolToString(r.WithClickHouseExporter), - common.BoolToString(r.WithS3Exporter), - common.BoolToString(r.WithLogExporter), - common.BoolToString(r.WithIPFIXExporter), - } -} - -func (r Response) SortRows() bool { - return true -} diff --git a/pkg/flowaggregator/apiserver/handlers/recordmetrics/handler_test.go b/pkg/flowaggregator/apiserver/handlers/recordmetrics/handler_test.go index 45a699e7fa1..d17ec0055c6 100644 --- a/pkg/flowaggregator/apiserver/handlers/recordmetrics/handler_test.go +++ b/pkg/flowaggregator/apiserver/handlers/recordmetrics/handler_test.go @@ -23,6 +23,7 @@ import ( "github.com/stretchr/testify/assert" "go.uber.org/mock/gomock" + "antrea.io/antrea/pkg/flowaggregator/apis" "antrea.io/antrea/pkg/flowaggregator/querier" queriertest "antrea.io/antrea/pkg/flowaggregator/querier/testing" ) @@ -48,10 +49,10 @@ func TestRecordMetricsQuery(t *testing.T) { handler.ServeHTTP(recorder, req) assert.Equal(t, http.StatusOK, recorder.Code) - var received Response + var received apis.RecordMetricsResponse err = json.Unmarshal(recorder.Body.Bytes(), &received) assert.Nil(t, err) - assert.Equal(t, Response{ + assert.Equal(t, apis.RecordMetricsResponse{ NumRecordsExported: 20, NumRecordsReceived: 15, NumFlows: 30, diff --git a/pkg/monitor/agent_test.go b/pkg/monitor/agent_test.go index 857b55f0810..dc30a285490 100644 --- a/pkg/monitor/agent_test.go +++ b/pkg/monitor/agent_test.go @@ -44,6 +44,7 @@ var fakeCertData = []byte("foobar") func TestSyncAgentCRD(t *testing.T) { ctx := context.Background() + crdName := "antrea-agent-foo" existingCRD := &v1beta1.AntreaAgentInfo{ ObjectMeta: metav1.ObjectMeta{ Name: "testAgentCRD", diff --git a/pkg/monitor/controller.go b/pkg/monitor/controller.go index 321f28d182f..58243b7e39f 100644 --- a/pkg/monitor/controller.go +++ b/pkg/monitor/controller.go @@ -39,7 +39,6 @@ import ( ) const ( - crdName = "antrea-controller" controllerName = "AntreaControllerMonitor" // How long to wait before retrying the processing of a Node/ExternalNode change. minRetryDelay = 5 * time.Second @@ -155,10 +154,10 @@ func (monitor *controllerMonitor) syncControllerCRD() { monitor.controllerCRD = nil } - monitor.controllerCRD, err = monitor.getControllerCRD(crdName) + monitor.controllerCRD, err = monitor.getControllerCRD(v1beta1.AntreaControllerInfoResourceName) if errors.IsNotFound(err) { - monitor.controllerCRD, err = monitor.createControllerCRD(crdName) + monitor.controllerCRD, err = monitor.createControllerCRD(v1beta1.AntreaControllerInfoResourceName) if err != nil { klog.ErrorS(err, "Failed to create controller monitoring CRD") monitor.controllerCRD = nil diff --git a/pkg/monitor/controller_test.go b/pkg/monitor/controller_test.go index 8644a7434cf..5d36e5eb5fa 100644 --- a/pkg/monitor/controller_test.go +++ b/pkg/monitor/controller_test.go @@ -486,6 +486,7 @@ func TestDeleteStaleAgentCRD(t *testing.T) { func TestSyncControllerCRD(t *testing.T) { ctx := context.Background() + crdName := v1beta1.AntreaControllerInfoResourceName existingCRD := &v1beta1.AntreaControllerInfo{ ObjectMeta: metav1.ObjectMeta{ Name: crdName, diff --git a/pkg/querier/querier.go b/pkg/querier/querier.go index 6285dfe04a8..1ebf4fa0f06 100644 --- a/pkg/querier/querier.go +++ b/pkg/querier/querier.go @@ -18,6 +18,7 @@ import ( v1 "k8s.io/api/core/v1" apitypes "k8s.io/apimachinery/pkg/types" + "antrea.io/antrea/pkg/agent/apis" "antrea.io/antrea/pkg/agent/interfacestore" "antrea.io/antrea/pkg/agent/multicast" "antrea.io/antrea/pkg/agent/types" @@ -115,14 +116,5 @@ type NetworkPolicyQueryFilter struct { // Ideally, every Node should have consistent results eventually. This should only be used when // ServiceExternalIP feature is enabled. type ServiceExternalIPStatusQuerier interface { - GetServiceExternalIPStatus() []ServiceExternalIPInfo -} - -// ServiceExternalIPInfo contains the essential information for Services with type of Loadbalancer managed by Antrea. -type ServiceExternalIPInfo struct { - ServiceName string `json:"serviceName,omitempty" antctl:"name,Name of the Service"` - Namespace string `json:"namespace,omitempty"` - ExternalIP string `json:"externalIP,omitempty"` - ExternalIPPool string `json:"externalIPPool,omitempty"` - AssignedNode string `json:"assignedNode,omitempty"` + GetServiceExternalIPStatus() []apis.ServiceExternalIPInfo } diff --git a/pkg/util/k8s/name.go b/pkg/util/k8s/name.go index 4c51d28f877..5c7f3e1683c 100644 --- a/pkg/util/k8s/name.go +++ b/pkg/util/k8s/name.go @@ -55,3 +55,10 @@ func ParseStatefulSetName(name string) (statefulSetName string, index int, err e statefulSetName = strings.Join(splittedName[:len(splittedName)-1], "-") return } + +// GetServiceDNSNames returns the DNS names that can be used to access the given Service. +// It currently returns one name only and may add other alternate names when needed. +func GetServiceDNSNames(namespace, serviceName string) []string { + dnsName := serviceName + "." + namespace + ".svc" + return []string{dnsName} +} diff --git a/pkg/util/printers/table.go b/pkg/util/printers/table.go new file mode 100644 index 00000000000..3f5ea1a9a53 --- /dev/null +++ b/pkg/util/printers/table.go @@ -0,0 +1,55 @@ +// Copyright 2024 Antrea Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package printers + +import ( + "fmt" + "sort" +) + +func GenerateTableElementWithSummary(list []string, maxColumnLength int) string { + element := "" + sort.Strings(list) + for i, ele := range list { + val := ele + if i != 0 { + val = "," + val + } + + // If we can't show the information in one line, generate a summary. + summary := fmt.Sprintf(" + %d more...", len(list)-i) + if len(element)+len(val) > maxColumnLength { + element += summary + if len(element) > maxColumnLength { + newEle := "" + for i, ele := range list { + val := ele + if i != 0 { + val = "," + val + } + if i != 0 && len(newEle)+len(val)+len(summary) > maxColumnLength { + break + } + newEle += val + } + newEle += summary + return newEle + } + break + } + element += val + } + return element +} diff --git a/test/e2e/antreapolicy_test.go b/test/e2e/antreapolicy_test.go index 00bfc5ab4c4..1cd2b10c49c 100644 --- a/test/e2e/antreapolicy_test.go +++ b/test/e2e/antreapolicy_test.go @@ -36,7 +36,7 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/wait" - "antrea.io/antrea/pkg/agent/apiserver/handlers/podinterface" + "antrea.io/antrea/pkg/agent/apis" crdv1beta1 "antrea.io/antrea/pkg/apis/crd/v1beta1" "antrea.io/antrea/pkg/controller/networkpolicy" "antrea.io/antrea/pkg/features" @@ -4085,7 +4085,7 @@ func generatePacketCaptureCmd(t *testing.T, data *TestData, timeout int, hostIP, agentPodName := getAntreaPodName(t, data, nodeName) cmds := []string{"antctl", "get", "podinterface", podName, "-n", testNamespace, "-o", "json"} stdout, stderr, err := runAntctl(agentPodName, cmds, data) - var podInterfaceInfo []podinterface.Response + var podInterfaceInfo []apis.PodInterfaceResponse if err := json.Unmarshal([]byte(stdout), &podInterfaceInfo); err != nil { return "", err } diff --git a/test/e2e/basic_test.go b/test/e2e/basic_test.go index 4c8d352726d..13778aa70e9 100644 --- a/test/e2e/basic_test.go +++ b/test/e2e/basic_test.go @@ -32,7 +32,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" - "antrea.io/antrea/pkg/agent/apiserver/handlers/podinterface" + "antrea.io/antrea/pkg/agent/apis" "antrea.io/antrea/pkg/agent/config" "antrea.io/antrea/pkg/agent/openflow/cookie" crdv1alpha2 "antrea.io/antrea/pkg/apis/crd/v1alpha2" @@ -129,7 +129,7 @@ func (data *TestData) testDeletePod(t *testing.T, podName string, nodeName strin t.Fatalf("Error when running antctl: %v", err) } - var podInterfaces []podinterface.Response + var podInterfaces []apis.PodInterfaceResponse if err := json.Unmarshal([]byte(stdout), &podInterfaces); err != nil { t.Fatalf("Error when querying the pod interface: %v", err) } diff --git a/test/e2e/flowaggregator_test.go b/test/e2e/flowaggregator_test.go index 5c17f98067e..79531f7e640 100644 --- a/test/e2e/flowaggregator_test.go +++ b/test/e2e/flowaggregator_test.go @@ -41,7 +41,7 @@ import ( "antrea.io/antrea/pkg/antctl/runtime" secv1beta1 "antrea.io/antrea/pkg/apis/crd/v1beta1" "antrea.io/antrea/pkg/features" - "antrea.io/antrea/pkg/flowaggregator/apiserver/handlers/recordmetrics" + "antrea.io/antrea/pkg/flowaggregator/apis" "antrea.io/antrea/test/e2e/utils" ) @@ -1869,7 +1869,7 @@ func getAndCheckFlowAggregatorMetrics(t *testing.T, data *TestData) error { t.Logf("Error when requesting recordmetrics, %v", err) return false, nil } - metrics := &recordmetrics.Response{} + metrics := &apis.RecordMetricsResponse{} if err := json.Unmarshal([]byte(stdout), metrics); err != nil { return false, fmt.Errorf("error when decoding recordmetrics: %w", err) } diff --git a/test/e2e/networkpolicy_test.go b/test/e2e/networkpolicy_test.go index 1a5e3199752..080c879c1a9 100644 --- a/test/e2e/networkpolicy_test.go +++ b/test/e2e/networkpolicy_test.go @@ -30,7 +30,7 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/wait" - "antrea.io/antrea/pkg/agent/apiserver/handlers/agentinfo" + "antrea.io/antrea/pkg/agent/apis" "antrea.io/antrea/pkg/apis/crd/v1beta1" "antrea.io/antrea/pkg/apis/stats/v1alpha1" "antrea.io/antrea/pkg/features" @@ -1142,7 +1142,7 @@ func waitForAgentCondition(t *testing.T, data *TestData, podName string, conditi if err != nil { return false, nil } - var agentInfo agentinfo.AntreaAgentInfoResponse + var agentInfo apis.AntreaAgentInfoResponse err = json.Unmarshal([]byte(stdout), &agentInfo) if err != nil { return true, err diff --git a/test/e2e/security_test.go b/test/e2e/security_test.go index b8adff2a570..644663453ea 100644 --- a/test/e2e/security_test.go +++ b/test/e2e/security_test.go @@ -28,9 +28,11 @@ import ( "k8s.io/apimachinery/pkg/util/wait" certutil "k8s.io/client-go/util/cert" + "antrea.io/antrea/pkg/apis" "antrea.io/antrea/pkg/apis/crd/v1beta1" "antrea.io/antrea/pkg/apiserver/certificate" controllerconfig "antrea.io/antrea/pkg/config/controller" + "antrea.io/antrea/pkg/util/k8s" ) const ( @@ -75,7 +77,7 @@ func testUserProvidedCert(t *testing.T, data *TestData) { }) genCertKeyAndUpdateSecret := func() ([]byte, []byte) { - certPem, keyPem, _ := certutil.GenerateSelfSignedCertKey("antrea", nil, certificate.GetAntreaServerNames(certificate.AntreaServiceName)) + certPem, keyPem, _ := certutil.GenerateSelfSignedCertKey("antrea", nil, k8s.GetServiceDNSNames("kube-system", apis.AntreaServiceName)) secret, err := data.clientset.CoreV1().Secrets(tlsSecretNamespace).Get(context.TODO(), tlsSecretName, metav1.GetOptions{}) exists := true if err != nil { @@ -168,12 +170,12 @@ func testCert(t *testing.T, data *TestData, expectedCABundle string, restartPod var configMap *v1.ConfigMap if err := wait.PollUntilContextTimeout(context.Background(), 2*time.Second, timeout, false, func(ctx context.Context) (bool, error) { var err error - configMap, err = data.clientset.CoreV1().ConfigMaps(caConfigMapNamespace).Get(context.TODO(), certificate.AntreaCAConfigMapName, metav1.GetOptions{}) + configMap, err = data.clientset.CoreV1().ConfigMaps(caConfigMapNamespace).Get(context.TODO(), apis.AntreaCAConfigMapName, metav1.GetOptions{}) if err != nil { return false, fmt.Errorf("cannot get ConfigMap antrea-ca") } var exists bool - caBundle, exists = configMap.Data[certificate.CAConfigMapKey] + caBundle, exists = configMap.Data[apis.CAConfigMapKey] if !exists { t.Log("Missing content for CA bundle, retrying") return false, nil @@ -209,7 +211,7 @@ func testCert(t *testing.T, data *TestData, expectedCABundle string, restartPod caFile := "/etc/config/ca.crt" clientName := "agnhost" - reqURL := fmt.Sprintf("https://%s/readyz", certificate.GetAntreaServerNames(certificate.AntreaServiceName)[0]) + reqURL := fmt.Sprintf("https://%s/readyz", k8s.GetServiceDNSNames("kube-system", apis.AntreaServiceName)[0]) cmd := []string{"curl", "--cacert", caFile, "-s", reqURL} require.NoError(t, NewPodBuilder(clientName, data.testNamespace, agnhostImage).WithContainerName(getImageName(agnhostImage)).MountConfigMap(configMapCopy.Name, "/etc/config/", "config-volume").WithHostNetwork(false).Create(data)) defer data.DeletePodAndWait(defaultTimeout, clientName, data.testNamespace) diff --git a/test/e2e/service_externalip_test.go b/test/e2e/service_externalip_test.go index 555c39592d3..76f29bfc08f 100644 --- a/test/e2e/service_externalip_test.go +++ b/test/e2e/service_externalip_test.go @@ -33,10 +33,10 @@ import ( "k8s.io/client-go/util/retry" utilnet "k8s.io/utils/net" + "antrea.io/antrea/pkg/agent/apis" antreaagenttypes "antrea.io/antrea/pkg/agent/types" "antrea.io/antrea/pkg/apis/crd/v1beta1" "antrea.io/antrea/pkg/features" - "antrea.io/antrea/pkg/querier" ) func TestServiceExternalIP(t *testing.T) { @@ -702,7 +702,7 @@ func (data *TestData) getServiceAssignedNode(node string, service *v1.Service) ( if err != nil { return "", err } - var serviceExternalIPInfo []querier.ServiceExternalIPInfo + var serviceExternalIPInfo []apis.ServiceExternalIPInfo if err := json.Unmarshal([]byte(stdout), &serviceExternalIPInfo); err != nil { return "", err } diff --git a/test/e2e/supportbundle_test.go b/test/e2e/supportbundle_test.go index 08633112efb..9cb644321a8 100644 --- a/test/e2e/supportbundle_test.go +++ b/test/e2e/supportbundle_test.go @@ -29,10 +29,8 @@ import ( "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/rest" - agentapiserver "antrea.io/antrea/pkg/agent/apiserver" "antrea.io/antrea/pkg/apis" systemv1beta1 "antrea.io/antrea/pkg/apis/system/v1beta1" - controllerapiserver "antrea.io/antrea/pkg/apiserver" clientset "antrea.io/antrea/pkg/client/clientset/versioned" "antrea.io/antrea/test/e2e/utils/portforwarder" ) @@ -57,7 +55,7 @@ func testSupportBundle(name string, t *testing.T) { } defer teardownTest(t, data) - var podName, tokenPath string + var podName string var podPort int if name == "controller" { var pod *v1.Pod @@ -65,15 +63,13 @@ func testSupportBundle(name string, t *testing.T) { require.NoError(t, err) podName = pod.Name podPort = apis.AntreaControllerAPIPort - tokenPath = controllerapiserver.TokenPath } else { podName, err = data.getAntreaPodOnNode(controlPlaneNodeName()) require.NoError(t, err) podPort = apis.AntreaAgentAPIPort - tokenPath = agentapiserver.TokenPath } // Acquire token. - token, err := getAccessToken(podName, fmt.Sprintf("antrea-%s", name), tokenPath, data) + token, err := getAccessToken(podName, fmt.Sprintf("antrea-%s", name), apis.APIServerLoopbackTokenPath, data) require.NoError(t, err) podIP, err := data.podWaitForIPs(defaultTimeout, podName, metav1.NamespaceSystem) require.NoError(t, err)