Skip to content

Commit

Permalink
Versioned API
Browse files Browse the repository at this point in the history
Signed-off-by: Qiyue Yao <yaoq@vmware.com>
  • Loading branch information
qiyueyao committed Jan 25, 2024
1 parent 8137cd6 commit 71e6128
Show file tree
Hide file tree
Showing 54 changed files with 3,455 additions and 1,396 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,10 @@ Also check out [@ProjectAntrea](https://twitter.com/ProjectAntrea) on Twitter!
enable fine-grained visibility into the communication among Kubernetes
workloads. Theia provides visualization for Antrea network flows in Grafana
dashboards, and recommends Network Policies to secure the workloads.
* **Network Policies for virtual machines**: Antrea native policies can be
* **Network Policies for virtual machines**: Antrea-native policies can be
enforced on non-Kubernetes Nodes including VMs and baremetal servers. Project
[Nephe](https://github.com/antrea-io/nephe) implements security policies for
VMs across clouds, leveraging Antrea native policies.
VMs across clouds, leveraging Antrea-native policies.
* **Encryption**: Encryption of inter-Node Pod traffic with IPsec or WireGuard
tunnels.
* **Easy deployment**: Antrea is deployed by applying a single YAML manifest
Expand Down
8 changes: 4 additions & 4 deletions docs/antctl.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ running in three different modes:
- [controllerinfo and agentinfo commands](#controllerinfo-and-agentinfo-commands)
- [NetworkPolicy commands](#networkpolicy-commands)
- [Mapping endpoints to NetworkPolicies](#mapping-endpoints-to-networkpolicies)
- [Analyzing expected NetworkPolicies behavior](#analyzing-expected-networkpolicies-behavior)
- [Analyzing expected NetworkPolicy behavior](#analyzing-expected-networkpolicy-behavior)
- [Dumping Pod network interface information](#dumping-pod-network-interface-information)
- [Dumping OVS flows](#dumping-ovs-flows)
- [OVS packet tracing](#ovs-packet-tracing)
Expand Down Expand Up @@ -264,14 +264,14 @@ Namespace.
This command only works in "controller mode" and **as of now it can only be run
from inside the Antrea Controller Pod, and not from out-of-cluster**.

#### Analyzing expected NetworkPolicies behavior
#### Analyzing expected NetworkPolicy behavior

`antctl` supports analyzing all the existing Antrea Native NetworkPolicies,
`antctl` supports analyzing all the existing Antrea-native NetworkPolicies,
Kubernetes NetworkPolicies and AdminNetworkPolicies to predict the effective
policy rule for traffic between source and destination Pods.

```bash
antctl query networkpolicyanalysis -S NAMESPACE/POD -D NAMESPACE/POD
antctl query effectivepolicyrule -S NAMESPACE/POD -D NAMESPACE/POD
```

If only Pod name is provided, the command will default to the "default" Namespace.
Expand Down
2 changes: 1 addition & 1 deletion docs/feature-gates.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ This feature is currently only supported for Nodes running Linux. Windows suppor
Stats API, which can be accessed by kubectl get commands, e.g. `kubectl get networkpolicystats`. The statistical data
includes total number of sessions, packets, and bytes allowed or denied by a NetworkPolicy. It is collected
asynchronously so there may be a delay of up to 1 minute for changes to be reflected in API responses. The feature
supports K8s NetworkPolicies and Antrea native policies, the latter of which requires
supports K8s NetworkPolicies and Antrea-native policies, the latter of which requires
`AntreaPolicy` to be enabled. Usage examples:

```bash
Expand Down
2 changes: 1 addition & 1 deletion docs/multicluster/user-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

Antrea Multi-cluster implements [Multi-cluster Service API](https://github.com/kubernetes/enhancements/tree/master/keps/sig-multicluster/1645-multi-cluster-services-api),
which allows users to create multi-cluster Services that can be accessed cross
clusters in a ClusterSet. Antrea Multi-cluster also extends Antrea native
clusters in a ClusterSet. Antrea Multi-cluster also extends Antrea-native
NetworkPolicy to support Multi-cluster NetworkPolicy rules that apply to
cross-cluster traffic, and ClusterNetworkPolicy replication that allows a
ClusterSet admin to create ClusterNetworkPolicies which are replicated across
Expand Down
2 changes: 1 addition & 1 deletion docs/traceflow-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ will fail. But you can specify a different timeout value, by adding
`timeout: <value-in-seconds>` to the Traceflow `spec`.

In some cases, it might be useful to capture the packets dropped by
NetworkPolicies (inc. K8s NetworkPolicies or Antrea native policies). You can
NetworkPolicies (inc. K8s NetworkPolicies or Antrea-native policies). You can
add `droppedOnly: true` to the live-traffic Traceflow `spec`, then the first
packet that matches the Traceflow spec and is dropped by a NetworkPolicy will
be captured and traced.
Expand Down
2 changes: 1 addition & 1 deletion hack/update-codegen-dockerized.sh
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ MOCKGEN_TARGETS=(
"pkg/agent/util/netlink Interface testing mock_netlink_linux.go"
"pkg/agent/wireguard Interface testing mock_wireguard.go"
"pkg/antctl AntctlClient ."
"pkg/controller/networkpolicy EndpointQuerier testing"
"pkg/controller/networkpolicy EndpointQuerier,PolicyRuleQuerier testing"
"pkg/controller/querier ControllerQuerier testing"
"pkg/flowaggregator/exporter Interface testing"
"pkg/ipfix IPFIXExportingProcess,IPFIXRegistry,IPFIXCollectingProcess,IPFIXAggregationProcess testing"
Expand Down
2 changes: 1 addition & 1 deletion pkg/agent/controller/networkpolicy/audit_logging.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ func getNetworkPolicyInfo(pktIn *ofctrl.PacketIn, packet *binding.Packet, c *Con
ob.ofPriority = ofPriority
ob.ruleName = ruleName
ob.logLabel = logLabel
// Fill in placeholders for Antrea native policies without log labels,
// Fill in placeholders for Antrea-native policies without log labels,
// K8s NetworkPolicies without rule names or log labels.
fillLogInfoPlaceholders([]*string{&ob.ruleName, &ob.logLabel, &ob.ofPriority})
return nil
Expand Down
23 changes: 13 additions & 10 deletions pkg/antctl/antctl.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ $ antctl get podmulticaststats pod -n namespace`,
},
{
name: "type",
usage: "Get NetworkPolicies with specific type. Type means the type of its source network policy: K8sNP, ACNP, ANNP",
usage: "Get NetworkPolicies with specific type. Type means the type of its source NetworkPolicy: K8sNP, ACNP, ANNP",
shorthand: "T",
},
}, getSortByFlag()),
Expand Down Expand Up @@ -509,17 +509,18 @@ $ antctl get podmulticaststats pod -n namespace`,
},
transformedResponse: reflect.TypeOf(endpointServer.EndpointQueryResponse{}),
},
{use: "networkpolicyanalysis",
aliases: []string{"npanalysis"},
short: "Analyze network policy rules.",
{
use: "effectivepolicyrule",
aliases: []string{"effectiverule"},
short: "Analyze effective NetworkPolicy rules.",
long: "Analyze network policies in the cluster and return the rule expected to be effective on the source and destination endpoints provided.",
example: ` Query effective network policy rule between two pods
$ antctl query networkpolicyanalysis -S ns1/pod1 -D ns2/pod2
example: ` Query effective NetworkPolicy rule between two Pods
$ antctl query effectivepolicyrule -S ns1/pod1 -D ns2/pod2
`,
commandGroup: query,
controllerEndpoint: &endpoint{
nonResourceEndpoint: &nonResourceEndpoint{
path: "/networkpolicyanalysis",
resourceEndpoint: &resourceEndpoint{
groupVersionResource: &cpv1beta.NetworkPolicyAccessReviewVersionResource,
params: []flagInfo{
{
name: "source",
Expand All @@ -532,10 +533,12 @@ $ antctl get podmulticaststats pod -n namespace`,
shorthand: "D",
},
},
outputType: single,
paramsFormatter: networkpolicy.NewNetworkPolicyAccessReview,
restMethod: restPost,
},
addonTransform: networkpolicy.AccessTransform,
},
transformedResponse: reflect.TypeOf(endpointServer.Rule{}),
transformedResponse: reflect.TypeOf(networkpolicy.AccessResponse{}),
},
{
use: "flowrecords",
Expand Down
26 changes: 21 additions & 5 deletions pkg/antctl/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,22 +161,38 @@ func (c *client) resourceRequest(e *resourceEndpoint, opt *requestOption) (io.Re
// If timeout is zero, there will be no timeout.
restClient.Client.Timeout = opt.timeout

resGetter := restClient.Get().
var restRequest *rest.Request
if e.restMethod == restGet {
restRequest = restClient.Get()
} else if e.restMethod == restPost {
restRequest = restClient.Post()
}

restRequest = restRequest.
NamespaceIfScoped(opt.args["namespace"], e.namespaced).
Resource(e.groupVersionResource.Resource)

if len(e.resourceName) != 0 {
resGetter = resGetter.Name(e.resourceName)
restRequest = restRequest.Name(e.resourceName)
} else if name, ok := opt.args["name"]; ok {
resGetter = resGetter.Name(name)
restRequest = restRequest.Name(name)
}

for arg, val := range opt.args {
if arg != "name" && arg != "namespace" {
resGetter = resGetter.Param(arg, val)
restRequest = restRequest.Param(arg, val)
}
}
result := resGetter.Do(context.TODO())

if e.paramsFormatter != nil {
obj, err := e.paramsFormatter(opt.args)
if err != nil {
return nil, err
}
restRequest = restRequest.Body(obj)
}

result := restRequest.Do(context.TODO())
if result.Error() != nil {
return nil, generateMessage(opt.commandDefinition, opt.args, true /* isResourceRequest */, result.Error())
}
Expand Down
48 changes: 18 additions & 30 deletions pkg/antctl/command_definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@ import (

"github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
apiRuntime "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/klog/v2"

"antrea.io/antrea/pkg/antctl/output"
"antrea.io/antrea/pkg/antctl/runtime"
"antrea.io/antrea/pkg/apis/controlplane/v1beta2"
"antrea.io/antrea/pkg/apis/controlplane"
endpointServer "antrea.io/antrea/pkg/apiserver/handlers/endpoint"
)

Expand Down Expand Up @@ -108,6 +109,9 @@ type resourceEndpoint struct {
resourceName string
namespaced bool
supportSorting bool
params []flagInfo
paramsFormatter func(args map[string]string) (apiRuntime.Object, error)
restMethod restMethod
}

func (e *resourceEndpoint) OutputType() OutputType {
Expand Down Expand Up @@ -138,6 +142,7 @@ func (e *resourceEndpoint) flags() []flagInfo {
if e.supportSorting {
flags = append(flags, getSortByFlag())
}
flags = append(flags, e.params...)
return flags
}

Expand All @@ -149,6 +154,13 @@ func getSortByFlag() flagInfo {
}
}

type restMethod uint

const (
restGet restMethod = iota
restPost
)

type nonResourceEndpoint struct {
path string
params []flagInfo
Expand Down Expand Up @@ -455,10 +467,10 @@ func (cd *commandDefinition) tableOutputForQueryEndpoint(obj interface{}, writer
// transform egress and ingress rules to string representation
egress, ingress := make([][]string, 0), make([][]string, 0)
for _, rule := range endpoint.Rules {
ruleStr := []string{rule.Name, rule.Namespace, strconv.Itoa(rule.RuleIndex), string(rule.UID)}
if rule.Direction == v1beta2.DirectionIn {
ruleStr := []string{rule.PolicyRef.Name, rule.PolicyRef.Namespace, strconv.Itoa(rule.RuleIndex), string(rule.PolicyRef.UID)}
if rule.Direction == controlplane.DirectionIn {
ingress = append(ingress, ruleStr)
} else if rule.Direction == v1beta2.DirectionOut {
} else if rule.Direction == controlplane.DirectionOut {
egress = append(egress, ruleStr)
}
}
Expand Down Expand Up @@ -497,27 +509,6 @@ func (cd *commandDefinition) tableOutputForQueryEndpoint(obj interface{}, writer
return nil
}

// tableOutputForQueryNetworkPolicyAnalysis implements printing rule as query result
func (cd *commandDefinition) tableOutputForQueryNetworkPolicyAnalysis(obj interface{}, writer io.Writer) error {
constructTable := func(header []string, body []string) error {
rows := [][]string{header, body}
numRows, numCol := len(rows), len(rows[0])
widths := output.GetColumnWidths(numRows, numCol, rows)
if err := output.ConstructTable(numRows, numCol, widths, rows, writer); err != nil {
return err
}
return nil
}
queryResponse := obj.(*endpointServer.Rule)
if queryResponse.Name != "" {
ruleStr := []string{queryResponse.Name, queryResponse.Namespace, string(queryResponse.Type), strconv.Itoa(queryResponse.RuleIndex), string(queryResponse.Direction)}
if err := constructTable([]string{"Name", "Namespace", "PolicyType", "RuleIndex", "Direction"}, ruleStr); err != nil {
return err
}
}
return nil
}

// output reads bytes from the resp and outputs the data to the writer in desired
// format. If the AddonTransform is set, it will use the function to transform
// the data first. It will try to output the resp in the format ft specified after
Expand Down Expand Up @@ -560,12 +551,10 @@ func (cd *commandDefinition) output(resp io.Reader, writer io.Writer, ft formatt
if cd.commandGroup == get {
return output.TableOutputForGetCommands(obj, writer)
} else if cd.commandGroup == query {
if cd.controllerEndpoint.nonResourceEndpoint.path == "/endpoint" {
if cd.controllerEndpoint.nonResourceEndpoint != nil && cd.controllerEndpoint.nonResourceEndpoint.path == "/endpoint" {
return cd.tableOutputForQueryEndpoint(obj, writer)
}
if cd.controllerEndpoint.nonResourceEndpoint.path == "/networkpolicyanalysis" {
return cd.tableOutputForQueryNetworkPolicyAnalysis(obj, writer)
}
return output.TableOutputForGetCommands(obj, writer)
} else {
return output.TableOutput(obj, writer)
}
Expand All @@ -574,7 +563,6 @@ func (cd *commandDefinition) output(resp io.Reader, writer io.Writer, ft formatt
default:
return fmt.Errorf("unsupported format type: %v", ft)
}
return nil
}

func (cd *commandDefinition) collectFlags(cmd *cobra.Command, args []string) (map[string]string, error) {
Expand Down
56 changes: 10 additions & 46 deletions pkg/antctl/command_definition_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -910,8 +910,8 @@ func TestGetRequestErrorFallback(t *testing.T) {
}

func TestTableOutputForQueryEndpoint(t *testing.T) {
policyRef0 := endpointServer.PolicyRef{Namespace: "testNamespace", Name: "test-ingress-egress", UID: "uid-1"}
policyRef1 := endpointServer.PolicyRef{Namespace: "testNamespace", Name: "default-deny-egress", UID: "uid-2"}
policyRef0 := controlplane.NetworkPolicyReference{Namespace: "testNamespace", Name: "test-ingress-egress", UID: "uid-1", Type: controlplane.AntreaNetworkPolicy}
policyRef1 := controlplane.NetworkPolicyReference{Namespace: "testNamespace", Name: "default-deny-egress", UID: "uid-2", Type: controlplane.AntreaNetworkPolicy}
tc := []struct {
name string
rawResponseData interface{}
Expand All @@ -921,7 +921,7 @@ func TestTableOutputForQueryEndpoint(t *testing.T) {
name: "Pod selected by no policy",
rawResponseData: &endpointServer.EndpointQueryResponse{
Endpoints: []endpointServer.Endpoint{
{Namespace: "testNamespace", Name: "podA", Policies: []endpointServer.Policy{}, Rules: []endpointServer.Rule{}},
{Namespace: "testNamespace", Name: "podA", Policies: []controlplane.NetworkPolicyReference{}, Rules: []endpointServer.Rule{}},
},
},
expected: `Endpoint testNamespace/podA
Expand All @@ -940,10 +940,10 @@ Ingress Rules: None
{
Namespace: "testNamespace",
Name: "podA",
Policies: []endpointServer.Policy{{PolicyRef: policyRef0}},
Policies: []controlplane.NetworkPolicyReference{policyRef0},
Rules: []endpointServer.Rule{
{PolicyRef: policyRef0, Direction: cpv1beta.DirectionOut, RuleIndex: 0},
{PolicyRef: policyRef0, Direction: cpv1beta.DirectionIn, RuleIndex: 0},
{PolicyRef: policyRef0, Direction: controlplane.DirectionOut, RuleIndex: 0},
{PolicyRef: policyRef0, Direction: controlplane.DirectionIn, RuleIndex: 0},
},
},
},
Expand All @@ -970,13 +970,12 @@ test-ingress-egress testNamespace 0 uid-1
{
Namespace: "testNamespace",
Name: "podA",
Policies: []endpointServer.Policy{
{PolicyRef: policyRef0},
{PolicyRef: policyRef1},
Policies: []controlplane.NetworkPolicyReference{
policyRef0, policyRef1,
},
Rules: []endpointServer.Rule{
{PolicyRef: policyRef0, Direction: cpv1beta.DirectionOut, RuleIndex: 0},
{PolicyRef: policyRef0, Direction: cpv1beta.DirectionIn, RuleIndex: 0},
{PolicyRef: policyRef0, Direction: controlplane.DirectionOut, RuleIndex: 0},
{PolicyRef: policyRef0, Direction: controlplane.DirectionIn, RuleIndex: 0},
},
},
},
Expand Down Expand Up @@ -1009,41 +1008,6 @@ test-ingress-egress testNamespace 0 uid-1
}
}

func TestTableOutputForQueryNetworkPolicyAnalysis(t *testing.T) {
policyRef0 := endpointServer.PolicyRef{Type: controlplane.K8sNetworkPolicy, Namespace: "testNamespace", Name: "test-default-deny", UID: "uid-1"}
tc := []struct {
name string
rawResponseData interface{}
expected string
}{
{
name: "No matching rule",
rawResponseData: &endpointServer.Rule{},
expected: ``,
},
{
name: "Matched KNP default drop rule",
rawResponseData: &endpointServer.Rule{
PolicyRef: policyRef0,
Direction: cpv1beta.DirectionIn,
RuleIndex: -1,
},
expected: `Name Namespace PolicyType RuleIndex Direction
test-default-deny testNamespace K8sNetworkPolicy -1 In
`,
},
}
for _, tt := range tc {
t.Run(tt.name, func(t *testing.T) {
cd := &commandDefinition{}
var outputBuf bytes.Buffer
err := cd.tableOutputForQueryNetworkPolicyAnalysis(tt.rawResponseData, &outputBuf)
assert.Nil(t, err)
assert.Equal(t, tt.expected, outputBuf.String())
})
}
}

func TestCollectFlags(t *testing.T) {
tc := []struct {
name string
Expand Down
Loading

0 comments on commit 71e6128

Please sign in to comment.