Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize package organization to reduce antctl binary size #6037

Merged
merged 1 commit into from
Mar 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cmd/antrea-agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -893,6 +894,7 @@ func run(o *Options) error {
authorization,
*o.config.EnablePrometheusMetrics,
o.config.ClientConnection.Kubeconfig,
apis.APIServerLoopbackTokenPath,
v4Enabled,
v6Enabled)
if err != nil {
Expand Down
8 changes: 4 additions & 4 deletions cmd/antrea-controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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())

Expand Down Expand Up @@ -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(
Expand Down
16 changes: 16 additions & 0 deletions pkg/agent/apis/doc.go
Original file line number Diff line number Diff line change
@@ -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
192 changes: 192 additions & 0 deletions pkg/agent/apis/types.go
Original file line number Diff line number Diff line change
@@ -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
}
10 changes: 5 additions & 5 deletions pkg/agent/apiserver/apiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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
}
Expand All @@ -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 {
Expand All @@ -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()
Expand Down
28 changes: 8 additions & 20 deletions pkg/agent/apiserver/apiserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"sync"
"testing"
"time"
Expand All @@ -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:
Expand All @@ -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)
Expand All @@ -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,
Expand Down
Loading
Loading