├── .dockerignore ├── .github ├── .codecov.yml ├── ISSUE_TEMPLATE │ ├── bug-report.md │ ├── enhancement.md │ └── support-request.md ├── PULL_REQUEST_TEMPLATE.md ├── actions │ └── govulncheck │ │ └── action.yaml ├── dependabot.yml └── workflows │ ├── deps.yml │ ├── integration-tests.yaml │ ├── issue-closed-message.yaml │ ├── issue-stale-pr.yaml │ ├── kops-test.yaml │ ├── nightly-cron-tests.yaml │ ├── pr-automated-tests.yaml │ ├── pr-manual-tests.yaml │ ├── release.yaml │ ├── update.yml │ └── weekly-cron-tests.yaml ├── .gitignore ├── .go-version ├── .mailmap ├── CHANGELOG.md ├── CODEOWNERS ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── Makefile ├── README.md ├── charts ├── aws-vpc-cni │ ├── .helmignore │ ├── Chart.yaml │ ├── README.md │ ├── crds │ │ ├── customresourcedefinition.yaml │ │ └── kustomization.yaml │ ├── templates │ │ ├── NOTES.txt │ │ ├── _helpers.tpl │ │ ├── clusterrole.yaml │ │ ├── clusterrolebinding.yaml │ │ ├── configmap.yaml │ │ ├── daemonset.yaml │ │ ├── eniconfig.yaml │ │ ├── podmonitor.yaml │ │ └── serviceaccount.yaml │ └── values.yaml ├── cni-metrics-helper │ ├── .helmignore │ ├── Chart.yaml │ ├── README.md │ ├── templates │ │ ├── NOTES.txt │ │ ├── _helpers.tpl │ │ ├── clusterrole.yaml │ │ ├── clusterrolebinding.yaml │ │ ├── deployment.yaml │ │ └── serviceaccount.yaml │ └── values.yaml └── regions.json ├── cmd ├── aws-k8s-agent │ └── main.go ├── aws-vpc-cni-init │ └── main.go ├── aws-vpc-cni │ ├── main.go │ └── main_test.go ├── cni-metrics-helper │ ├── README.md │ ├── main.go │ └── metrics │ │ ├── cni_metrics.go │ │ ├── cni_metrics_test.go │ │ ├── cni_test1.data │ │ ├── cni_test2.data │ │ ├── metrics.go │ │ ├── metrics_test.go │ │ └── pod_watcher.go ├── egress-cni-plugin │ ├── egressContext.go │ ├── main.go │ ├── main_test.go │ ├── netconf.go │ ├── snat │ │ ├── snat.go │ │ └── snat_test.go │ └── test_utils.go ├── grpc-health-probe │ └── main.go └── routed-eni-cni-plugin │ ├── cni.go │ ├── cni_test.go │ └── driver │ ├── driver.go │ ├── driver_test.go │ ├── generate_mocks.go │ └── mocks │ └── driver_mocks.go ├── config ├── master │ ├── aws-k8s-cni-cn.yaml │ ├── aws-k8s-cni-us-gov-east-1.yaml │ ├── aws-k8s-cni-us-gov-west-1.yaml │ ├── aws-k8s-cni.yaml │ ├── cni-metrics-helper-cn.yaml │ ├── cni-metrics-helper-us-gov-east-1.yaml │ ├── cni-metrics-helper-us-gov-west-1.yaml │ └── cni-metrics-helper.yaml └── multus │ ├── README.md │ ├── v3.7.2-eksbuild.1 │ ├── aws-k8s-multus-cn.yaml │ ├── aws-k8s-multus-us-gov-east-1.yaml │ ├── aws-k8s-multus-us-gov-west-1.yaml │ └── aws-k8s-multus.yaml │ ├── v3.7.2-eksbuild.2 │ ├── Readme.md │ ├── aws-k8s-multus-cn.yaml │ ├── aws-k8s-multus-us-gov-east-1.yaml │ ├── aws-k8s-multus-us-gov-west-1.yaml │ └── aws-k8s-multus.yaml │ ├── v3.8.0-eksbuild.1 │ ├── Readme.md │ ├── aws-k8s-multus-cn.yaml │ ├── aws-k8s-multus-us-gov-east-1.yaml │ ├── aws-k8s-multus-us-gov-west-1.yaml │ └── aws-k8s-multus.yaml │ ├── v3.9.0-eksbuild.1 │ ├── Readme.md │ ├── aws-k8s-multus-cn.yaml │ ├── aws-k8s-multus-us-gov-east-1.yaml │ ├── aws-k8s-multus-us-gov-west-1.yaml │ └── aws-k8s-multus.yaml │ ├── v3.9.0-eksbuild.2 │ ├── Readme.md │ ├── aws-k8s-multus-cn.yaml │ ├── aws-k8s-multus-us-gov-east-1.yaml │ ├── aws-k8s-multus-us-gov-west-1.yaml │ └── aws-k8s-multus.yaml │ ├── v3.9.1-eksbuild.1 │ ├── Readme.md │ ├── aws-k8s-multus-cn.yaml │ ├── aws-k8s-multus-us-gov-east-1.yaml │ ├── aws-k8s-multus-us-gov-west-1.yaml │ └── aws-k8s-multus.yaml │ ├── v3.9.2-eksbuild.1 │ ├── Readme.md │ ├── aws-k8s-multus-cn.yaml │ ├── aws-k8s-multus-us-gov-east-1.yaml │ ├── aws-k8s-multus-us-gov-west-1.yaml │ └── aws-k8s-multus.yaml │ ├── v4.0.2-eksbuild.1 │ └── multus-daemonset-thick.yml │ ├── v4.1.4-eksbuild.1 │ └── multus-daemonset-thick.yml │ └── v4.1.4-eksbuild.3 │ └── multus-daemonset-thick.yml ├── docs ├── cni-proposal.md ├── eni-and-ip-target.md ├── iam-policy.md ├── images │ ├── EKS_CNI_metrics.png │ ├── cni-metrics-100.png │ ├── cni-metrics-helper.png │ ├── cni-metrics-inprogress.png │ ├── ipam.png │ ├── ping.png │ ├── ping2external.png │ ├── subnet.png │ └── wire-network.png ├── network-policy-faq.md ├── prefix-and-ip-target.md └── troubleshooting.md ├── go.mod ├── go.sum ├── hack └── ec2_preview_models │ ├── api-2.json │ ├── docs-2.json │ ├── examples-1.json │ └── paginators-1.json ├── misc ├── 10-aws.conflist ├── certs │ └── ca-certificates.crt └── eni-max-pods.txt ├── pkg ├── apis │ └── crd │ │ └── v1alpha1 │ │ ├── eniconfig_types.go │ │ ├── groupversion_info.go │ │ └── zz_generated.deepcopy.go ├── awsutils │ ├── awssession │ │ ├── session.go │ │ └── session_test.go │ ├── awsutils.go │ ├── awsutils_test.go │ ├── generate_mocks.go │ ├── imds.go │ ├── imds_test.go │ └── mocks │ │ └── awsutils_mocks.go ├── cninswrapper │ ├── generate_mocks.go │ └── mock_ns │ │ └── netns_mocks.go ├── ec2metadatawrapper │ ├── ec2metadatawrapper.go │ ├── ec2metadatawrapper_test.go │ ├── generate_mocks.go │ └── mocks │ │ └── ec2metadatawrapper_mocks.go ├── ec2wrapper │ ├── client.go │ ├── ec2wrapper.go │ ├── ec2wrapper_test.go │ ├── generate_mocks.go │ └── mocks │ │ └── ec2wrapper_mocks.go ├── eniconfig │ ├── eniconfig.go │ ├── eniconfig_test.go │ ├── generate_mocks.go │ └── mocks │ │ └── eniconfig_mocks.go ├── grpcwrapper │ ├── client.go │ ├── generate_mocks.go │ └── mocks │ │ └── grpcwrapper_mocks.go ├── hostipamwrapper │ ├── generate_mocks.go │ ├── hostipam.go │ └── mocks │ │ └── hostipam_mocks.go ├── ipamd │ ├── datastore │ │ ├── checkpoint.go │ │ ├── data_store.go │ │ └── data_store_test.go │ ├── introspect.go │ ├── ipamd.go │ ├── ipamd_test.go │ ├── rpc_handler.go │ └── rpc_handler_test.go ├── iptableswrapper │ ├── generate_mocks.go │ ├── iptables.go │ └── mocks │ │ ├── iptables_maps.go │ │ └── iptables_mocks.go ├── ipwrapper │ ├── generate_mocks.go │ ├── ip.go │ └── mocks │ │ └── ipwrapper_mocks.go ├── k8sapi │ ├── k8sutils.go │ └── k8sutils_test.go ├── netlinkwrapper │ ├── generate_mocks.go │ ├── mock_netlink │ │ └── link_mocks.go │ ├── mocks │ │ └── netlinkwrapper_mocks.go │ ├── mocks_link │ │ └── link_mocks.go │ └── netlink.go ├── networkutils │ ├── generate_mocks.go │ ├── mocks │ │ └── network_mocks.go │ ├── names.go │ ├── names_test.go │ ├── network.go │ └── network_test.go ├── nswrapper │ ├── generate_mocks.go │ ├── mocks │ │ └── nswrapper_mocks.go │ └── ns.go ├── procsyswrapper │ ├── generate_mocks.go │ ├── mocks │ │ └── procsys_mocks.go │ └── procsys.go ├── publisher │ ├── generate_mocks.go │ ├── mock_publisher │ │ └── mock_publisher.go │ ├── publisher.go │ └── publisher_test.go ├── rpcwrapper │ ├── client.go │ ├── generate_mocks.go │ └── mocks │ │ └── rpcwrapper_mocks.go ├── sgpp │ ├── constants.go │ ├── utils.go │ └── utils_test.go ├── typeswrapper │ ├── client.go │ ├── generate_mocks.go │ └── mocks │ │ └── typeswrapper_mocks.go ├── utils │ ├── cniutils │ │ ├── cni_utils.go │ │ └── cni_utils_test.go │ ├── eventrecorder │ │ ├── eventrecorder.go │ │ └── eventrecorder_test.go │ ├── logger │ │ ├── config.go │ │ ├── logger.go │ │ ├── logger_test.go │ │ └── zaplogger.go │ ├── retry │ │ ├── backoff.go │ │ ├── backoff_test.go │ │ ├── errors.go │ │ ├── retry.go │ │ └── retry_test.go │ └── ttime │ │ ├── generate_mocks.go │ │ ├── mocks │ │ └── time_mocks.go │ │ └── ttime.go ├── version │ └── info.go ├── vethwrapper │ ├── generate_mocks.go │ ├── mocks │ │ └── veth_mocks.go │ └── veth.go └── vpc │ ├── vpc.go │ ├── vpc_ip_resource_limit.go │ └── vpc_test.go ├── rpc ├── generate_mocks.go ├── mocks │ └── rpc_mocks.go ├── rpc.pb.go └── rpc.proto ├── scripts ├── README.md ├── copyright.txt ├── dockerfiles │ ├── Dockerfile.init │ ├── Dockerfile.metrics │ ├── Dockerfile.release │ └── Dockerfile.test ├── ec2_model_override │ ├── cleanup.sh │ └── setup.sh ├── gen_vpc_ip_limits.go ├── generate-cni-yaml.sh ├── lib │ ├── add-on.sh │ ├── aws.sh │ ├── canary.sh │ ├── cluster.sh │ ├── common.sh │ ├── integration.sh │ ├── k8s.sh │ ├── performance_tests.sh │ └── set_kubeconfig.sh ├── protoc-gen-go ├── run-canary-test.sh ├── run-cni-release-tests.sh ├── run-ginkgo-integration-suite.sh ├── run-integration-tests.sh ├── run-ipv6-canary-test.sh ├── run-ipv6-integration-tests.sh ├── run-multus-tests.sh ├── run-release-tests.sh ├── run-soak-test.sh ├── run-static-canary.sh ├── sync-to-config-folder.sh ├── sync-to-eks-charts.sh ├── test │ ├── config │ │ ├── bottlerocket.yaml │ │ ├── cluster-autoscaler-autodiscover.yml │ │ ├── perf-cluster.yml │ │ └── test-cluster.yaml │ └── run-integration-tests.sh └── update-cni-images.sh ├── test ├── README.md ├── _cmd │ └── packet-verifier │ │ ├── Dockerfile │ │ ├── example │ │ └── packetverifier_pod.yaml │ │ └── packet-verifier.go ├── agent │ ├── Dockerfile │ ├── Makefile │ ├── README.md │ ├── cmd │ │ ├── metric-server │ │ │ └── main.go │ │ ├── networking │ │ │ ├── main.go │ │ │ └── tester │ │ │ │ └── network.go │ │ ├── snat-utils │ │ │ └── main.go │ │ ├── traffic-client │ │ │ └── main.go │ │ └── traffic-server │ │ │ └── main.go │ ├── go.mod │ ├── go.sum │ └── pkg │ │ └── input │ │ └── input.go ├── framework │ ├── controller │ │ ├── constant.go │ │ └── installation_manager.go │ ├── framework.go │ ├── helm │ │ └── release_manager.go │ ├── options.go │ ├── resources │ │ ├── agent │ │ │ └── traffic_tester.go │ │ ├── aws │ │ │ ├── cloud.go │ │ │ ├── services │ │ │ │ ├── autoscaling.go │ │ │ │ ├── cloudformation.go │ │ │ │ ├── cloudwatch.go │ │ │ │ ├── ec2.go │ │ │ │ ├── eks.go │ │ │ │ └── iam.go │ │ │ └── utils │ │ │ │ └── nodegroup.go │ │ └── k8s │ │ │ ├── manager.go │ │ │ ├── manifest │ │ │ ├── container.go │ │ │ ├── daemonset.go │ │ │ ├── deployment.go │ │ │ ├── eniconfig.go │ │ │ ├── job.go │ │ │ ├── pod.go │ │ │ └── service.go │ │ │ ├── resources │ │ │ ├── configmap.go │ │ │ ├── daemonset.go │ │ │ ├── deployment.go │ │ │ ├── eniconfig.go │ │ │ ├── events.go │ │ │ ├── job.go │ │ │ ├── namespace.go │ │ │ ├── networkpolicy.go │ │ │ ├── node.go │ │ │ ├── pod.go │ │ │ └── service.go │ │ │ └── utils │ │ │ ├── addon.go │ │ │ ├── container.go │ │ │ ├── daemonset.go │ │ │ └── node.go │ └── utils │ │ ├── const.go │ │ ├── image.go │ │ ├── log.go │ │ └── utils.go ├── helm │ ├── charts │ │ └── cni-metrics-helper │ │ │ ├── .helmignore │ │ │ ├── Chart.yaml │ │ │ ├── templates │ │ │ ├── _helpers.tpl │ │ │ ├── deployment.yaml │ │ │ ├── rbac.yaml │ │ │ └── serviceaccount.yaml │ │ │ └── values.yaml │ └── helm-lint.sh └── integration │ ├── README.md │ ├── Troubleshooting.md │ ├── az-traffic │ ├── pod_az_traffic_suite_test.go │ └── pod_traffic_across_az_test.go │ ├── calico │ ├── calico_suite_test.go │ └── calico_test.go │ ├── cni-egress │ ├── pod_egress_suite_test.go │ └── pod_egress_test.go │ ├── cni-upgrade-downgrade │ ├── host_networking_test.go │ ├── pod_traffic_PD_enabled_test.go │ └── upgrade_downgrade_suite_test.go │ ├── cni │ ├── host_networking_test.go │ ├── pod_networking_suite_test.go │ ├── pod_traffic_test.go │ ├── pod_traffic_test_PD_enabled.go │ ├── pod_traffic_test_PD_toggle.go │ ├── service_connectivity_test.go │ ├── soak_test.go │ └── vpc_cni_logfile_test.go │ ├── common │ └── util.go │ ├── custom-networking-sgpp │ ├── custom_networking_sgpp_suite_test.go │ ├── custom_networking_sgpp_test.go │ └── trunk_test.go │ ├── custom-networking │ ├── custom_networking_suite_test.go │ └── custom_networking_test.go │ ├── eni-subnet-discovery │ ├── eni_subnet_discovery_suite_test.go │ └── eni_subnet_discovery_test.go │ ├── ipamd │ ├── common.go │ ├── eni_ip_leak_test.go │ ├── eni_tag_test.go │ ├── introspection_test.go │ ├── ipamd_event_test.go │ ├── ipamd_suite_test.go │ ├── metrics_test.go │ ├── warm_target_test.go │ └── warm_target_test_PD_enabled.go │ ├── ipv6 │ ├── ipv6_host_networking_test.go │ ├── ipv6_service_connectivity_test.go │ ├── pod_traffic_test_v6_PD_enabled.go │ └── pod_v6_networking_suite_test.go │ ├── metrics-helper │ ├── metric_helper_test.go │ └── metrics_helper_suite_test.go │ ├── multus │ ├── multus_setup_suite_test.go │ └── multus_setup_test.go │ ├── pod-eni │ ├── security_group_per_pod_suite_test.go │ └── security_group_per_pod_test.go │ └── snat │ ├── snat_suite_test.go │ └── snat_test.go ├── testdata ├── amazon-eks-cni-policy-v4.json ├── amazon-eks-nodegroup.yaml ├── deploy-130-pods.yaml ├── deploy-5000-pods.yaml ├── deploy-730-pods.yaml ├── dummy-role-policy.json ├── executable └── regular-file.txt └── utils ├── constants.go ├── cp └── cp.go ├── imds └── imds.go ├── prometheusmetrics └── prometheusmetrics.go ├── utils.go └── utils_test.go /.dockerignore: -------------------------------------------------------------------------------- 1 | aws-cni 2 | aws-k8s-agent 3 | cni-metrics-helper 4 | grpc-health-probe 5 | portmap 6 | loopback 7 | bandwidth 8 | routed-eni-cni-plugin 9 | -------------------------------------------------------------------------------- /.github/.codecov.yml: -------------------------------------------------------------------------------- 1 | # To validate: 2 | # cat codecov.yml | curl --data-binary @- https://codecov.io/validate 3 | 4 | codecov: 5 | # Avoid "Missing base report" 6 | # https://docs.codecov.io/docs/comparing-commits 7 | allow_coverage_offsets: true 8 | notify: 9 | require_ci_to_pass: yes 10 | 11 | coverage: 12 | precision: 2 13 | round: down 14 | range: "50...75" 15 | 16 | status: 17 | project: 18 | default: 19 | threshold: 1 20 | unittest: 21 | threshold: 1 22 | only_pulls: true 23 | flags: 24 | - "unittest" 25 | # Disable patch since it is noisy and not correct 26 | patch: 27 | default: 28 | enabled: no 29 | if_not_found: success 30 | 31 | comment: false 32 | 33 | ignore: 34 | - "cmd/**/main.go" 35 | - "config/**/*" 36 | - "docs/**/*" 37 | - "misc/**/*" 38 | - "rpc/**/*" 39 | - "scripts/**/*" 40 | - "test/**/*" 41 | - "testdata/**/*" 42 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug Report 3 | about: Report a bug in amazon-vpc-cni-k8s project. 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | 17 | 18 | **What happened**: 19 | 22 | 23 | **Attach logs** 24 | 27 | 28 | **What you expected to happen**: 29 | 30 | **How to reproduce it (as minimally and precisely as possible)**: 31 | 32 | **Anything else we need to know?**: 33 | 34 | **Environment**: 35 | - Kubernetes version (use `kubectl version`): 36 | - CNI Version 37 | - OS (e.g: `cat /etc/os-release`): 38 | - Kernel (e.g. `uname -a`): 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/enhancement.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Enhancement Request 3 | about: Suggest an enhancement to the amazon-vpc-cni-k8s project 4 | title: '' 5 | labels: enhancement, feature request 6 | assignees: '' 7 | 8 | --- 9 | 10 | 19 | 20 | **What would you like to be added**: 21 | 22 | **Why is this needed**: 23 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/support-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Support Request/Question 3 | about: Support request or question relating to amazon-vpc-cni-k8s project. 4 | title: '' 5 | labels: needs investigation, question 6 | assignees: '' 7 | 8 | --- 9 | 10 | 17 | 18 | **What happened**: 19 | 20 | 25 | 26 | **Environment**: 27 | - Kubernetes version (use `kubectl version`): 28 | - CNI Version 29 | - OS (e.g: `cat /etc/os-release`): 30 | - Kernel (e.g. `uname -a`): 31 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 10 | **What type of PR is this?** 11 | 22 | 23 | **Which issue does this PR fix?**: 24 | 25 | 26 | 27 | **What does this PR do / Why do we need it?**: 28 | 29 | 30 | **Testing done on this change**: 31 | 34 | 35 | 38 | 39 | **Will this PR introduce any new dependencies?**: 40 | 43 | 44 | **Will this break upgrades or downgrades? Has updating a running cluster been tested?**: 45 | 46 | 47 | **Does this change require updates to the CNI daemonset config files to work?**: 48 | 51 | 52 | **Does this PR introduce any user-facing change?**: 53 | 58 | 59 | ```release-note 60 | 61 | ``` 62 | 63 | By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license. 64 | -------------------------------------------------------------------------------- /.github/actions/govulncheck/action.yaml: -------------------------------------------------------------------------------- 1 | name: 'golang-govulncheck-action' 2 | description: 'Run govulncheck' 3 | inputs: 4 | go-version-input: # version of Go to use for govulncheck 5 | description: 'Version of Go to use for govulncheck' 6 | required: false 7 | check-latest: 8 | description: 'Set this option to true if you want the action to always check for the latest available Go version that satisfies the version spec' 9 | required: false 10 | default: false 11 | cache: 12 | description: 'Used to specify whether Go caching is needed. Set to true, if you would like to enable caching.' 13 | required: false 14 | default: true 15 | go-package: 16 | description: 'Go Package to scan with govulncheck' 17 | required: false 18 | default: './...' 19 | work-dir: 20 | description: 'Directory in which to run govulncheck' 21 | required: false 22 | default: '.' 23 | repo-checkout: 24 | description: "Checkout the repository" 25 | required: false 26 | default: true 27 | go-version-file: 28 | description: 'Path to the go.mod or go.work file.' 29 | required: false 30 | runs: 31 | using: "composite" 32 | steps: 33 | - if: inputs.repo-checkout != false # only explicit false prevents repo checkout 34 | uses: actions/checkout@v4 35 | - uses: actions/setup-go@v4.0.0 36 | with: 37 | go-version: ${{ inputs.go-version-input }} 38 | check-latest: ${{ inputs.check-latest }} 39 | go-version-file: ${{ inputs.go-version-file }} 40 | cache: ${{ inputs.cache }} 41 | - name: Install govulncheck 42 | run: go install golang.org/x/vuln/cmd/govulncheck@latest 43 | shell: bash 44 | - name: Run govulncheck 45 | run: govulncheck -C ${{ inputs.work-dir }} ${{ inputs.go-package }} 46 | shell: bash 47 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # See https://docs.github.com/en/github/administering-a-repository/configuration-options-for-dependency-updates#package-ecosystem 2 | version: 2 3 | updates: 4 | - package-ecosystem: "gomod" 5 | directory: "/" 6 | schedule: 7 | interval: "monthly" 8 | - package-ecosystem: "gomod" 9 | directory: "/test/agent" 10 | schedule: 11 | interval: "monthly" -------------------------------------------------------------------------------- /.github/workflows/deps.yml: -------------------------------------------------------------------------------- 1 | name: "Dependency Review" 2 | on: 3 | pull_request: 4 | branches: 5 | - "master" 6 | - "release*" 7 | - "sdkv2" 8 | permissions: 9 | contents: read 10 | jobs: 11 | dependency-review: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: "Checkout Repository" 15 | uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # refs/tags/v4.1.7 16 | with: 17 | show-progress: false 18 | - name: "Dependency Review" 19 | uses: actions/dependency-review-action@72eb03d02c7872a771aacd928f3123ac62ad6d3a # refs/tags/v4.3.3 20 | govulncheck: 21 | runs-on: ubuntu-latest 22 | steps: 23 | - name: "Checkout Repository" 24 | uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # refs/tags/v4.1.7 25 | with: 26 | show-progress: false 27 | - name: Setup Go Version 28 | run: echo "GO_VERSION=$(cat .go-version)" >> $GITHUB_ENV 29 | - id: govulncheck 30 | uses: ./.github/actions/govulncheck 31 | with: 32 | go-version-input: ${{ env.GO_VERSION }} 33 | go-version-file: go.mod 34 | cache: false 35 | repo-checkout: false 36 | - id: govulncheck-tests-agent 37 | uses: ./.github/actions/govulncheck 38 | with: 39 | go-version-input: ${{ env.GO_VERSION }} 40 | go-version-file: test/agent/go.mod 41 | cache: false 42 | repo-checkout: false 43 | -------------------------------------------------------------------------------- /.github/workflows/integration-tests.yaml: -------------------------------------------------------------------------------- 1 | name: Integration tests 2 | 3 | on: 4 | push: 5 | branches: 6 | - "master" 7 | - "release*" 8 | - "sdk*" 9 | 10 | permissions: 11 | id-token: write 12 | contents: read 13 | 14 | jobs: 15 | integration-test: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: Checkout latest commit in the PR 19 | uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # refs/tags/v4.1.7 20 | - name: Set up Docker QEMU 21 | uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # refs/tags/v3.0.0 22 | - name: Set up Docker Buildx 23 | uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # refs/tags/v3.3.0 24 | - name: Set up Go 25 | uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # refs/tags/v5.0.1 26 | with: 27 | go-version: "1.24" 28 | - name: Set up tools 29 | run: | 30 | # Install ginkgo version from go.mod 31 | go install -mod=mod github.com/onsi/ginkgo/v2/ginkgo 32 | curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp 33 | sudo mv /tmp/eksctl /usr/local/bin/ 34 | - name: Set up AWS credentials 35 | uses: aws-actions/configure-aws-credentials@5579c002bb4778aa43395ef1df492868a9a1c83f # refs/tags/v4.0.2 36 | with: 37 | role-to-assume: ${{ secrets.OSS_TEST_ROLE_ARN }} 38 | role-duration-seconds: 14400 # 4 hours 39 | aws-region: ${{ secrets.AWS_DEFAULT_REGION }} 40 | - name: Run e2e tests 41 | env: 42 | DISABLE_PROMPT: true 43 | ROLE_CREATE: false 44 | ROLE_ARN: ${{ secrets.EKS_CLUSTER_ROLE_ARN }} 45 | RUN_CONFORMANCE: true 46 | run: | 47 | ./scripts/run-integration-tests.sh 48 | -------------------------------------------------------------------------------- /.github/workflows/issue-closed-message.yaml: -------------------------------------------------------------------------------- 1 | name: Closed Issue Message 2 | on: 3 | issues: 4 | types: [closed] 5 | 6 | permissions: 7 | issues: write 8 | 9 | jobs: 10 | auto_comment: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: aws-actions/closed-issue-message@3c30436c76e381c567524ba630f169f2fc0d175a # refs/tags/v1 14 | with: 15 | # These inputs are both required 16 | repo-token: "${{ secrets.GITHUB_TOKEN }}" 17 | message: | 18 | This issue is now closed. Comments on closed issues are hard for our team to see. 19 | If you need more assistance, please either tag a team member or open a new issue that references this one. 20 | -------------------------------------------------------------------------------- /.github/workflows/issue-stale-pr.yaml: -------------------------------------------------------------------------------- 1 | name: "Stale issue & PR handler" 2 | on: 3 | workflow_dispatch: 4 | schedule: 5 | - cron: "0 0 * * *" 6 | 7 | permissions: 8 | issues: write 9 | pull-requests: write 10 | 11 | jobs: 12 | stale: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e # refs/tags/v9.0.0 16 | id: stale 17 | with: 18 | ascending: true 19 | close-issue-message: "Issue closed due to inactivity." 20 | close-pr-message: "Pull request closed due to inactivity." 21 | days-before-close: 14 22 | days-before-stale: 60 23 | exempt-issue-labels: "triage-pending,review-pending" 24 | operations-per-run: 100 25 | stale-issue-message: "This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 14 days" 26 | stale-pr-message: "This pull request is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 14 days" 27 | -------------------------------------------------------------------------------- /.github/workflows/kops-test.yaml: -------------------------------------------------------------------------------- 1 | name: Kops tests 2 | 3 | on: 4 | workflow_dispatch: {} 5 | schedule: 6 | - cron: "0 15 * * *" # every day 7 | 8 | permissions: 9 | id-token: write 10 | contents: read 11 | 12 | jobs: 13 | daily-kops: 14 | if: github.repository == 'aws/amazon-vpc-cni-k8s' 15 | runs-on: ubuntu-latest 16 | steps: 17 | - name: Checkout latest commit in the PR 18 | uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # refs/tags/v4.1.7 19 | - name: Set up Docker QEMU 20 | uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # refs/tags/v3.0.0 21 | - name: Set up Docker Buildx 22 | uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # refs/tags/v3.3.0 23 | - name: Set up Go 24 | uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # refs/tags/v5.0.1 25 | with: 26 | go-version: "1.24" 27 | - name: Set up tools 28 | run: | 29 | # Install ginkgo version from go.mod 30 | go install -mod=mod github.com/onsi/ginkgo/v2/ginkgo 31 | curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp 32 | sudo mv /tmp/eksctl /usr/local/bin/ 33 | - name: Set up AWS credentials 34 | uses: aws-actions/configure-aws-credentials@5579c002bb4778aa43395ef1df492868a9a1c83f # refs/tags/v4.0.2 35 | with: 36 | role-to-assume: ${{ secrets.OSS_TEST_ROLE_ARN }} 37 | role-duration-seconds: 28800 # 8 hours 38 | aws-region: ${{ secrets.AWS_DEFAULT_REGION }} 39 | - name: Run kops tests 40 | env: 41 | DISABLE_PROMPT: true 42 | ROLE_CREATE: false 43 | ROLE_ARN: ${{ secrets.EKS_CLUSTER_ROLE_ARN }} 44 | RUN_CNI_INTEGRATION_TESTS: false 45 | RUN_KOPS_TEST: true 46 | K8S_VERSION: v1.33.0-beta.0 47 | KOPS_VERSION: v1.31.0 48 | KOPS_RUN_TOO_NEW_VERSION: 1 49 | run: | 50 | ./scripts/run-integration-tests.sh 51 | if: always() 52 | -------------------------------------------------------------------------------- /.github/workflows/nightly-cron-tests.yaml: -------------------------------------------------------------------------------- 1 | name: Nightly Cron tests 2 | 3 | on: 4 | schedule: 5 | - cron: "0 3 * * *" # every night 6 | 7 | permissions: 8 | id-token: write 9 | contents: read 10 | 11 | jobs: 12 | nightly-cron-test: 13 | if: github.repository == 'aws/amazon-vpc-cni-k8s' 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout latest commit in the PR 17 | uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # refs/tags/v4.1.7 18 | - name: Set up Docker QEMU 19 | uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # refs/tags/v3.0.0 20 | - name: Set up Docker Buildx 21 | uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # refs/tags/v3.3.0 22 | - name: Set up Go 23 | uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # refs/tags/v5.0.1 24 | with: 25 | go-version: "1.24" 26 | - name: Set up tools 27 | run: | 28 | # Install ginkgo version from go.mod 29 | go install -mod=mod github.com/onsi/ginkgo/v2/ginkgo 30 | curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp 31 | sudo mv /tmp/eksctl /usr/local/bin/ 32 | - name: Set up AWS credentials 33 | uses: aws-actions/configure-aws-credentials@5579c002bb4778aa43395ef1df492868a9a1c83f # refs/tags/v4.0.2 34 | with: 35 | role-to-assume: ${{ secrets.OSS_TEST_ROLE_ARN }} 36 | role-duration-seconds: 14400 # 4 hours 37 | aws-region: ${{ secrets.AWS_DEFAULT_REGION }} 38 | - name: Run e2e tests 39 | env: 40 | DISABLE_PROMPT: true 41 | ROLE_CREATE: false 42 | ROLE_ARN: ${{ secrets.EKS_CLUSTER_ROLE_ARN }} 43 | RUN_CONFORMANCE: true 44 | run: | 45 | ./scripts/run-integration-tests.sh 46 | -------------------------------------------------------------------------------- /.github/workflows/pr-manual-tests.yaml: -------------------------------------------------------------------------------- 1 | # Repo owner must review the PR properly before trigger this workflow manually. 2 | name: Manual Pull Request test 3 | 4 | on: 5 | workflow_dispatch: 6 | inputs: 7 | pull_request_number: 8 | description: "PR number we want to run tests on" 9 | required: true 10 | type: string 11 | 12 | permissions: 13 | id-token: write 14 | contents: read 15 | 16 | jobs: 17 | integration-test: 18 | if: github.event.inputs.pull_request_number != '' 19 | runs-on: ubuntu-latest 20 | steps: 21 | - name: Checkout latest commit in the PR 22 | uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # refs/tags/v4.1.7 23 | with: 24 | ref: "refs/pull/${{ github.event.inputs.pull_request_number }}/merge" 25 | - name: Set up Docker QEMU 26 | uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # refs/tags/v3.0.0 27 | - name: Set up Docker Buildx 28 | uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # refs/tags/v3.3.0 29 | - name: Set up Go 30 | uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # refs/tags/v5.0.1 31 | with: 32 | go-version: "1.24" 33 | - name: Set up tools 34 | run: | 35 | # Install ginkgo version from go.mod 36 | go install -mod=mod github.com/onsi/ginkgo/v2/ginkgo 37 | curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp 38 | sudo mv /tmp/eksctl /usr/local/bin/ 39 | - name: Set up AWS credentials 40 | uses: aws-actions/configure-aws-credentials@5579c002bb4778aa43395ef1df492868a9a1c83f # refs/tags/v4.0.2 41 | with: 42 | role-to-assume: ${{ secrets.OSS_TEST_ROLE_ARN }} 43 | role-duration-seconds: 14400 # 4 hours 44 | aws-region: ${{ secrets.AWS_DEFAULT_REGION }} 45 | - name: Run e2e tests 46 | env: 47 | DISABLE_PROMPT: true 48 | ROLE_CREATE: false 49 | ROLE_ARN: ${{ secrets.EKS_CLUSTER_ROLE_ARN }} 50 | RUN_CONFORMANCE: true 51 | run: | 52 | ./scripts/run-integration-tests.sh 53 | -------------------------------------------------------------------------------- /.github/workflows/release.yaml: -------------------------------------------------------------------------------- 1 | name: VPC CNI Release 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | permissions: 8 | contents: read 9 | 10 | env: 11 | GITHUB_USERNAME: ${{ secrets.EKS_BOT_GITHUB_USERNAME }} 12 | GITHUB_TOKEN: ${{ secrets.EKS_BOT_GITHUB_TOKEN }} 13 | 14 | jobs: 15 | release: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: Checkout latest commit in the PR 19 | uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # refs/tags/v4.1.7 20 | with: 21 | ref: "refs/tags/${{ github.event.release.tag_name }}" 22 | - name: Set up Go 23 | uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # refs/tags/v5.0.1 24 | with: 25 | go-version: "1.24" 26 | - name: Generate CNI YAML 27 | run: make generate-cni-yaml 28 | - name: Create eks-charts PR 29 | run: make ekscharts-sync-release 30 | - name: Create sample manifests PR 31 | run: make config-folder-sync 32 | -------------------------------------------------------------------------------- /.github/workflows/update.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # SPDX-license-identifier: Apache-2.0 3 | ############################################################################## 4 | # Copyright (c) 2024 5 | # All rights reserved. This program and the accompanying materials 6 | # are made available under the terms of the Apache License, Version 2.0 7 | # which accompanies this distribution, and is available at 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | ############################################################################## 10 | name: Scheduled Update Versions 11 | # yamllint disable-line rule:truthy 12 | on: 13 | schedule: 14 | - cron: '0 0 * * 5' 15 | workflow_dispatch: 16 | jobs: 17 | check-versions: 18 | runs-on: ubuntu-latest 19 | steps: 20 | - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # refs/tags/v4.1.7 21 | - uses: technote-space/create-pr-action@91114507cf92349bec0a9a501c2edf1635427bc5 # refs/tags/v2.1.4 22 | with: 23 | EXECUTE_COMMANDS: | 24 | gh_actions=$(grep -r "uses: [a-z\-]*/[\_a-z\-]*@" .github/workflows/ | sed 's/@.*//' | awk -F ': ' '{ print $3 }' | sort | uniq) 25 | for action in $gh_actions; do 26 | commit_hash=$(git ls-remote --tags "https://github.com/$action" | grep 'refs/tags/v[0-9][0-9\.]*$' | awk '{ print $NF,$0 }' | sort -k1,1 -V | cut -f2- -d' ' | grep -oh '.*refs/tags/[v0-9\.]*$' | tail -1 | awk '{ printf "%s # %s\n",$1,$2 }') 27 | grep -ElRZ "uses: $action@" .github/workflows/ | xargs -0 -l sed -i -e "s|uses: $action@.*|uses: $action@$commit_hash|g" 28 | done 29 | COMMIT_MESSAGE: 'Upgrade versions GitHub actions' 30 | COMMIT_NAME: 'updater bot' 31 | PR_BRANCH_NAME: "versions-update-${PR_ID}" 32 | PR_TITLE: 'chore: update gh versions' 33 | -------------------------------------------------------------------------------- /.github/workflows/weekly-cron-tests.yaml: -------------------------------------------------------------------------------- 1 | name: Weekly Cron tests 2 | 3 | on: 4 | workflow_dispatch: {} 5 | schedule: 6 | - cron: "0 16 * * 3" # every Wednesday 7 | 8 | permissions: 9 | id-token: write 10 | contents: read 11 | 12 | jobs: 13 | weekly-cron: 14 | if: github.repository == 'aws/amazon-vpc-cni-k8s' 15 | runs-on: ubuntu-latest 16 | steps: 17 | - name: Checkout latest commit in the PR 18 | uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # refs/tags/v4.1.7 19 | - name: Set up Docker QEMU 20 | uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # refs/tags/v3.0.0 21 | - name: Set up Docker Buildx 22 | uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # refs/tags/v3.3.0 23 | - name: Set up Go 24 | uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # refs/tags/v5.0.1 25 | with: 26 | go-version: "1.24" 27 | - name: Set up tools 28 | run: | 29 | # Install ginkgo version from go.mod 30 | go install -mod=mod github.com/onsi/ginkgo/v2/ginkgo 31 | curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp 32 | sudo mv /tmp/eksctl /usr/local/bin/ 33 | - name: Set up AWS credentials 34 | uses: aws-actions/configure-aws-credentials@5579c002bb4778aa43395ef1df492868a9a1c83f # refs/tags/v4.0.2 35 | with: 36 | role-to-assume: ${{ secrets.OSS_TEST_ROLE_ARN }} 37 | role-duration-seconds: 28800 # 8 hours 38 | aws-region: ${{ secrets.AWS_DEFAULT_REGION }} 39 | - name: Run perf tests 40 | env: 41 | DISABLE_PROMPT: true 42 | ROLE_CREATE: false 43 | ROLE_ARN: ${{ secrets.EKS_CLUSTER_ROLE_ARN }} 44 | RUN_CNI_INTEGRATION_TESTS: false 45 | PERFORMANCE_TEST_S3_BUCKET_NAME: cni-performance-tests 46 | RUN_PERFORMANCE_TESTS: true 47 | run: | 48 | ./scripts/run-integration-tests.sh 49 | if: always() 50 | - name: Run bottlerocket tests 51 | env: 52 | DISABLE_PROMPT: true 53 | ROLE_CREATE: false 54 | ROLE_ARN: ${{ secrets.EKS_CLUSTER_ROLE_ARN }} 55 | RUN_CNI_INTEGRATION_TESTS: false 56 | RUN_BOTTLEROCKET_TEST: true 57 | run: | 58 | ./scripts/run-integration-tests.sh 59 | if: always() 60 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore generated binaries 2 | aws-k8s-agent 3 | aws-cni 4 | aws-vpc-cni 5 | aws-vpc-cni-init 6 | cni-metrics-helper 7 | egress-cni 8 | grpc-health-probe 9 | portmap 10 | verify-aws 11 | verify-network 12 | # Ignore generated files 13 | *~ 14 | *.swp 15 | .idea/ 16 | *.iml 17 | .DS_Store 18 | coverage.txt 19 | cmd/egress-cni-plugin/egress-plugin.log 20 | # Ignore build files 21 | core-plugins/ 22 | build/ 23 | vendor/ 24 | # Unignore charts directory as its confilcts with `aws-vpc-cni` binary ignore rule 25 | !charts/** 26 | scripts/cni-test/ -------------------------------------------------------------------------------- /.go-version: -------------------------------------------------------------------------------- 1 | 1.24.2 2 | -------------------------------------------------------------------------------- /.mailmap: -------------------------------------------------------------------------------- 1 | Andrew Rudoi 2 | Claes Mogren 3 | Kit Ewbank 4 | Liwen Wu liwen wu 5 | Nick Turner Nicholas Turner <1205393+nckturner@users.noreply.github.com> 6 | Shaun Crampton 7 | Taylor Bertie <45247171+taylorb-syd@users.noreply.github.com> 8 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @aws/eks-networking 2 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /charts/aws-vpc-cni/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | .vscode/ 23 | crds/kustomization.yaml -------------------------------------------------------------------------------- /charts/aws-vpc-cni/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | name: aws-vpc-cni 3 | version: 1.19.5 4 | appVersion: "v1.19.5" 5 | description: A Helm chart for the AWS VPC CNI 6 | icon: https://raw.githubusercontent.com/aws/eks-charts/master/docs/logo/aws.png 7 | home: https://github.com/aws/amazon-vpc-cni-k8s 8 | sources: 9 | - https://github.com/aws/amazon-vpc-cni-k8s 10 | keywords: 11 | - eks 12 | - cni 13 | - networking 14 | - vpc 15 | maintainers: 16 | - name: Jayanth Varavani 17 | url: https://github.com/jayanthvn 18 | email: jayanthvn@users.noreply.github.com 19 | engine: gotpl 20 | -------------------------------------------------------------------------------- /charts/aws-vpc-cni/crds/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - customresourcedefinition.yaml 5 | -------------------------------------------------------------------------------- /charts/aws-vpc-cni/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | 2 | {{ .Release.Name }} has been installed or updated. To check the status of pods, run: 3 | 4 | kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "aws-vpc-cni.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" 5 | -------------------------------------------------------------------------------- /charts/aws-vpc-cni/templates/clusterrole.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: {{ include "aws-vpc-cni.fullname" . }} 5 | labels: 6 | {{ include "aws-vpc-cni.labels" . | indent 4 }} 7 | rules: 8 | - apiGroups: 9 | - crd.k8s.amazonaws.com 10 | resources: 11 | - eniconfigs 12 | verbs: ["list", "watch", "get"] 13 | - apiGroups: [""] 14 | resources: 15 | - namespaces 16 | verbs: ["list", "watch", "get"] 17 | {{- if .Values.env.ANNOTATE_POD_IP }} 18 | - apiGroups: [""] 19 | resources: 20 | - pods 21 | verbs: ["list", "watch", "get", "patch"] 22 | {{- else }} 23 | - apiGroups: [""] 24 | resources: 25 | - pods 26 | verbs: ["list", "watch", "get"] 27 | {{- end }} 28 | - apiGroups: [""] 29 | resources: 30 | - nodes 31 | verbs: ["list", "watch", "get"] 32 | - apiGroups: ["", "events.k8s.io"] 33 | resources: 34 | - events 35 | verbs: ["create", "patch", "list"] 36 | - apiGroups: ["networking.k8s.aws"] 37 | resources: 38 | - policyendpoints 39 | verbs: ["get", "list", "watch"] 40 | - apiGroups: ["networking.k8s.aws"] 41 | resources: 42 | - policyendpoints/status 43 | verbs: ["get"] 44 | - apiGroups: 45 | - vpcresources.k8s.aws 46 | resources: 47 | - cninodes 48 | verbs: ["get", "list", "watch", "patch"] 49 | -------------------------------------------------------------------------------- /charts/aws-vpc-cni/templates/clusterrolebinding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: {{ include "aws-vpc-cni.fullname" . }} 5 | labels: 6 | {{ include "aws-vpc-cni.labels" . | indent 4 }} 7 | roleRef: 8 | apiGroup: rbac.authorization.k8s.io 9 | kind: ClusterRole 10 | name: {{ include "aws-vpc-cni.fullname" . }} 11 | subjects: 12 | - kind: ServiceAccount 13 | name: {{ template "aws-vpc-cni.serviceAccountName" . }} 14 | namespace: {{ .Release.Namespace }} 15 | -------------------------------------------------------------------------------- /charts/aws-vpc-cni/templates/configmap.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.cniConfig.enabled }} 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: {{ include "aws-vpc-cni.fullname" . }} 6 | labels: 7 | {{ include "aws-vpc-cni.labels" . | indent 4 }} 8 | binaryData: 9 | 10-aws.conflist: {{ .Values.cniConfig.fileContents | b64enc }} 10 | {{- end }} 11 | --- 12 | apiVersion: v1 13 | kind: ConfigMap 14 | metadata: 15 | name: amazon-vpc-cni 16 | namespace: {{ .Release.Namespace }} 17 | labels: 18 | {{ include "aws-vpc-cni.labels" . | indent 4 }} 19 | data: 20 | enable-windows-ipam: {{ .Values.enableWindowsIpam | quote }} 21 | enable-network-policy-controller: {{ .Values.enableNetworkPolicy | quote }} 22 | enable-windows-prefix-delegation: {{ .Values.enableWindowsPrefixDelegation | quote }} 23 | warm-prefix-target: {{ .Values.warmWindowsPrefixTarget | quote }} 24 | warm-ip-target: {{ .Values.warmWindowsIPTarget | quote }} 25 | minimum-ip-target: {{ .Values.minimumWindowsIPTarget | quote }} 26 | branch-eni-cooldown: {{ .Values.branchENICooldown | quote }} 27 | -------------------------------------------------------------------------------- /charts/aws-vpc-cni/templates/eniconfig.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.eniConfig.create }} 2 | {{- range $key, $value := (required ".Values.eniConfig.subnets must be specified" .Values.eniConfig.subnets) }} 3 | apiVersion: crd.k8s.amazonaws.com/v1alpha1 4 | kind: ENIConfig 5 | metadata: 6 | name: "{{ $key }}" 7 | spec: 8 | {{- if $value.securityGroups }} 9 | securityGroups: 10 | {{- range $sg := $value.securityGroups }} 11 | - {{ $sg }} 12 | {{- end }} 13 | {{- end }} 14 | subnet: {{ $value.id }} 15 | --- 16 | {{- end }} 17 | {{- end }} 18 | -------------------------------------------------------------------------------- /charts/aws-vpc-cni/templates/podmonitor.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.podMonitor.create }} 2 | apiVersion: monitoring.coreos.com/v1 3 | kind: PodMonitor 4 | metadata: 5 | name: {{ include "aws-vpc-cni.fullname" . }} 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | {{- with .Values.podMonitor.labels }} 9 | {{- toYaml . | nindent 4 }} 10 | {{- end }} 11 | {{- with .Values.podMonitor.annotations }} 12 | annotations: 13 | {{- toYaml . | nindent 4 }} 14 | {{- end }} 15 | spec: 16 | jobLabel: {{ include "aws-vpc-cni.fullname" . }} 17 | namespaceSelector: 18 | matchNames: 19 | - {{ .Release.Namespace }} 20 | podMetricsEndpoints: 21 | - interval: {{ .Values.podMonitor.interval }} 22 | path: /metrics 23 | port: metrics 24 | {{- with .Values.podMonitor.relabelings }} 25 | relabelings: 26 | {{- toYaml . | nindent 6 }} 27 | {{- end }} 28 | {{- if .Values.nodeAgent.enabled }} 29 | - interval: {{ .Values.podMonitor.interval }} 30 | path: /metrics 31 | port: agentmetrics 32 | {{- with .Values.podMonitor.relabelings }} 33 | relabelings: 34 | {{- toYaml . | nindent 6 }} 35 | {{- end }} 36 | {{- end }} 37 | selector: 38 | matchLabels: 39 | k8s-app: aws-node 40 | {{- end }} 41 | -------------------------------------------------------------------------------- /charts/aws-vpc-cni/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.serviceAccount.create -}} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: {{ template "aws-vpc-cni.serviceAccountName" . }} 6 | namespace: {{ .Release.Namespace }} 7 | {{- with .Values.serviceAccount.annotations }} 8 | annotations: 9 | {{ toYaml . | indent 4 }} 10 | {{- end }} 11 | labels: 12 | {{ include "aws-vpc-cni.labels" . | indent 4 }} 13 | {{- end -}} 14 | -------------------------------------------------------------------------------- /charts/cni-metrics-helper/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /charts/cni-metrics-helper/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: cni-metrics-helper 3 | version: 1.19.5 4 | appVersion: v1.19.5 5 | description: A Helm chart for the AWS VPC CNI Metrics Helper 6 | icon: https://raw.githubusercontent.com/aws/eks-charts/master/docs/logo/aws.png 7 | home: https://github.com/aws/amazon-vpc-cni-k8s 8 | sources: 9 | - https://github.com/aws/amazon-vpc-cni-k8s 10 | keywords: 11 | - eks 12 | - cni 13 | - networking 14 | - vpc 15 | maintainers: 16 | - name: Jayanth Varavani 17 | url: https://github.com/jayanthvn 18 | email: jayanthvn@users.noreply.github.com 19 | engine: gotpl 20 | -------------------------------------------------------------------------------- /charts/cni-metrics-helper/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | {{ .Release.Name }} has been installed or updated. To check the status of pods, run: 2 | 3 | kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "cni-metrics-helper.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -------------------------------------------------------------------------------- /charts/cni-metrics-helper/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "cni-metrics-helper.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} 7 | {{- end }} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | If release name contains chart name it will be used as a full name. 13 | */}} 14 | {{- define "cni-metrics-helper.fullname" -}} 15 | {{- if .Values.fullnameOverride }} 16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 17 | {{- else }} 18 | {{- $name := default .Chart.Name .Values.nameOverride }} 19 | {{- if contains $name .Release.Name }} 20 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 21 | {{- else }} 22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} 23 | {{- end }} 24 | {{- end }} 25 | {{- end }} 26 | 27 | {{/* 28 | Create chart name and version as used by the chart label. 29 | */}} 30 | {{- define "cni-metrics-helper.chart" -}} 31 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} 32 | {{- end }} 33 | 34 | {{/* 35 | Common labels 36 | */}} 37 | {{- define "cni-metrics-helper.labels" -}} 38 | helm.sh/chart: {{ include "cni-metrics-helper.chart" . }} 39 | {{ include "cni-metrics-helper.selectorLabels" . }} 40 | {{- if .Chart.AppVersion }} 41 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 42 | {{- end }} 43 | app.kubernetes.io/managed-by: {{ .Release.Service }} 44 | {{- end }} 45 | 46 | {{/* 47 | Selector labels 48 | */}} 49 | {{- define "cni-metrics-helper.selectorLabels" -}} 50 | app.kubernetes.io/name: {{ include "cni-metrics-helper.name" . }} 51 | app.kubernetes.io/instance: {{ .Release.Name }} 52 | {{- end }} 53 | 54 | {{/* 55 | Create the name of the service account to use 56 | */}} 57 | {{- define "cni-metrics-helper.serviceAccountName" -}} 58 | {{- if .Values.serviceAccount.create }} 59 | {{- default (include "cni-metrics-helper.fullname" .) .Values.serviceAccount.name }} 60 | {{- else }} 61 | {{- default "default" .Values.serviceAccount.name }} 62 | {{- end }} 63 | {{- end }} 64 | -------------------------------------------------------------------------------- /charts/cni-metrics-helper/templates/clusterrole.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: {{ include "cni-metrics-helper.fullname" . }} 5 | labels: 6 | {{ include "cni-metrics-helper.labels" . | indent 4 }} 7 | rules: 8 | - apiGroups: [""] 9 | resources: 10 | - pods 11 | - pods/proxy 12 | verbs: ["get", "watch", "list"] 13 | -------------------------------------------------------------------------------- /charts/cni-metrics-helper/templates/clusterrolebinding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: {{ include "cni-metrics-helper.fullname" . }} 5 | labels: 6 | {{ include "cni-metrics-helper.labels" . | indent 4 }} 7 | roleRef: 8 | apiGroup: rbac.authorization.k8s.io 9 | kind: ClusterRole 10 | name: {{ include "cni-metrics-helper.fullname" . }} 11 | subjects: 12 | - kind: ServiceAccount 13 | name: {{ template "cni-metrics-helper.serviceAccountName" . }} 14 | namespace: {{ .Release.Namespace }} 15 | -------------------------------------------------------------------------------- /charts/cni-metrics-helper/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.serviceAccount.create -}} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: {{ template "cni-metrics-helper.serviceAccountName" . }} 6 | namespace: {{ .Release.Namespace }} 7 | {{- with .Values.serviceAccount.annotations }} 8 | annotations: 9 | {{ toYaml . | indent 4 }} 10 | {{- end }} 11 | labels: 12 | {{ include "cni-metrics-helper.labels" . | indent 4 }} 13 | {{- end -}} 14 | -------------------------------------------------------------------------------- /charts/cni-metrics-helper/values.yaml: -------------------------------------------------------------------------------- 1 | # This default name override is to maintain backwards compatability with 2 | # existing naming 3 | nameOverride: cni-metrics-helper 4 | 5 | image: 6 | region: us-west-2 7 | tag: v1.19.5 8 | account: "602401143452" 9 | domain: "amazonaws.com" 10 | # Set to use custom image 11 | # override: "repo/org/image:tag" 12 | 13 | env: 14 | USE_CLOUDWATCH: "true" 15 | USE_PROMETHEUS: "false" 16 | AWS_CLUSTER_ID: "" 17 | AWS_VPC_K8S_CNI_LOGLEVEL: "INFO" 18 | 19 | fullnameOverride: "cni-metrics-helper" 20 | 21 | serviceAccount: 22 | # Specifies whether a service account should be created 23 | create: true 24 | # The name of the service account to use. 25 | # If not set and create is true, a name is generated using the fullname template 26 | name: 27 | annotations: {} 28 | # eks.amazonaws.com/role-arn: arn:aws:iam::AWS_ACCOUNT_ID:role/IAM_ROLE_NAME 29 | 30 | resources: {} 31 | 32 | revisionHistoryLimit: 10 33 | 34 | podSecurityContext: {} 35 | 36 | containerSecurityContext: {} 37 | 38 | podAnnotations: {} 39 | 40 | imagePullSecrets: [] 41 | 42 | updateStrategy: {} 43 | # type: RollingUpdate 44 | # rollingUpdate: 45 | # maxUnavailable: "10%" 46 | 47 | nodeSelector: {} 48 | 49 | tolerations: [] 50 | # - operator: Exists 51 | 52 | affinity: {} 53 | # nodeAffinity: 54 | # requiredDuringSchedulingIgnoredDuringExecution: 55 | # nodeSelectorTerms: 56 | # - matchExpressions: 57 | # - key: "kubernetes.io/os" 58 | # operator: In 59 | # values: 60 | # - linux 61 | # - key: "kubernetes.io/arch" 62 | # operator: In 63 | # values: 64 | # - amd64 65 | # - arm64 66 | # - key: "eks.amazonaws.com/compute-type" 67 | # operator: NotIn 68 | # values: 69 | # - fargate 70 | -------------------------------------------------------------------------------- /charts/regions.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ecrRegion": "us-west-2", 4 | "ecrAccount": "602401143452", 5 | "ecrDomain": "amazonaws.com" 6 | }, 7 | { 8 | "ecrRegion": "us-gov-east-1", 9 | "ecrAccount": "151742754352", 10 | "ecrDomain": "amazonaws.com" 11 | }, 12 | { 13 | "ecrRegion": "us-gov-west-1", 14 | "ecrAccount": "013241004608", 15 | "ecrDomain": "amazonaws.com" 16 | }, 17 | { 18 | "ecrRegion": "cn-northwest-1", 19 | "ecrAccount": "961992271922", 20 | "ecrDomain": "amazonaws.com.cn" 21 | } 22 | ] -------------------------------------------------------------------------------- /cmd/cni-metrics-helper/metrics/pod_watcher.go: -------------------------------------------------------------------------------- 1 | package metrics 2 | 3 | import ( 4 | "context" 5 | 6 | corev1 "k8s.io/api/core/v1" 7 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 8 | "sigs.k8s.io/controller-runtime/pkg/client" 9 | 10 | "github.com/aws/amazon-vpc-cni-k8s/pkg/utils/logger" 11 | ) 12 | 13 | type PodWatcher interface { 14 | GetCNIPods(ctx context.Context) ([]string, error) 15 | } 16 | 17 | type defaultPodWatcher struct { 18 | k8sClient client.Client 19 | log logger.Logger 20 | } 21 | 22 | // NewDefaultPodWatcher creates a new podWatcher 23 | func NewDefaultPodWatcher(k8sClient client.Client, log logger.Logger) *defaultPodWatcher { 24 | return &defaultPodWatcher{ 25 | k8sClient: k8sClient, 26 | log: log, 27 | } 28 | } 29 | 30 | // Returns aws-node pod info. Below function assumes CNI pods follow aws-node* naming format 31 | // and so the function has to be updated if the CNI pod name format changes. 32 | func (d *defaultPodWatcher) GetCNIPods(ctx context.Context) ([]string, error) { 33 | var CNIPods []string 34 | var podList corev1.PodList 35 | labelSelector, err := metav1.LabelSelectorAsSelector(&metav1.LabelSelector{ 36 | MatchLabels: map[string]string{ 37 | "k8s-app": "aws-node", 38 | }, 39 | }) 40 | 41 | if err != nil { 42 | panic(err.Error()) 43 | } 44 | 45 | listOptions := client.ListOptions{ 46 | Namespace: metav1.NamespaceSystem, 47 | LabelSelector: labelSelector, 48 | } 49 | 50 | err = d.k8sClient.List(ctx, &podList, &listOptions) 51 | if err != nil { 52 | return CNIPods, err 53 | } 54 | 55 | for _, pod := range podList.Items { 56 | CNIPods = append(CNIPods, pod.Name) 57 | } 58 | 59 | d.log.Infof("Total aws-node pod count: %d", len(CNIPods)) 60 | return CNIPods, nil 61 | } 62 | -------------------------------------------------------------------------------- /cmd/egress-cni-plugin/netconf.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package main 15 | 16 | import ( 17 | "encoding/json" 18 | "fmt" 19 | "net" 20 | 21 | "github.com/containernetworking/cni/pkg/types" 22 | cniversion "github.com/containernetworking/cni/pkg/version" 23 | 24 | "github.com/aws/amazon-vpc-cni-k8s/pkg/utils/logger" 25 | ) 26 | 27 | const ( 28 | // egressIPv4InterfaceName interface name used in container ns for IPv4 egress traffic 29 | egressIPv4InterfaceName = "v4if0" 30 | 31 | // egressIPv6InterfaceName interface name used in container ns for IPv6 egress traffic 32 | egressIPv6InterfaceName = "v6if0" 33 | ) 34 | 35 | // NetConf is our CNI config structure 36 | type NetConf struct { 37 | types.NetConf 38 | 39 | // Interface inside container to create 40 | IfName string `json:"ifName"` 41 | 42 | // MTU for Egress v4 interface 43 | MTU string `json:"mtu"` 44 | 45 | Enabled string `json:"enabled"` 46 | 47 | RandomizeSNAT string `json:"randomizeSNAT"` 48 | 49 | // IP to use as SNAT target 50 | NodeIP net.IP `json:"nodeIP"` 51 | 52 | PluginLogFile string `json:"pluginLogFile"` 53 | PluginLogLevel string `json:"pluginLogLevel"` 54 | } 55 | 56 | // LoadConf load stdin and parse to NetConf type, a new log instance is created based on conf settings 57 | func LoadConf(bytes []byte) (*NetConf, logger.Logger, error) { 58 | conf := &NetConf{} 59 | 60 | if err := json.Unmarshal(bytes, conf); err != nil { 61 | return nil, nil, err 62 | } 63 | 64 | if conf.RawPrevResult != nil { 65 | if err := cniversion.ParsePrevResult(&conf.NetConf); err != nil { 66 | return nil, nil, fmt.Errorf("could not parse prevResult: %v", err) 67 | } 68 | } 69 | 70 | logConfig := logger.Configuration{ 71 | LogLevel: conf.PluginLogLevel, 72 | LogLocation: conf.PluginLogFile, 73 | } 74 | log := logger.New(&logConfig) 75 | return conf, log, nil 76 | } 77 | -------------------------------------------------------------------------------- /cmd/routed-eni-cni-plugin/driver/generate_mocks.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package driver 15 | 16 | //go:generate go run github.com/golang/mock/mockgen -destination mocks/driver_mocks.go -copyright_file ../../../scripts/copyright.txt . NetworkAPIs 17 | -------------------------------------------------------------------------------- /config/multus/README.md: -------------------------------------------------------------------------------- 1 | ## Setup 2 | The following Multus installation will set up aws-vpc-cni as the default plugin. 3 | 4 | The Multus daemonset assumes that 10-aws.conflist (aws-vpc-cni) config file is present in the /etc/cni/net.d/ directory on your worker node to generate the multus config from it. 5 | 6 | Download the latest version of the [yaml](../multus/) and apply it the cluster. 7 | ``` 8 | kubectl apply -f aws-k8s-multus.yaml 9 | ``` 10 | 11 | Check logs for Multus pod 12 | ``` 13 | kubectl logs -f pod/kube-multus-ds-677mq -n kube-system 14 | 2021-07-27T08:02:00+0000 Generating Multus configuration file using files in /host/etc/cni/net.d... 15 | 2021-07-27T08:02:00+0000 Using MASTER_PLUGIN: 10-aws.conflist 16 | 2021-07-27T08:02:00+0000 Nested capabilities string: "capabilities": {"portMappings": true}, 17 | 2021-07-27T08:02:00+0000 Using /host/etc/cni/net.d/10-aws.conflist as a source to generate the Multus configuration 18 | 2021-07-27T08:02:00+0000 Config file created @ /host/etc/cni/net.d/00-multus.conf 19 | { "cniVersion": "0.3.1", "name": "multus-cni-network", "type": "multus", "capabilities": {"portMappings": true}, "kubeconfig": "/etc/cni/net.d/multus.d/multus.kubeconfig", "delegates": [ { "cniVersion": "0.3.1", "name": "aws-cni", "plugins": [ { "name": "aws-cni", "type": "aws-cni", "vethPrefix": "eni", "mtu": "9001", "pluginLogFile": "/var/log/aws-routed-eni/plugin.log", "pluginLogLevel": "DEBUG" }, { "type": "portmap", "capabilities": {"portMappings": true}, "snat": true } ] } ] } 20 | 2021-07-27T08:02:00+0000 Entering sleep (success)... 21 | ``` 22 | 23 | ### Multus Logging 24 | The log level for multus has been set to error. It will log only the errors. 25 | 26 | If you want a more verbose logging you can change it to verbose. You can also use debug for your development but it can quickly fill up disk space 27 | 28 | You can find more info [here](https://github.com/k8snetworkplumbingwg/multus-cni/blob/master/docs/configuration.md#logging-level) 29 | -------------------------------------------------------------------------------- /config/multus/v3.7.2-eksbuild.2/Readme.md: -------------------------------------------------------------------------------- 1 | ## Changelog 2 | 3 | Updated Multus image manifest to support arm64 architecture 4 | 5 | docker manifest inspect 602401143452.dkr.ecr.us-west-2.amazonaws.com/eks/multus-cni:v3.7.2-eksbuild.2 6 | ``` 7 | eksbuild.2 8 | { 9 | "schemaVersion": 2, 10 | "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json", 11 | "manifests": [ 12 | { 13 | "mediaType": "application/vnd.docker.distribution.manifest.v2+json", 14 | "size": 1161, 15 | "digest": "sha256:207e228c5c871ef42ebf9029bd3fea8ce2558ec96a0a95f670f5e5cba891836d", 16 | "platform": { 17 | "architecture": "amd64", 18 | "os": "linux" 19 | } 20 | }, 21 | { 22 | "mediaType": "application/vnd.docker.distribution.manifest.v2+json", 23 | "size": 1163, 24 | "digest": "sha256:e43fc57c63a01c0a64197408650efff767a8a76460a9ef02d87ea4fb5568409e", 25 | "platform": { 26 | "architecture": "arm64", 27 | "os": "linux" 28 | } 29 | } 30 | ] 31 | } 32 | ``` 33 | -------------------------------------------------------------------------------- /config/multus/v3.8.0-eksbuild.1/Readme.md: -------------------------------------------------------------------------------- 1 | ## Changelog 2 | Multus source code in-sync with upstream Multus repo [v3.8](https://github.com/k8snetworkplumbingwg/multus-cni/releases/tag/v3.8) 3 | -------------------------------------------------------------------------------- /config/multus/v3.9.0-eksbuild.1/Readme.md: -------------------------------------------------------------------------------- 1 | ## Changelog 2 | Multus source code in-sync with upstream Multus repo [v3.9](https://github.com/k8snetworkplumbingwg/multus-cni/releases/tag/v3.9) -------------------------------------------------------------------------------- /config/multus/v3.9.0-eksbuild.2/Readme.md: -------------------------------------------------------------------------------- 1 | ## Changelog 2 | Addressed CVE's -------------------------------------------------------------------------------- /config/multus/v3.9.1-eksbuild.1/Readme.md: -------------------------------------------------------------------------------- 1 | ## Changelog 2 | Multus source code in-sync with upstream Multus repo [v3.9.1] (https://github.com/k8snetworkplumbingwg/multus-cni/releases/tag/v3.9.1) 3 | -------------------------------------------------------------------------------- /config/multus/v3.9.2-eksbuild.1/Readme.md: -------------------------------------------------------------------------------- 1 | ## Changelog 2 | Multus source code in-sync with upstream Multus repo [v3.9.2] (https://github.com/k8snetworkplumbingwg/multus-cni/releases/tag/v3.9.2) 3 | -------------------------------------------------------------------------------- /docs/images/EKS_CNI_metrics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/c9d6f7baeb2f4b2975f71d53b3099bc87f68fbf4/docs/images/EKS_CNI_metrics.png -------------------------------------------------------------------------------- /docs/images/cni-metrics-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/c9d6f7baeb2f4b2975f71d53b3099bc87f68fbf4/docs/images/cni-metrics-100.png -------------------------------------------------------------------------------- /docs/images/cni-metrics-helper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/c9d6f7baeb2f4b2975f71d53b3099bc87f68fbf4/docs/images/cni-metrics-helper.png -------------------------------------------------------------------------------- /docs/images/cni-metrics-inprogress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/c9d6f7baeb2f4b2975f71d53b3099bc87f68fbf4/docs/images/cni-metrics-inprogress.png -------------------------------------------------------------------------------- /docs/images/ipam.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/c9d6f7baeb2f4b2975f71d53b3099bc87f68fbf4/docs/images/ipam.png -------------------------------------------------------------------------------- /docs/images/ping.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/c9d6f7baeb2f4b2975f71d53b3099bc87f68fbf4/docs/images/ping.png -------------------------------------------------------------------------------- /docs/images/ping2external.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/c9d6f7baeb2f4b2975f71d53b3099bc87f68fbf4/docs/images/ping2external.png -------------------------------------------------------------------------------- /docs/images/subnet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/c9d6f7baeb2f4b2975f71d53b3099bc87f68fbf4/docs/images/subnet.png -------------------------------------------------------------------------------- /docs/images/wire-network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/c9d6f7baeb2f4b2975f71d53b3099bc87f68fbf4/docs/images/wire-network.png -------------------------------------------------------------------------------- /misc/10-aws.conflist: -------------------------------------------------------------------------------- 1 | { 2 | "cniVersion": "0.4.0", 3 | "name": "aws-cni", 4 | "disableCheck": true, 5 | "plugins": [ 6 | { 7 | "name": "aws-cni", 8 | "type": "aws-cni", 9 | "vethPrefix": "__VETHPREFIX__", 10 | "mtu": "__MTU__", 11 | "podSGEnforcingMode": "__PODSGENFORCINGMODE__", 12 | "pluginLogFile": "__PLUGINLOGFILE__", 13 | "pluginLogLevel": "__PLUGINLOGLEVEL__" 14 | }, 15 | { 16 | "name": "egress-cni", 17 | "type": "egress-cni", 18 | "mtu": "__MTU__", 19 | "enabled": "__EGRESSPLUGINENABLED__", 20 | "randomizeSNAT": "__RANDOMIZESNAT__", 21 | "nodeIP": "__NODEIP__", 22 | "ipam": { 23 | "type": "host-local", 24 | "ranges": [[{"subnet": "__EGRESSPLUGINIPAMSUBNET__"}]], 25 | "routes": [{"dst": "__EGRESSPLUGINIPAMDST__"}], 26 | "dataDir": "__EGRESSPLUGINIPAMDATADIR__" 27 | }, 28 | "pluginLogFile": "__EGRESSPLUGINLOGFILE__", 29 | "pluginLogLevel": "__PLUGINLOGLEVEL__" 30 | }, 31 | { 32 | "type": "portmap", 33 | "capabilities": {"portMappings": true}, 34 | "snat": true 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /pkg/apis/crd/v1alpha1/eniconfig_types.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package v1alpha1 18 | 19 | import ( 20 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 21 | ) 22 | 23 | // EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! 24 | // NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. 25 | 26 | // ENIConfigSpec defines the desired state of ENIConfig 27 | type ENIConfigSpec struct { 28 | SecurityGroups []string `json:"securityGroups"` 29 | Subnet string `json:"subnet"` 30 | } 31 | 32 | // ENIConfigStatus defines the observed state of ENIConfig 33 | type ENIConfigStatus struct { 34 | // Fill me 35 | } 36 | 37 | //+kubebuilder:object:root=true 38 | //+kubebuilder:subresource:status 39 | 40 | // ENIConfig is the Schema for the eniconfigs API 41 | type ENIConfig struct { 42 | metav1.TypeMeta `json:",inline"` 43 | metav1.ObjectMeta `json:"metadata,omitempty"` 44 | 45 | Spec ENIConfigSpec `json:"spec,omitempty"` 46 | Status ENIConfigStatus `json:"status,omitempty"` 47 | } 48 | 49 | //+kubebuilder:object:root=true 50 | 51 | // ENIConfigList contains a list of ENIConfig 52 | type ENIConfigList struct { 53 | metav1.TypeMeta `json:",inline"` 54 | metav1.ListMeta `json:"metadata,omitempty"` 55 | Items []ENIConfig `json:"items"` 56 | } 57 | 58 | func init() { 59 | SchemeBuilder.Register(&ENIConfig{}, &ENIConfigList{}) 60 | } 61 | -------------------------------------------------------------------------------- /pkg/apis/crd/v1alpha1/groupversion_info.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Package v1alpha1 contains API Schema definitions for the crd v1alpha1 API group 18 | // +kubebuilder:object:generate=true 19 | // +groupName=crd.example.com 20 | package v1alpha1 21 | 22 | import ( 23 | "k8s.io/apimachinery/pkg/runtime/schema" 24 | "sigs.k8s.io/controller-runtime/pkg/scheme" 25 | ) 26 | 27 | var ( 28 | // GroupVersion is group version used to register these objects 29 | GroupVersion = schema.GroupVersion{Group: "crd.k8s.amazonaws.com", Version: "v1alpha1"} 30 | 31 | // SchemeBuilder is used to add go types to the GroupVersionKind scheme 32 | SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} 33 | 34 | // AddToScheme adds the types in this group-version to the given scheme. 35 | AddToScheme = SchemeBuilder.AddToScheme 36 | ) 37 | -------------------------------------------------------------------------------- /pkg/awsutils/awssession/session_test.go: -------------------------------------------------------------------------------- 1 | package awssession 2 | 3 | import ( 4 | "context" 5 | "os" 6 | "testing" 7 | "time" 8 | 9 | "github.com/aws/aws-sdk-go-v2/service/ec2" 10 | "github.com/stretchr/testify/assert" 11 | ) 12 | 13 | func TestHttpTimeoutReturnDefault(t *testing.T) { 14 | os.Setenv(httpTimeoutEnv, "2") 15 | defer os.Unsetenv(httpTimeoutEnv) 16 | expectedHTTPTimeOut := time.Duration(10) * time.Second 17 | assert.Equal(t, expectedHTTPTimeOut, getHTTPTimeout()) 18 | } 19 | 20 | func TestHttpTimeoutWithValueAbove10(t *testing.T) { 21 | os.Setenv(httpTimeoutEnv, "12") 22 | defer os.Unsetenv(httpTimeoutEnv) 23 | expectedHTTPTimeOut := time.Duration(12) * time.Second 24 | assert.Equal(t, expectedHTTPTimeOut, getHTTPTimeout()) 25 | } 26 | 27 | func TestAwsEc2EndpointResolver(t *testing.T) { 28 | customEndpoint := "https://ec2.us-west-2.customaws.com" 29 | ctx := context.Background() 30 | 31 | os.Setenv("AWS_EC2_ENDPOINT", customEndpoint) 32 | defer os.Unsetenv("AWS_EC2_ENDPOINT") 33 | 34 | cfg, err := New(ctx) 35 | assert.NoError(t, err) 36 | 37 | resolvedEndpoint, err := cfg.EndpointResolver.ResolveEndpoint(ec2.ServiceID, "") 38 | assert.NoError(t, err) 39 | assert.Equal(t, customEndpoint, resolvedEndpoint.URL) 40 | } 41 | -------------------------------------------------------------------------------- /pkg/awsutils/generate_mocks.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package awsutils 15 | 16 | //go:generate go run github.com/golang/mock/mockgen -destination mocks/awsutils_mocks.go -copyright_file ../../scripts/copyright.txt . APIs 17 | -------------------------------------------------------------------------------- /pkg/cninswrapper/generate_mocks.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package cninswrapper 15 | 16 | //go:generate go run github.com/golang/mock/mockgen -destination mock_ns/netns_mocks.go -copyright_file ../../scripts/copyright.txt github.com/containernetworking/plugins/pkg/ns NetNS 17 | -------------------------------------------------------------------------------- /pkg/ec2metadatawrapper/ec2metadatawrapper.go: -------------------------------------------------------------------------------- 1 | // Package ec2metadatawrapper is used to retrieve data from EC2 IMDS 2 | package ec2metadatawrapper 3 | 4 | import ( 5 | "context" 6 | 7 | "github.com/aws/aws-sdk-go-v2/config" 8 | "github.com/aws/aws-sdk-go-v2/feature/ec2/imds" 9 | ) 10 | 11 | // HTTPClient is used to help with testing 12 | type HTTPClient interface { 13 | GetInstanceIdentityDocument(ctx context.Context, params *imds.GetInstanceIdentityDocumentInput, optFns ...func(*imds.Options)) (*imds.GetInstanceIdentityDocumentOutput, error) 14 | GetRegion(ctx context.Context, params *imds.GetRegionInput, optFns ...func(*imds.Options)) (*imds.GetRegionOutput, error) 15 | } 16 | 17 | // EC2MetadataClient to used to obtain a subset of information from EC2 IMDS 18 | type EC2MetadataClient interface { 19 | GetInstanceIdentityDocument(ctx context.Context, params *imds.GetInstanceIdentityDocumentInput, optFns ...func(*imds.Options)) (*imds.GetInstanceIdentityDocumentOutput, error) 20 | GetRegion(ctx context.Context, params *imds.GetRegionInput, optFns ...func(*imds.Options)) (*imds.GetRegionOutput, error) 21 | } 22 | 23 | type ec2MetadataClientImpl struct { 24 | client HTTPClient 25 | } 26 | 27 | // New creates an ec2metadata client to retrieve metadata 28 | func New(ctx context.Context) (EC2MetadataClient, error) { 29 | cfg, err := config.LoadDefaultConfig(ctx) 30 | if err != nil { 31 | return nil, err 32 | } 33 | 34 | client := imds.NewFromConfig(cfg) 35 | return NewMetadataService(client), nil 36 | } 37 | 38 | // NewMetadataService creates an ec2metadata client to retrieve metadata 39 | func NewMetadataService(client HTTPClient) EC2MetadataClient { 40 | return &ec2MetadataClientImpl{client: client} 41 | } 42 | 43 | // GetInstanceIdentityDocument returns instance identity documents 44 | func (c *ec2MetadataClientImpl) GetInstanceIdentityDocument(ctx context.Context, params *imds.GetInstanceIdentityDocumentInput, optFns ...func(*imds.Options)) (*imds.GetInstanceIdentityDocumentOutput, error) { 45 | return c.client.GetInstanceIdentityDocument(ctx, params, optFns...) 46 | } 47 | 48 | // GetRegion returns the AWS Region the instance is running in 49 | func (c *ec2MetadataClientImpl) GetRegion(ctx context.Context, params *imds.GetRegionInput, optFns ...func(*imds.Options)) (*imds.GetRegionOutput, error) { 50 | return c.client.GetRegion(ctx, params, optFns...) 51 | } 52 | -------------------------------------------------------------------------------- /pkg/ec2metadatawrapper/generate_mocks.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package ec2metadatawrapper 15 | 16 | //go:generate go run github.com/golang/mock/mockgen -destination mocks/ec2metadatawrapper_mocks.go -copyright_file ../../scripts/copyright.txt . HTTPClient,EC2MetadataClient 17 | -------------------------------------------------------------------------------- /pkg/ec2wrapper/generate_mocks.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package ec2wrapper 15 | 16 | //go:generate go run github.com/golang/mock/mockgen -destination mocks/ec2wrapper_mocks.go -copyright_file ../../scripts/copyright.txt . EC2 17 | -------------------------------------------------------------------------------- /pkg/eniconfig/generate_mocks.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package eniconfig 15 | 16 | //go:generate go run github.com/golang/mock/mockgen -destination mocks/eniconfig_mocks.go -copyright_file ../../scripts/copyright.txt . ENIConfig 17 | -------------------------------------------------------------------------------- /pkg/grpcwrapper/client.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | // Package grpcwrapper is a wrapper for the ipamd client Dial interface 15 | package grpcwrapper 16 | 17 | import ( 18 | "context" 19 | 20 | google_grpc "google.golang.org/grpc" 21 | ) 22 | 23 | // GRPC is the ipamd client Dial interface 24 | type GRPC interface { 25 | Dial(target string, opts ...google_grpc.DialOption) (*google_grpc.ClientConn, error) 26 | DialContext(ctx context.Context, target string, opts ...google_grpc.DialOption) (*google_grpc.ClientConn, error) 27 | } 28 | 29 | type cniGRPC struct{} 30 | 31 | // New creates a new cniGRPC 32 | func New() GRPC { 33 | return &cniGRPC{} 34 | } 35 | 36 | func (*cniGRPC) Dial(target string, opts ...google_grpc.DialOption) (*google_grpc.ClientConn, error) { 37 | return google_grpc.Dial(target, opts...) 38 | } 39 | 40 | func (*cniGRPC) DialContext(ctx context.Context, target string, opts ...google_grpc.DialOption) (*google_grpc.ClientConn, error) { 41 | return google_grpc.DialContext(ctx, target, opts...) 42 | } 43 | -------------------------------------------------------------------------------- /pkg/grpcwrapper/generate_mocks.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package grpcwrapper 15 | 16 | //go:generate go run github.com/golang/mock/mockgen -destination mocks/grpcwrapper_mocks.go -copyright_file ../../scripts/copyright.txt . GRPC 17 | -------------------------------------------------------------------------------- /pkg/hostipamwrapper/generate_mocks.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package hostipamwrapper 15 | 16 | //go:generate go run github.com/golang/mock/mockgen -destination mocks/hostipam_mocks.go -copyright_file ../../scripts/copyright.txt . HostIpam 17 | -------------------------------------------------------------------------------- /pkg/hostipamwrapper/hostipam.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | // Package hostipamwrapper is a wrapper method for the hostipam package 15 | package hostipamwrapper 16 | 17 | import ( 18 | "github.com/containernetworking/cni/pkg/types" 19 | current "github.com/containernetworking/cni/pkg/types/100" 20 | _ipam "github.com/containernetworking/plugins/pkg/ipam" 21 | ) 22 | 23 | // HostIpam is an interface created to make code unit testable. 24 | // Both the hostipam package version and mocked version implement the same interface 25 | type HostIpam interface { 26 | ExecAdd(plugin string, netconf []byte) (types.Result, error) 27 | 28 | ExecCheck(plugin string, netconf []byte) error 29 | 30 | ExecDel(plugin string, netconf []byte) error 31 | 32 | ConfigureIface(ifName string, res *current.Result) error 33 | } 34 | 35 | type hostipam struct{} 36 | 37 | // NewIpam return a new HostIpam object 38 | func NewIpam() HostIpam { 39 | return &hostipam{} 40 | } 41 | func (h *hostipam) ExecAdd(plugin string, netconf []byte) (types.Result, error) { 42 | return _ipam.ExecAdd(plugin, netconf) 43 | } 44 | 45 | func (h *hostipam) ExecCheck(plugin string, netconf []byte) error { 46 | return _ipam.ExecCheck(plugin, netconf) 47 | } 48 | 49 | func (h *hostipam) ExecDel(plugin string, netconf []byte) error { 50 | return _ipam.ExecDel(plugin, netconf) 51 | } 52 | 53 | func (h *hostipam) ConfigureIface(ifName string, res *current.Result) error { 54 | return _ipam.ConfigureIface(ifName, res) 55 | } 56 | -------------------------------------------------------------------------------- /pkg/iptableswrapper/generate_mocks.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package iptableswrapper 15 | 16 | //go:generate go run github.com/golang/mock/mockgen -destination mocks/iptables_mocks.go -copyright_file ../../scripts/copyright.txt . IPTablesIface 17 | -------------------------------------------------------------------------------- /pkg/ipwrapper/generate_mocks.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package ipwrapper 15 | 16 | //go:generate go run github.com/golang/mock/mockgen -destination mocks/ipwrapper_mocks.go -copyright_file ../../scripts/copyright.txt . IP 17 | -------------------------------------------------------------------------------- /pkg/ipwrapper/ip.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | // Package ipwrapper is a wrapper interface for the containernetworking ip plugin 15 | package ipwrapper 16 | 17 | import ( 18 | "net" 19 | 20 | "github.com/containernetworking/plugins/pkg/ip" 21 | "github.com/vishvananda/netlink" 22 | ) 23 | 24 | // IP is the wrapper interface for the containernetworking ip plugin 25 | type IP interface { 26 | AddDefaultRoute(gw net.IP, dev netlink.Link) error 27 | } 28 | 29 | type ipRoute struct { 30 | } 31 | 32 | // NewIP returns a new IP 33 | func NewIP() IP { 34 | return &ipRoute{} 35 | } 36 | 37 | func (*ipRoute) AddDefaultRoute(gw net.IP, dev netlink.Link) error { 38 | return ip.AddDefaultRoute(gw, dev) 39 | } 40 | -------------------------------------------------------------------------------- /pkg/ipwrapper/mocks/ipwrapper_mocks.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | // 14 | 15 | // Code generated by MockGen. DO NOT EDIT. 16 | // Source: github.com/aws/amazon-vpc-cni-k8s/pkg/ipwrapper (interfaces: IP) 17 | 18 | // Package mock_ipwrapper is a generated GoMock package. 19 | package mock_ipwrapper 20 | 21 | import ( 22 | net "net" 23 | reflect "reflect" 24 | 25 | gomock "github.com/golang/mock/gomock" 26 | netlink "github.com/vishvananda/netlink" 27 | ) 28 | 29 | // MockIP is a mock of IP interface. 30 | type MockIP struct { 31 | ctrl *gomock.Controller 32 | recorder *MockIPMockRecorder 33 | } 34 | 35 | // MockIPMockRecorder is the mock recorder for MockIP. 36 | type MockIPMockRecorder struct { 37 | mock *MockIP 38 | } 39 | 40 | // NewMockIP creates a new mock instance. 41 | func NewMockIP(ctrl *gomock.Controller) *MockIP { 42 | mock := &MockIP{ctrl: ctrl} 43 | mock.recorder = &MockIPMockRecorder{mock} 44 | return mock 45 | } 46 | 47 | // EXPECT returns an object that allows the caller to indicate expected use. 48 | func (m *MockIP) EXPECT() *MockIPMockRecorder { 49 | return m.recorder 50 | } 51 | 52 | // AddDefaultRoute mocks base method. 53 | func (m *MockIP) AddDefaultRoute(arg0 net.IP, arg1 netlink.Link) error { 54 | m.ctrl.T.Helper() 55 | ret := m.ctrl.Call(m, "AddDefaultRoute", arg0, arg1) 56 | ret0, _ := ret[0].(error) 57 | return ret0 58 | } 59 | 60 | // AddDefaultRoute indicates an expected call of AddDefaultRoute. 61 | func (mr *MockIPMockRecorder) AddDefaultRoute(arg0, arg1 interface{}) *gomock.Call { 62 | mr.mock.ctrl.T.Helper() 63 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddDefaultRoute", reflect.TypeOf((*MockIP)(nil).AddDefaultRoute), arg0, arg1) 64 | } 65 | -------------------------------------------------------------------------------- /pkg/k8sapi/k8sutils_test.go: -------------------------------------------------------------------------------- 1 | package k8sapi 2 | 3 | import ( 4 | "context" 5 | "os" 6 | "testing" 7 | 8 | eniconfigscheme "github.com/aws/amazon-vpc-cni-k8s/pkg/apis/crd/v1alpha1" 9 | "github.com/stretchr/testify/assert" 10 | corev1 "k8s.io/api/core/v1" 11 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 12 | "k8s.io/apimachinery/pkg/runtime" 13 | "sigs.k8s.io/controller-runtime/pkg/client/fake" 14 | ) 15 | 16 | func TestGetNode(t *testing.T) { 17 | ctx := context.Background() 18 | k8sSchema := runtime.NewScheme() 19 | corev1.AddToScheme(k8sSchema) 20 | eniconfigscheme.AddToScheme(k8sSchema) 21 | 22 | fakeNode := &corev1.Node{ 23 | ObjectMeta: v1.ObjectMeta{ 24 | Name: "testNode", 25 | }, 26 | } 27 | k8sClient := fake.NewClientBuilder().WithScheme(k8sSchema).WithObjects(fakeNode).Build() 28 | os.Setenv("MY_NODE_NAME", "testNode") 29 | node, err := GetNode(ctx, k8sClient) 30 | assert.NoError(t, err) 31 | assert.Equal(t, node.Name, "testNode") 32 | 33 | os.Setenv("MY_NODE_NAME", "dummyNode") 34 | _, err = GetNode(ctx, k8sClient) 35 | assert.Error(t, err) 36 | } 37 | -------------------------------------------------------------------------------- /pkg/netlinkwrapper/generate_mocks.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package netlinkwrapper 15 | 16 | //go:generate go run github.com/golang/mock/mockgen -destination mocks/netlinkwrapper_mocks.go -copyright_file ../../scripts/copyright.txt . NetLink 17 | //go:generate go run github.com/golang/mock/mockgen -destination mock_netlink/link_mocks.go -copyright_file ../../scripts/copyright.txt github.com/vishvananda/netlink Link 18 | -------------------------------------------------------------------------------- /pkg/netlinkwrapper/mock_netlink/link_mocks.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | // 14 | 15 | // Code generated by MockGen. DO NOT EDIT. 16 | // Source: github.com/vishvananda/netlink (interfaces: Link) 17 | 18 | // Package mock_netlink is a generated GoMock package. 19 | package mock_netlink 20 | 21 | import ( 22 | reflect "reflect" 23 | 24 | gomock "github.com/golang/mock/gomock" 25 | netlink "github.com/vishvananda/netlink" 26 | ) 27 | 28 | // MockLink is a mock of Link interface. 29 | type MockLink struct { 30 | ctrl *gomock.Controller 31 | recorder *MockLinkMockRecorder 32 | } 33 | 34 | // MockLinkMockRecorder is the mock recorder for MockLink. 35 | type MockLinkMockRecorder struct { 36 | mock *MockLink 37 | } 38 | 39 | // NewMockLink creates a new mock instance. 40 | func NewMockLink(ctrl *gomock.Controller) *MockLink { 41 | mock := &MockLink{ctrl: ctrl} 42 | mock.recorder = &MockLinkMockRecorder{mock} 43 | return mock 44 | } 45 | 46 | // EXPECT returns an object that allows the caller to indicate expected use. 47 | func (m *MockLink) EXPECT() *MockLinkMockRecorder { 48 | return m.recorder 49 | } 50 | 51 | // Attrs mocks base method. 52 | func (m *MockLink) Attrs() *netlink.LinkAttrs { 53 | m.ctrl.T.Helper() 54 | ret := m.ctrl.Call(m, "Attrs") 55 | ret0, _ := ret[0].(*netlink.LinkAttrs) 56 | return ret0 57 | } 58 | 59 | // Attrs indicates an expected call of Attrs. 60 | func (mr *MockLinkMockRecorder) Attrs() *gomock.Call { 61 | mr.mock.ctrl.T.Helper() 62 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Attrs", reflect.TypeOf((*MockLink)(nil).Attrs)) 63 | } 64 | 65 | // Type mocks base method. 66 | func (m *MockLink) Type() string { 67 | m.ctrl.T.Helper() 68 | ret := m.ctrl.Call(m, "Type") 69 | ret0, _ := ret[0].(string) 70 | return ret0 71 | } 72 | 73 | // Type indicates an expected call of Type. 74 | func (mr *MockLinkMockRecorder) Type() *gomock.Call { 75 | mr.mock.ctrl.T.Helper() 76 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Type", reflect.TypeOf((*MockLink)(nil).Type)) 77 | } 78 | -------------------------------------------------------------------------------- /pkg/netlinkwrapper/mocks_link/link_mocks.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | // Code generated by MockGen. DO NOT EDIT. 15 | // Source: github.com/vishvananda/netlink (interfaces: Link) 16 | 17 | // Package mock_netlink is a generated GoMock package. 18 | package mock_netlink 19 | 20 | import ( 21 | reflect "reflect" 22 | 23 | gomock "github.com/golang/mock/gomock" 24 | netlink "github.com/vishvananda/netlink" 25 | ) 26 | 27 | // MockLink is a mock of Link interface 28 | type MockLink struct { 29 | ctrl *gomock.Controller 30 | recorder *MockLinkMockRecorder 31 | } 32 | 33 | // MockLinkMockRecorder is the mock recorder for MockLink 34 | type MockLinkMockRecorder struct { 35 | mock *MockLink 36 | } 37 | 38 | // NewMockLink creates a new mock instance 39 | func NewMockLink(ctrl *gomock.Controller) *MockLink { 40 | mock := &MockLink{ctrl: ctrl} 41 | mock.recorder = &MockLinkMockRecorder{mock} 42 | return mock 43 | } 44 | 45 | // EXPECT returns an object that allows the caller to indicate expected use 46 | func (m *MockLink) EXPECT() *MockLinkMockRecorder { 47 | return m.recorder 48 | } 49 | 50 | // Attrs mocks base method 51 | func (m *MockLink) Attrs() *netlink.LinkAttrs { 52 | ret := m.ctrl.Call(m, "Attrs") 53 | ret0, _ := ret[0].(*netlink.LinkAttrs) 54 | return ret0 55 | } 56 | 57 | // Attrs indicates an expected call of Attrs 58 | func (mr *MockLinkMockRecorder) Attrs() *gomock.Call { 59 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Attrs", reflect.TypeOf((*MockLink)(nil).Attrs)) 60 | } 61 | 62 | // Type mocks base method 63 | func (m *MockLink) Type() string { 64 | ret := m.ctrl.Call(m, "Type") 65 | ret0, _ := ret[0].(string) 66 | return ret0 67 | } 68 | 69 | // Type indicates an expected call of Type 70 | func (mr *MockLinkMockRecorder) Type() *gomock.Call { 71 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Type", reflect.TypeOf((*MockLink)(nil).Type)) 72 | } 73 | -------------------------------------------------------------------------------- /pkg/networkutils/generate_mocks.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package networkutils 15 | 16 | //go:generate go run github.com/golang/mock/mockgen -destination mocks/network_mocks.go -copyright_file ../../scripts/copyright.txt . NetworkAPIs 17 | -------------------------------------------------------------------------------- /pkg/networkutils/names.go: -------------------------------------------------------------------------------- 1 | package networkutils 2 | 3 | import ( 4 | "crypto/sha1" 5 | "encoding/hex" 6 | "fmt" 7 | ) 8 | 9 | // GeneratePodHostVethName generates the name for Pod's host-side veth device. 10 | // The veth name is generated in a way that aligns with the value expected by Calico for NetworkPolicy enforcement. 11 | func GeneratePodHostVethName(prefix string, podNamespace string, podName string) string { 12 | suffix := GeneratePodHostVethNameSuffix(podNamespace, podName) 13 | return fmt.Sprintf("%s%s", prefix, suffix) 14 | } 15 | 16 | // GeneratePodHostVethNameSuffix generates the name suffix for Pod's hostVeth. 17 | func GeneratePodHostVethNameSuffix(podNamespace string, podName string) string { 18 | h := sha1.New() 19 | h.Write([]byte(fmt.Sprintf("%s.%s", podNamespace, podName))) 20 | return hex.EncodeToString(h.Sum(nil))[:11] 21 | } 22 | -------------------------------------------------------------------------------- /pkg/networkutils/names_test.go: -------------------------------------------------------------------------------- 1 | package networkutils 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestGeneratePodHostVethName(t *testing.T) { 10 | type args struct { 11 | prefix string 12 | podNamespace string 13 | podName string 14 | } 15 | tests := []struct { 16 | name string 17 | args args 18 | want string 19 | }{ 20 | { 21 | name: "with eni as prefix", 22 | args: args{ 23 | prefix: "eni", 24 | podNamespace: "kube-system", 25 | podName: "coredns-57ff979f67-qqbdh", 26 | }, 27 | want: "enib5faff8a083", 28 | }, 29 | { 30 | name: "with vlan as prefix", 31 | args: args{ 32 | prefix: "vlan", 33 | podNamespace: "kube-system", 34 | podName: "coredns-57ff979f67-qqbdh", 35 | }, 36 | want: "vlanb5faff8a083", 37 | }, 38 | } 39 | for _, tt := range tests { 40 | t.Run(tt.name, func(t *testing.T) { 41 | got := GeneratePodHostVethName(tt.args.prefix, tt.args.podNamespace, tt.args.podName) 42 | assert.Equal(t, tt.want, got) 43 | }) 44 | } 45 | } 46 | 47 | func TestGeneratePodHostVethNameSuffix(t *testing.T) { 48 | type args struct { 49 | podNamespace string 50 | podName string 51 | } 52 | tests := []struct { 53 | name string 54 | args args 55 | want string 56 | }{ 57 | { 58 | name: "kube-system/coredns-57ff979f67-qqbdh", 59 | args: args{ 60 | podNamespace: "kube-system", 61 | podName: "coredns-57ff979f67-qqbdh", 62 | }, 63 | want: "b5faff8a083", 64 | }, 65 | { 66 | name: "kube-system/coredns-57ff979f67-8ns9b", 67 | args: args{ 68 | podNamespace: "kube-system", 69 | podName: "coredns-57ff979f67-8ns9b", 70 | }, 71 | want: "9571956a6cc", 72 | }, 73 | { 74 | name: "default/sample-pod", 75 | args: args{ 76 | podNamespace: "default", 77 | podName: "sample-pod", 78 | }, 79 | want: "cc21c2d7785", 80 | }, 81 | } 82 | for _, tt := range tests { 83 | t.Run("", func(t *testing.T) { 84 | got := GeneratePodHostVethNameSuffix(tt.args.podNamespace, tt.args.podName) 85 | assert.Equal(t, tt.want, got) 86 | }) 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /pkg/nswrapper/generate_mocks.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package nswrapper 15 | 16 | //go:generate go run github.com/golang/mock/mockgen -destination mocks/nswrapper_mocks.go -copyright_file ../../scripts/copyright.txt . NS 17 | -------------------------------------------------------------------------------- /pkg/nswrapper/mocks/nswrapper_mocks.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | // 14 | 15 | // Code generated by MockGen. DO NOT EDIT. 16 | // Source: github.com/aws/amazon-vpc-cni-k8s/pkg/nswrapper (interfaces: NS) 17 | 18 | // Package mock_nswrapper is a generated GoMock package. 19 | package mock_nswrapper 20 | 21 | import ( 22 | reflect "reflect" 23 | 24 | ns "github.com/containernetworking/plugins/pkg/ns" 25 | gomock "github.com/golang/mock/gomock" 26 | ) 27 | 28 | // MockNS is a mock of NS interface. 29 | type MockNS struct { 30 | ctrl *gomock.Controller 31 | recorder *MockNSMockRecorder 32 | } 33 | 34 | // MockNSMockRecorder is the mock recorder for MockNS. 35 | type MockNSMockRecorder struct { 36 | mock *MockNS 37 | } 38 | 39 | // NewMockNS creates a new mock instance. 40 | func NewMockNS(ctrl *gomock.Controller) *MockNS { 41 | mock := &MockNS{ctrl: ctrl} 42 | mock.recorder = &MockNSMockRecorder{mock} 43 | return mock 44 | } 45 | 46 | // EXPECT returns an object that allows the caller to indicate expected use. 47 | func (m *MockNS) EXPECT() *MockNSMockRecorder { 48 | return m.recorder 49 | } 50 | 51 | // WithNetNSPath mocks base method. 52 | func (m *MockNS) WithNetNSPath(arg0 string, arg1 func(ns.NetNS) error) error { 53 | m.ctrl.T.Helper() 54 | ret := m.ctrl.Call(m, "WithNetNSPath", arg0, arg1) 55 | ret0, _ := ret[0].(error) 56 | return ret0 57 | } 58 | 59 | // WithNetNSPath indicates an expected call of WithNetNSPath. 60 | func (mr *MockNSMockRecorder) WithNetNSPath(arg0, arg1 interface{}) *gomock.Call { 61 | mr.mock.ctrl.T.Helper() 62 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WithNetNSPath", reflect.TypeOf((*MockNS)(nil).WithNetNSPath), arg0, arg1) 63 | } 64 | -------------------------------------------------------------------------------- /pkg/nswrapper/ns.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | // Package nswrapper is a wrapper interface for the containernetworking ns plugin 15 | package nswrapper 16 | 17 | import ( 18 | "github.com/containernetworking/plugins/pkg/ns" 19 | ) 20 | 21 | // NS is the wrapper interface for the containernetworking ns plugin 22 | type NS interface { 23 | WithNetNSPath(nspath string, toRun func(ns.NetNS) error) error 24 | } 25 | 26 | type nsType struct { 27 | } 28 | 29 | // NewNS returns a new NS 30 | func NewNS() NS { 31 | return &nsType{} 32 | } 33 | 34 | func (*nsType) WithNetNSPath(nspath string, toRun func(ns.NetNS) error) error { 35 | return ns.WithNetNSPath(nspath, toRun) 36 | 37 | } 38 | -------------------------------------------------------------------------------- /pkg/procsyswrapper/generate_mocks.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package procsyswrapper 15 | 16 | //go:generate go run github.com/golang/mock/mockgen -destination mocks/procsys_mocks.go -copyright_file ../../scripts/copyright.txt . ProcSys 17 | -------------------------------------------------------------------------------- /pkg/procsyswrapper/procsys.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | // Package procsyswrapper contains helper functions for doing /proc/sys calls 15 | package procsyswrapper 16 | 17 | import ( 18 | "os" 19 | ) 20 | 21 | // ProcSys is the /proc/sys interface wrapper 22 | type ProcSys interface { 23 | Get(key string) (string, error) 24 | Set(key, value string) error 25 | } 26 | 27 | type procSys struct { 28 | prefix string 29 | } 30 | 31 | // NewProcSys returns a new ProcSys 32 | func NewProcSys() ProcSys { 33 | return &procSys{prefix: "/proc/sys/"} 34 | } 35 | 36 | func (p *procSys) path(key string) string { 37 | return p.prefix + key 38 | } 39 | 40 | func (p *procSys) Get(key string) (string, error) { 41 | data, err := os.ReadFile(p.path(key)) 42 | return string(data), err 43 | } 44 | 45 | func (p *procSys) Set(key, value string) error { 46 | return os.WriteFile(p.path(key), []byte(value), 0644) 47 | } 48 | -------------------------------------------------------------------------------- /pkg/publisher/generate_mocks.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package publisher 15 | 16 | //go:generate go run github.com/golang/mock/mockgen -source=publisher.go -destination mock_publisher/mock_publisher.go -copyright_file ../../scripts/copyright.txt . 17 | -------------------------------------------------------------------------------- /pkg/rpcwrapper/client.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | // Package rpcwrapper is a wrapper for the CNI IPAMD pod connection 15 | package rpcwrapper 16 | 17 | import ( 18 | "github.com/aws/amazon-vpc-cni-k8s/rpc" 19 | grpc "google.golang.org/grpc" 20 | ) 21 | 22 | // RPC is the wrapper interface for the CNI and network policy agent gRPC backend clients 23 | type RPC interface { 24 | NewCNIBackendClient(cc *grpc.ClientConn) rpc.CNIBackendClient 25 | NewNPBackendClient(cc *grpc.ClientConn) rpc.NPBackendClient 26 | } 27 | 28 | type cniRPC struct{} 29 | 30 | // New returns a new RPC 31 | func New() RPC { 32 | return &cniRPC{} 33 | } 34 | 35 | func (*cniRPC) NewCNIBackendClient(cc *grpc.ClientConn) rpc.CNIBackendClient { 36 | return rpc.NewCNIBackendClient(cc) 37 | } 38 | 39 | func (*cniRPC) NewNPBackendClient(cc *grpc.ClientConn) rpc.NPBackendClient { 40 | return rpc.NewNPBackendClient(cc) 41 | } 42 | -------------------------------------------------------------------------------- /pkg/rpcwrapper/generate_mocks.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package rpcwrapper 15 | 16 | //go:generate go run github.com/golang/mock/mockgen -destination mocks/rpcwrapper_mocks.go -copyright_file ../../scripts/copyright.txt . RPC 17 | -------------------------------------------------------------------------------- /pkg/sgpp/constants.go: -------------------------------------------------------------------------------- 1 | package sgpp 2 | 3 | type EnforcingMode string 4 | 5 | const ( 6 | EnforcingModeStrict EnforcingMode = "strict" 7 | EnforcingModeStandard EnforcingMode = "standard" 8 | VpcCNINodeEventActionForTrunk string = "NeedTrunk" 9 | TrunkEventNote string = "vpc.amazonaws.com/has-trunk-attached=false" 10 | VpcCNINodeEventActionForEniConfig string = "NeedEniConfig" 11 | VpcCNIEventReason string = "AwsNodeNotificationToRc" 12 | ) 13 | 14 | const ( 15 | // DefaultEnforcingMode is the default enforcing mode if not specified explicitly. 16 | DefaultEnforcingMode EnforcingMode = EnforcingModeStrict 17 | // environment variable knob to decide EnforcingMode for SGPP feature. 18 | envEnforcingMode = "POD_SECURITY_GROUP_ENFORCING_MODE" 19 | ) 20 | -------------------------------------------------------------------------------- /pkg/sgpp/utils.go: -------------------------------------------------------------------------------- 1 | package sgpp 2 | 3 | import ( 4 | "os" 5 | ) 6 | 7 | const vlanInterfacePrefix = "vlan" 8 | 9 | // BuildHostVethNamePrefix computes the name prefix for host-side veth pairs for SGPP pods 10 | // for the "standard" mode, we use the same hostVethNamePrefix as normal pods, which is "eni" by default, but can be overwritten as well. 11 | // for the "strict" mode, we use dedicated "vlan" hostVethNamePrefix, which is to opt-out SNAT support and opt-out calico's workload management. 12 | func BuildHostVethNamePrefix(hostVethNamePrefix string, podSGEnforcingMode EnforcingMode) string { 13 | switch podSGEnforcingMode { 14 | case EnforcingModeStrict: 15 | return vlanInterfacePrefix 16 | case EnforcingModeStandard: 17 | return hostVethNamePrefix 18 | default: 19 | return vlanInterfacePrefix 20 | } 21 | } 22 | 23 | // LoadEnforcingModeFromEnv tries to load the enforcing mode from environment variable and fall-back to DefaultEnforcingMode. 24 | func LoadEnforcingModeFromEnv() EnforcingMode { 25 | envVal, _ := os.LookupEnv(envEnforcingMode) 26 | switch envVal { 27 | case string(EnforcingModeStrict): 28 | return EnforcingModeStrict 29 | case string(EnforcingModeStandard): 30 | return EnforcingModeStandard 31 | default: 32 | return DefaultEnforcingMode 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /pkg/typeswrapper/client.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | // Package typeswrapper is a wrapper interface for containernetworking types package 15 | package typeswrapper 16 | 17 | import ( 18 | cnitypes "github.com/containernetworking/cni/pkg/types" 19 | ) 20 | 21 | // CNITYPES is the wrapper interface for containernetworking types package 22 | type CNITYPES interface { 23 | LoadArgs(args string, container interface{}) error 24 | PrintResult(result cnitypes.Result, version string) error 25 | } 26 | 27 | type cniTYPES struct{} 28 | 29 | // New returns a new CNITYPES 30 | func New() CNITYPES { 31 | return &cniTYPES{} 32 | } 33 | 34 | func (*cniTYPES) LoadArgs(args string, container interface{}) error { 35 | return cnitypes.LoadArgs(args, container) 36 | } 37 | 38 | func (*cniTYPES) PrintResult(result cnitypes.Result, version string) error { 39 | return cnitypes.PrintResult(result, version) 40 | } 41 | -------------------------------------------------------------------------------- /pkg/typeswrapper/generate_mocks.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package typeswrapper 15 | 16 | //go:generate go run github.com/golang/mock/mockgen -destination mocks/typeswrapper_mocks.go -copyright_file ../../scripts/copyright.txt . CNITYPES 17 | -------------------------------------------------------------------------------- /pkg/utils/eventrecorder/eventrecorder_test.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package eventrecorder 15 | 16 | import ( 17 | "context" 18 | "fmt" 19 | "testing" 20 | 21 | "github.com/aws/amazon-vpc-cni-k8s/test/framework/utils" 22 | "github.com/golang/mock/gomock" 23 | "github.com/stretchr/testify/assert" 24 | v1 "k8s.io/api/core/v1" 25 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 26 | "k8s.io/client-go/tools/events" 27 | ) 28 | 29 | var fakeRecorder *events.FakeRecorder 30 | 31 | func setup(t *testing.T) *gomock.Controller { 32 | fakeRecorder = InitMockEventRecorder() 33 | return gomock.NewController(t) 34 | } 35 | 36 | func TestSendPodEvent(t *testing.T) { 37 | ctrl := setup(t) 38 | defer ctrl.Finish() 39 | ctx := context.Background() 40 | MyPodName = "aws-node-5test" 41 | mockEventRecorder := Get() 42 | 43 | labels := map[string]string{"k8s-app": "aws-node"} 44 | pod := v1.Pod{ 45 | ObjectMeta: metav1.ObjectMeta{ 46 | Name: MyPodName, 47 | Namespace: utils.AwsNodeNamespace, 48 | Labels: labels, 49 | }, 50 | } 51 | // Create pod 52 | mockEventRecorder.K8sClient.Create(ctx, &pod) 53 | 54 | // Validate event call for missing permissions case 55 | action := "ec2:DescribeNetworkInterfaces" 56 | reason := "MissingIAMPermission" 57 | msg := "Failed to call ec2:DescribeNetworkInterfaces due to missing permissions. Please refer to https://github.com/aws/amazon-vpc-cni-k8s/blob/master/docs/iam-policy.md" 58 | mockEventRecorder.SendPodEvent(v1.EventTypeWarning, reason, action, msg) 59 | assert.Len(t, fakeRecorder.Events, 1) 60 | 61 | expected := fmt.Sprintf("%s %s %s", v1.EventTypeWarning, reason, msg) 62 | got := <-fakeRecorder.Events 63 | assert.Equal(t, expected, got) 64 | } 65 | -------------------------------------------------------------------------------- /pkg/utils/logger/config.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package logger 15 | 16 | import ( 17 | "os" 18 | ) 19 | 20 | const ( 21 | defaultLogFilePath = "/host/var/log/aws-routed-eni/ipamd.log" 22 | defaultLogLevel = "Debug" 23 | envLogLevel = "AWS_VPC_K8S_CNI_LOGLEVEL" 24 | envLogFilePath = "AWS_VPC_K8S_CNI_LOG_FILE" 25 | ) 26 | 27 | // Configuration stores the config for the logger 28 | type Configuration struct { 29 | LogLevel string 30 | LogLocation string 31 | } 32 | 33 | // LoadLogConfig returns the log configuration 34 | func LoadLogConfig() *Configuration { 35 | return &Configuration{ 36 | LogLevel: GetLogLevel(), 37 | LogLocation: GetLogLocation(), 38 | } 39 | } 40 | 41 | // GetLogLocation returns the log file path 42 | func GetLogLocation() string { 43 | logFilePath := os.Getenv(envLogFilePath) 44 | if logFilePath == "" { 45 | logFilePath = defaultLogFilePath 46 | } 47 | return logFilePath 48 | } 49 | 50 | // GetLogLevel returns the log level 51 | func GetLogLevel() string { 52 | logLevel := os.Getenv(envLogLevel) 53 | switch logLevel { 54 | case "": 55 | logLevel = defaultLogLevel 56 | return logLevel 57 | default: 58 | return logLevel 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /pkg/utils/logger/logger.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | // Package logger is the CNI Logger interface, using zap 15 | package logger 16 | 17 | // Log is global variable so that log functions can be directly accessed 18 | var log Logger 19 | 20 | // Fields Type to pass when we want to call WithFields for structured logging 21 | type Fields map[string]interface{} 22 | 23 | // Logger is our contract for the logger 24 | type Logger interface { 25 | Debugf(format string, args ...interface{}) 26 | 27 | Debug(format string) 28 | 29 | Infof(format string, args ...interface{}) 30 | 31 | Info(format string) 32 | 33 | Warnf(format string, args ...interface{}) 34 | 35 | Warn(format string) 36 | 37 | Errorf(format string, args ...interface{}) 38 | 39 | Error(format string) 40 | 41 | Fatalf(format string, args ...interface{}) 42 | 43 | Panicf(format string, args ...interface{}) 44 | 45 | WithFields(keyValues Fields) Logger 46 | } 47 | 48 | // Get returns an default instance of the zap logger 49 | func Get() Logger { 50 | if log == nil { 51 | logConfig := LoadLogConfig() 52 | log = New(logConfig) 53 | log.Info("Initialized new logger as an existing instance was not found") 54 | } 55 | return log 56 | } 57 | 58 | // New logger initializes logger 59 | func New(inputLogConfig *Configuration) Logger { 60 | log = inputLogConfig.newZapLogger() 61 | log.Info("Constructed new logger instance") 62 | return log 63 | } 64 | -------------------------------------------------------------------------------- /pkg/utils/retry/backoff_test.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package retry 15 | 16 | import ( 17 | "testing" 18 | "time" 19 | ) 20 | 21 | func TestSimpleBackoff(t *testing.T) { 22 | sb := NewSimpleBackoff(10*time.Second, time.Minute, 0, 2) 23 | 24 | for i := 0; i < 2; i++ { 25 | duration := sb.Duration() 26 | if duration.Nanoseconds() != 10*time.Second.Nanoseconds() { 27 | t.Error("Initial duration incorrect. Got ", duration.Nanoseconds()) 28 | } 29 | 30 | duration = sb.Duration() 31 | if duration.Nanoseconds() != 20*time.Second.Nanoseconds() { 32 | t.Error("Increase incorrect") 33 | } 34 | _ = sb.Duration() // 40s 35 | duration = sb.Duration() 36 | if duration.Nanoseconds() != 60*time.Second.Nanoseconds() { 37 | t.Error("Didn't stop at maximum") 38 | } 39 | sb.Reset() 40 | // loop to redo the above tests after resetting, they should be the same 41 | } 42 | } 43 | 44 | func TestJitter(t *testing.T) { 45 | for i := 0; i < 10; i++ { 46 | duration := AddJitter(10*time.Second, 3*time.Second) 47 | if duration < 10*time.Second || duration > 13*time.Second { 48 | t.Error("Excessive amount of jitter", duration) 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /pkg/utils/retry/errors.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package retry 15 | 16 | // Retriable is the retry interface 17 | type Retriable interface { 18 | Retry() bool 19 | } 20 | 21 | // DefaultRetriable is the default retryable 22 | type DefaultRetriable struct { 23 | retry bool 24 | } 25 | 26 | // Retry does the retry 27 | func (dr DefaultRetriable) Retry() bool { 28 | return dr.retry 29 | } 30 | 31 | // NewRetriable creates a new Retriable 32 | func NewRetriable(retry bool) Retriable { 33 | return DefaultRetriable{ 34 | retry: retry, 35 | } 36 | } 37 | 38 | // RetriableError interface 39 | type RetriableError interface { 40 | Retriable 41 | error 42 | } 43 | 44 | // DefaultRetriableError is the default retriable error 45 | type DefaultRetriableError struct { 46 | Retriable 47 | error 48 | } 49 | 50 | // NewRetriableError returns a new retriable error 51 | func NewRetriableError(retriable Retriable, err error) RetriableError { 52 | return &DefaultRetriableError{ 53 | retriable, 54 | err, 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /pkg/utils/ttime/generate_mocks.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package ttime 15 | 16 | //go:generate go run github.com/golang/mock/mockgen -destination mocks/time_mocks.go -copyright_file ../../../scripts/copyright.txt . Time,Timer 17 | -------------------------------------------------------------------------------- /pkg/utils/ttime/ttime.go: -------------------------------------------------------------------------------- 1 | // Package ttime implements a testable alternative to the Go "time" package. 2 | package ttime 3 | 4 | import "time" 5 | 6 | // Time represents an implementation for this package's methods 7 | type Time interface { 8 | Now() time.Time 9 | Sleep(d time.Duration) 10 | After(d time.Duration) <-chan time.Time 11 | AfterFunc(d time.Duration, f func()) Timer 12 | } 13 | 14 | // Timer is the timer interface 15 | type Timer interface { 16 | Reset(d time.Duration) bool 17 | Stop() bool 18 | } 19 | 20 | // DefaultTime is a Time that behaves normally 21 | type DefaultTime struct{} 22 | 23 | // Now returns the current time 24 | func (*DefaultTime) Now() time.Time { 25 | return time.Now() 26 | } 27 | 28 | // Sleep sleeps for the given duration 29 | func (*DefaultTime) Sleep(d time.Duration) { 30 | time.Sleep(d) 31 | } 32 | 33 | // After sleeps for the given duration and then writes to to the returned channel 34 | func (*DefaultTime) After(d time.Duration) <-chan time.Time { 35 | return time.After(d) 36 | } 37 | 38 | // AfterFunc waits for the duration to elapse and then calls f in its own 39 | // goroutine. It returns a Timer that can be used to cancel the call using its 40 | // Stop method. 41 | func (*DefaultTime) AfterFunc(d time.Duration, f func()) Timer { 42 | return time.AfterFunc(d, f) 43 | } 44 | -------------------------------------------------------------------------------- /pkg/version/info.go: -------------------------------------------------------------------------------- 1 | package version 2 | 3 | import ( 4 | "runtime" 5 | 6 | "github.com/prometheus/client_golang/prometheus" 7 | ) 8 | 9 | // Build information. Populated at build-time. 10 | var ( 11 | Version string 12 | GoVersion = runtime.Version() 13 | ) 14 | 15 | func RegisterMetric() { 16 | buildInfo := prometheus.NewGaugeVec( 17 | prometheus.GaugeOpts{ 18 | Name: "awscni_build_info", 19 | Help: "A metric with a constant '1' value labeled by version, revision, and goversion from which amazon-vpc-cni-k8s was built.", 20 | }, 21 | []string{"version", "goversion"}, 22 | ) 23 | buildInfo.WithLabelValues(Version, GoVersion).Set(1) 24 | prometheus.MustRegister(buildInfo) 25 | } 26 | -------------------------------------------------------------------------------- /pkg/vethwrapper/generate_mocks.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package vethwrapper 15 | 16 | //go:generate go run github.com/golang/mock/mockgen -destination mocks/veth_mocks.go -copyright_file ../../scripts/copyright.txt . Veth 17 | -------------------------------------------------------------------------------- /pkg/vethwrapper/mocks/veth_mocks.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | // 14 | 15 | // Code generated by MockGen. DO NOT EDIT. 16 | // Source: github.com/aws/amazon-vpc-cni-k8s/pkg/vethwrapper (interfaces: Veth) 17 | 18 | // Package mock_vethwrapper is a generated GoMock package. 19 | package mock_vethwrapper 20 | 21 | import ( 22 | net "net" 23 | reflect "reflect" 24 | 25 | ns "github.com/containernetworking/plugins/pkg/ns" 26 | gomock "github.com/golang/mock/gomock" 27 | ) 28 | 29 | // MockVeth is a mock of Veth interface. 30 | type MockVeth struct { 31 | ctrl *gomock.Controller 32 | recorder *MockVethMockRecorder 33 | } 34 | 35 | // MockVethMockRecorder is the mock recorder for MockVeth. 36 | type MockVethMockRecorder struct { 37 | mock *MockVeth 38 | } 39 | 40 | // NewMockVeth creates a new mock instance. 41 | func NewMockVeth(ctrl *gomock.Controller) *MockVeth { 42 | mock := &MockVeth{ctrl: ctrl} 43 | mock.recorder = &MockVethMockRecorder{mock} 44 | return mock 45 | } 46 | 47 | // EXPECT returns an object that allows the caller to indicate expected use. 48 | func (m *MockVeth) EXPECT() *MockVethMockRecorder { 49 | return m.recorder 50 | } 51 | 52 | // Setup mocks base method. 53 | func (m *MockVeth) Setup(arg0 string, arg1 int, arg2 string, arg3 ns.NetNS) (net.Interface, net.Interface, error) { 54 | m.ctrl.T.Helper() 55 | ret := m.ctrl.Call(m, "Setup", arg0, arg1, arg2, arg3) 56 | ret0, _ := ret[0].(net.Interface) 57 | ret1, _ := ret[1].(net.Interface) 58 | ret2, _ := ret[2].(error) 59 | return ret0, ret1, ret2 60 | } 61 | 62 | // Setup indicates an expected call of Setup. 63 | func (mr *MockVethMockRecorder) Setup(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { 64 | mr.mock.ctrl.T.Helper() 65 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Setup", reflect.TypeOf((*MockVeth)(nil).Setup), arg0, arg1, arg2, arg3) 66 | } 67 | -------------------------------------------------------------------------------- /pkg/vethwrapper/veth.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | // Package vethwrapper is a wrapper method for the ip.SetupVeth method 15 | package vethwrapper 16 | 17 | import ( 18 | "net" 19 | 20 | "github.com/containernetworking/plugins/pkg/ip" 21 | "github.com/containernetworking/plugins/pkg/ns" 22 | ) 23 | 24 | // Veth is an interface created to make code unit testable. 25 | // Both the veth version and mocked version implement the same interface 26 | type Veth interface { 27 | Setup(contVethName string, mtu int, contVethMac string, hostNS ns.NetNS) (net.Interface, net.Interface, error) 28 | } 29 | 30 | type veth struct{} 31 | 32 | // NewSetupVeth return a new veth object 33 | func NewSetupVeth() Veth { 34 | return &veth{} 35 | } 36 | func (v *veth) Setup(contVethName string, mtu int, contVethMac string, hostNS ns.NetNS) (net.Interface, net.Interface, error) { 37 | return ip.SetupVeth(contVethName, mtu, contVethMac, hostNS) 38 | } 39 | -------------------------------------------------------------------------------- /rpc/generate_mocks.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package rpc 15 | 16 | //go:generate protoc --go_out=plugins=grpc,paths=source_relative:. rpc.proto 17 | //go:generate go run github.com/golang/mock/mockgen -destination mocks/rpc_mocks.go -copyright_file ../scripts/copyright.txt . CNIBackendClient,NPBackendClient 18 | -------------------------------------------------------------------------------- /scripts/copyright.txt: -------------------------------------------------------------------------------- 1 | Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | not use this file except in compliance with the License. A copy of the 5 | License is located at 6 | 7 | http://aws.amazon.com/apache2.0/ 8 | 9 | or in the "license" file accompanying this file. This file is distributed 10 | on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | express or implied. See the License for the specific language governing 12 | permissions and limitations under the License. 13 | -------------------------------------------------------------------------------- /scripts/dockerfiles/Dockerfile.init: -------------------------------------------------------------------------------- 1 | ARG golang_image 2 | ARG base_image 3 | 4 | FROM $golang_image AS builder 5 | WORKDIR /go/src/github.com/aws/amazon-vpc-cni-k8s 6 | ARG TARGETARCH 7 | # Configure build with Go modules 8 | ENV GO111MODULE=on 9 | ENV GOPROXY=direct 10 | 11 | COPY . ./ 12 | RUN make plugins && make debug-script 13 | RUN make build-aws-vpc-cni-init 14 | 15 | # Build from EKS minimal base + glibc by default 16 | FROM $base_image 17 | 18 | WORKDIR /init 19 | 20 | COPY --from=builder \ 21 | /go/src/github.com/aws/amazon-vpc-cni-k8s/core-plugins/* \ 22 | /go/src/github.com/aws/amazon-vpc-cni-k8s/aws-cni-support.sh \ 23 | /go/src/github.com/aws/amazon-vpc-cni-k8s/aws-vpc-cni-init /init/ 24 | 25 | CMD ["/init/aws-vpc-cni-init"] 26 | -------------------------------------------------------------------------------- /scripts/dockerfiles/Dockerfile.metrics: -------------------------------------------------------------------------------- 1 | ARG golang_image 2 | ARG base_image 3 | 4 | FROM $golang_image AS builder 5 | WORKDIR /go/src/github.com/aws/amazon-vpc-cni-k8s 6 | # Configure build with Go modules 7 | ENV GO111MODULE=on 8 | ENV GOPROXY=direct 9 | 10 | COPY . ./ 11 | RUN make build-metrics 12 | 13 | # Build from EKS minimal base + glibc by default 14 | FROM $base_image 15 | 16 | # Copy our bundled certs to the first place go will check: see 17 | # https://golang.org/src/pkg/crypto/x509/root_unix.go 18 | COPY ./misc/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt 19 | 20 | WORKDIR /app 21 | 22 | COPY --from=builder /go/src/github.com/aws/amazon-vpc-cni-k8s/cni-metrics-helper /app 23 | 24 | ENTRYPOINT ["/app/cni-metrics-helper", "--cloudwatch=false"] 25 | -------------------------------------------------------------------------------- /scripts/dockerfiles/Dockerfile.release: -------------------------------------------------------------------------------- 1 | ARG golang_image 2 | ARG base_image 3 | 4 | FROM $golang_image AS builder 5 | WORKDIR /go/src/github.com/aws/amazon-vpc-cni-k8s 6 | ARG TARGETARCH 7 | # Configure build with Go modules 8 | ENV GO111MODULE=on 9 | ENV GOPROXY=direct 10 | 11 | COPY . ./ 12 | RUN make build-aws-vpc-cni && make build-linux 13 | 14 | # Build from EKS minimal base + iptables by default 15 | FROM $base_image 16 | 17 | WORKDIR /app 18 | 19 | COPY --from=builder /go/src/github.com/aws/amazon-vpc-cni-k8s/aws-cni \ 20 | /go/src/github.com/aws/amazon-vpc-cni-k8s/misc/10-aws.conflist \ 21 | /go/src/github.com/aws/amazon-vpc-cni-k8s/misc/eni-max-pods.txt \ 22 | /go/src/github.com/aws/amazon-vpc-cni-k8s/aws-k8s-agent \ 23 | /go/src/github.com/aws/amazon-vpc-cni-k8s/grpc-health-probe \ 24 | /go/src/github.com/aws/amazon-vpc-cni-k8s/egress-cni \ 25 | /go/src/github.com/aws/amazon-vpc-cni-k8s/aws-vpc-cni /app/ 26 | 27 | # Set iptables mode automatically based on kubelet hint 28 | RUN ["update-alternatives", "--set", "iptables", "/usr/sbin/iptables-wrapper"] 29 | 30 | ENTRYPOINT ["/app/aws-vpc-cni"] 31 | -------------------------------------------------------------------------------- /scripts/dockerfiles/Dockerfile.test: -------------------------------------------------------------------------------- 1 | ARG golang_image 2 | FROM $golang_image 3 | WORKDIR /go/src/github.com/aws/amazon-vpc-cni-k8s 4 | 5 | # Force the go compiler to use modules. 6 | ENV GO111MODULE=on 7 | ENV GOPROXY=direct 8 | 9 | # Add goimports 10 | RUN go install golang.org/x/tools/cmd/goimports@latest 11 | 12 | # go.mod and go.sum go into their own layers. 13 | COPY go.mod . 14 | COPY go.sum . 15 | 16 | # This ensures `go mod download` happens only when go.mod and go.sum change. 17 | RUN go mod download 18 | 19 | COPY . . 20 | -------------------------------------------------------------------------------- /scripts/ec2_model_override/cleanup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | rm -rf ./vendor 4 | go mod edit -dropreplace github.com/aws/aws-sdk-go 5 | go mod tidy 6 | -------------------------------------------------------------------------------- /scripts/ec2_model_override/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | mkdir -p ./vendor/github.com/aws 6 | 7 | SDK_MODEL_SOURCE=./hack/ec2_preview_models 8 | SDK_VENDOR_PATH=./vendor/github.com/aws/aws-sdk-go 9 | API_VERSION=2016-11-15 10 | API_PATH=$SDK_VENDOR_PATH/models/apis/ec2/$API_VERSION 11 | 12 | # Clone the SDK to the vendor path (removing an old one if necessary) 13 | rm -rf $SDK_VENDOR_PATH 14 | git clone --depth 1 https://github.com/aws/aws-sdk-go.git $SDK_VENDOR_PATH 15 | 16 | # Override the SDK models for AWS VPC CNI 17 | cp $SDK_MODEL_SOURCE/api-2.json $API_PATH/api-2.json 18 | cp $SDK_MODEL_SOURCE/docs-2.json $API_PATH/docs-2.json 19 | cp $SDK_MODEL_SOURCE/examples-1.json $API_PATH/examples-1.json 20 | cp $SDK_MODEL_SOURCE/paginators-1.json $API_PATH/paginators-1.json 21 | 22 | # Generate the SDK 23 | pushd ./vendor/github.com/aws/aws-sdk-go 24 | make generate 25 | popd 26 | 27 | # Use the vendored version of aws-sdk-go 28 | go mod edit -replace github.com/aws/aws-sdk-go=./vendor/github.com/aws/aws-sdk-go 29 | go mod tidy 30 | -------------------------------------------------------------------------------- /scripts/lib/aws.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | check_aws_credentials() { 4 | aws sts get-caller-identity --query "Account" || 5 | ( echo "No AWS credentials found. Please run \`aws configure\` to set up the CLI for your credentials." && exit 1) 6 | } 7 | 8 | ensure_ecr_repo() { 9 | echo "Ensuring that $2 exists for account $1" 10 | local __registry_account_id="$1" 11 | local __repo_name="$2" 12 | local __region="$3" 13 | if ! `aws ecr describe-repositories --registry-id "$__registry_account_id" --repository-names "$__repo_name" --region "$__region" >/dev/null 2>&1`; then 14 | echo "creating ECR repo with name $__repo_name in registry account $__registry_account_id" 15 | aws ecr create-repository --repository-name "$__repo_name" --region "$__region" 16 | fi 17 | } 18 | 19 | emit_cloudwatch_metric() { 20 | aws cloudwatch put-metric-data --metric-name $1 --namespace TestExecution --unit None --value $2 --region $AWS_DEFAULT_REGION 21 | } 22 | 23 | -------------------------------------------------------------------------------- /scripts/lib/canary.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Helper script used for running canary test for CNI IPv4 and IPv6 4 | 5 | SECONDS=0 6 | 7 | source "$SCRIPT_DIR"/lib/set_kubeconfig.sh 8 | 9 | echo "Running tests for amazon-vpc-cni-k8s with the following variables 10 | KUBECONFIG: $KUBECONFIG 11 | CLUSTER_NAME: $CLUSTER_NAME 12 | REGION: $REGION 13 | ENDPOINT: $ENDPOINT" 14 | 15 | if [[ -n "${ENDPOINT}" ]]; then 16 | ENDPOINT_FLAG="--endpoint $ENDPOINT" 17 | ENDPOINT_OPTION=" --eks-endpoint $ENDPOINT" 18 | fi 19 | 20 | if [[ -z "${SKIP_MAKE_TEST_BINARIES}" ]]; then 21 | echo "making ginkgo test binaries" 22 | (cd $SCRIPT_DIR/../ && make build-test-binaries) 23 | else 24 | echo "skipping making ginkgo test binaries" 25 | fi 26 | 27 | # Request times out in China Regions with default proxy 28 | if [[ $REGION == "cn-north-1" || $REGION == "cn-northwest-1" ]]; then 29 | go env -w GOPROXY=https://goproxy.cn,direct 30 | go env -w GOSUMDB=sum.golang.google.cn 31 | fi 32 | -------------------------------------------------------------------------------- /scripts/lib/common.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | check_is_installed() { 4 | local __name="$1" 5 | if ! is_installed "$__name"; then 6 | echo "Please install $__name before running this script." 7 | exit 1 8 | fi 9 | } 10 | 11 | is_installed() { 12 | local __name="$1" 13 | if $(which $__name >/dev/null 2>&1); then 14 | return 0 15 | else 16 | return 1 17 | fi 18 | } 19 | 20 | function display_timelines() { 21 | echo "" 22 | echo "Displaying all step durations." 23 | echo "TIMELINE: Upping test cluster took $UP_CLUSTER_DURATION seconds." 24 | if [[ "$RUN_CNI_INTEGRATION_TESTS" == true ]]; then 25 | echo "TIMELINE: Current image integration tests took $CURRENT_IMAGE_INTEGRATION_DURATION seconds." 26 | fi 27 | if [[ "$RUN_CONFORMANCE" == true ]]; then 28 | echo "TIMELINE: Conformance tests took $CONFORMANCE_DURATION seconds." 29 | fi 30 | if [[ "$RUN_PERFORMANCE_TESTS" == true ]]; then 31 | echo "TIMELINE: Performance tests took $PERFORMANCE_DURATION seconds." 32 | fi 33 | echo "TIMELINE: Down processes took $DOWN_DURATION seconds." 34 | } 35 | 36 | -------------------------------------------------------------------------------- /scripts/lib/k8s.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # check_ds_rollout watches the status of the latest rollout until it's done or 4 | # until the timeout. Namespace and timeout are optional parameters 5 | check_ds_rollout() { 6 | local __ds_name=${1:-} 7 | local __namespace=${2:-} 8 | local __timeout=${3:-"2m"} 9 | local __args="" 10 | if [ -n "$__namespace" ]; then 11 | __args="$__args-n $__namespace" 12 | fi 13 | kubectl rollout status ds/"$__ds_name" $__args --timeout=$__timeout 14 | } -------------------------------------------------------------------------------- /scripts/lib/set_kubeconfig.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script sets the KUBECONFIG environment variable based on KUBE_CONFIG_PATH if not already set. 4 | 5 | if [ -n "${KUBE_CONFIG_PATH:-}" ] && [ -z "$KUBECONFIG" ]; then 6 | export KUBECONFIG=$KUBE_CONFIG_PATH 7 | fi 8 | -------------------------------------------------------------------------------- /scripts/protoc-gen-go: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exec go run github.com/golang/protobuf/protoc-gen-go "$@" 4 | -------------------------------------------------------------------------------- /scripts/run-canary-test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # The script runs amazon-vpc-cni Canary tests on the default 4 | # addon version and then runs smoke test on the latest addon version. 5 | 6 | set -e 7 | 8 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 9 | GINKGO_TEST_BUILD="$SCRIPT_DIR/../test/build" 10 | # TEST_IMAGE_REGISTRY is the registry in test-infra-* accounts where e2e test images are stored 11 | TEST_IMAGE_REGISTRY=${TEST_IMAGE_REGISTRY:-"617930562442.dkr.ecr.us-west-2.amazonaws.com"} 12 | ADC_REGIONS="us-iso-east-1 us-isob-east-1 us-iso-west-1" 13 | 14 | source "$SCRIPT_DIR"/lib/set_kubeconfig.sh 15 | source "$SCRIPT_DIR"/lib/add-on.sh 16 | source "$SCRIPT_DIR"/lib/cluster.sh 17 | source "$SCRIPT_DIR"/lib/canary.sh 18 | 19 | function run_ginkgo_test() { 20 | local focus=$1 21 | echo "Running ginkgo tests with focus: $focus" 22 | (CGO_ENABLED=0 ginkgo $EXTRA_GINKGO_FLAGS --no-color --focus="$focus" -v --timeout 30m --fail-on-pending $GINKGO_TEST_BUILD/cni.test -- --cluster-kubeconfig="$KUBECONFIG" --cluster-name="$CLUSTER_NAME" --aws-region="$REGION" --aws-vpc-id="$VPC_ID" --ng-name-label-key="kubernetes.io/os" --ng-name-label-val="linux" --test-image-registry=$TEST_IMAGE_REGISTRY) 23 | (CGO_ENABLED=0 ginkgo $EXTRA_GINKGO_FLAGS --no-color --focus="$focus" -v --timeout 30m --fail-on-pending $GINKGO_TEST_BUILD/ipamd.test -- --cluster-kubeconfig="$KUBECONFIG" --cluster-name="$CLUSTER_NAME" --aws-region="$REGION" --aws-vpc-id="$VPC_ID" --ng-name-label-key="kubernetes.io/os" --ng-name-label-val="linux" --test-image-registry=$TEST_IMAGE_REGISTRY) 24 | } 25 | 26 | load_cluster_details 27 | load_addon_details 28 | 29 | # Run more comprehensive test on the default addon version. CANARY focused tests 30 | # cover basic functionlity plus test that could detect issues with dependencies 31 | # early on. 32 | echo "Running Canary tests on the default addon version" 33 | install_add_on "$DEFAULT_ADDON_VERSION" 34 | run_ginkgo_test "CANARY" 35 | 36 | # Run smoke test on the latest addon version. Smoke tests consist of a subset of tests 37 | # from Canary suite. 38 | # skip the latest addon version for ADC regions 39 | if [[ $ADC_REGIONS == *"$REGION"* ]]; then 40 | echo "Skipping Smoke tests on the latest addon version" 41 | else 42 | echo "Running Smoke tests on the latest addon version" 43 | install_add_on "$LATEST_ADDON_VERSION" 44 | run_ginkgo_test "SMOKE" 45 | fi 46 | 47 | echo "all tests ran successfully in $(($SECONDS / 60)) minutes and $(($SECONDS % 60)) seconds" 48 | -------------------------------------------------------------------------------- /scripts/run-ginkgo-integration-suite.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # This script can be used to run any ginkgo integration suite using SUITE_NAME environment variable. 4 | # Prerequisite: cluster with at least three Linux nodes must already exist. 5 | # It is up to the caller to ensure that tests are valid to run against cluster, i.e. IPv6 tests require IPv6 cluster. 6 | # Set appropriate optional args for running test suite 7 | 8 | set -e 9 | 10 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 11 | GINKGO_TEST_BUILD="$SCRIPT_DIR/../test/build" 12 | : "${SKIP_MAKE_TEST_BINARIES:=}" 13 | 14 | source "$SCRIPT_DIR"/lib/set_kubeconfig.sh 15 | source "$SCRIPT_DIR"/lib/cluster.sh 16 | source "$SCRIPT_DIR"/lib/canary.sh 17 | 18 | function load_test_parameters(){ 19 | 20 | EXTRA_OPTIONS="" 21 | if [[ ! -z $INITIAL_ADDON_VERSION ]]; then 22 | EXTRA_OPTIONS+=" --initial-addon-version $INITIAL_ADDON_VERSION" 23 | fi 24 | 25 | if [[ ! -z $TARGET_ADDON_VERSION ]]; then 26 | EXTRA_OPTIONS+=" --target-addon-version $TARGET_ADDON_VERSION" 27 | fi 28 | 29 | if [[ ! -z $INITIAL_MANIFEST_FILE ]]; then 30 | EXTRA_OPTIONS+=" --initial-manifest-file $INITIAL_MANIFEST_FILE" 31 | fi 32 | 33 | if [[ ! -z $TARGET_MANIFEST_FILE ]]; then 34 | EXTRA_OPTIONS+=" --target-manifest-file $TARGET_MANIFEST_FILE" 35 | fi 36 | 37 | } 38 | 39 | function run_ginkgo_test() { 40 | (CGO_ENABLED=0 ginkgo $EXTRA_GINKGO_FLAGS -v --timeout 60m --no-color --fail-on-pending $GINKGO_TEST_BUILD/$SUITE_NAME.test -- \ 41 | --cluster-kubeconfig="$KUBECONFIG" \ 42 | --cluster-name="$CLUSTER_NAME" \ 43 | --aws-region="$REGION" \ 44 | --aws-vpc-id="$VPC_ID" \ 45 | --ng-name-label-key="kubernetes.io/os" \ 46 | --ng-name-label-val="linux" \ 47 | $ENDPOINT_OPTION $EXTRA_OPTIONS 48 | ) 49 | } 50 | 51 | load_cluster_details 52 | 53 | load_test_parameters 54 | 55 | echo "Running $SUITE_NAME integration tests" 56 | 57 | run_ginkgo_test 58 | 59 | echo "all tests ran successfully in $(($SECONDS / 60)) minutes and $(($SECONDS % 60)) seconds" 60 | -------------------------------------------------------------------------------- /scripts/run-ipv6-canary-test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # The script runs amazon-vpc-cni IPv6 canary tests 4 | 5 | set -e 6 | 7 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 8 | GINKGO_TEST_BUILD="$SCRIPT_DIR/../test/build" 9 | 10 | source "$SCRIPT_DIR"/lib/set_kubeconfig.sh 11 | source "$SCRIPT_DIR"/lib/add-on.sh 12 | source "$SCRIPT_DIR"/lib/cluster.sh 13 | source "$SCRIPT_DIR"/lib/canary.sh 14 | 15 | function run_ginkgo_test() { 16 | local focus=$1 17 | echo "Running ginkgo tests with focus: $focus" 18 | (CGO_ENABLED=0 ginkgo $EXTRA_GINKGO_FLAGS --focus="$focus" -v --timeout 15m --no-color --fail-on-pending $GINKGO_TEST_BUILD/ipv6.test -- --cluster-kubeconfig="$KUBECONFIG" --cluster-name="$CLUSTER_NAME" --aws-region="$REGION" --aws-vpc-id="$VPC_ID" --ng-name-label-key="kubernetes.io/os" --ng-name-label-val="linux") 19 | } 20 | 21 | load_cluster_details 22 | load_addon_details 23 | 24 | echo "Running IPv6 Canary tests on the latest addon version" 25 | 26 | install_add_on "$LATEST_ADDON_VERSION" 27 | run_ginkgo_test "CANARY" 28 | 29 | echo "all tests ran successfully in $(($SECONDS / 60)) minutes and $(($SECONDS % 60)) seconds" 30 | -------------------------------------------------------------------------------- /scripts/run-ipv6-integration-tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # The script runs the full IPv6 integration test suite 4 | 5 | set -e 6 | 7 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 8 | GINKGO_TEST_BUILD="$SCRIPT_DIR/../test/build" 9 | 10 | # TEST_IMAGE_REGISTRY is the registry in test-infra-* accounts where e2e test images are stored 11 | TEST_IMAGE_REGISTRY=${TEST_IMAGE_REGISTRY:-"617930562442.dkr.ecr.us-west-2.amazonaws.com"} 12 | 13 | source "$SCRIPT_DIR"/lib/set_kubeconfig.sh 14 | source "$SCRIPT_DIR"/lib/add-on.sh 15 | source "$SCRIPT_DIR"/lib/cluster.sh 16 | source "$SCRIPT_DIR"/lib/canary.sh 17 | 18 | function run_ginkgo_test() { 19 | (CGO_ENABLED=0 ginkgo $EXTRA_GINKGO_FLAGS -v --timeout 30m --no-color --fail-on-pending $GINKGO_TEST_BUILD/ipv6.test -- --cluster-kubeconfig="$KUBECONFIG" --cluster-name="$CLUSTER_NAME" --aws-region="$REGION" --aws-vpc-id="$VPC_ID" --ng-name-label-key="kubernetes.io/os" --ng-name-label-val="linux" --test-image-registry=$TEST_IMAGE_REGISTRY) 20 | } 21 | 22 | load_cluster_details 23 | load_addon_details 24 | 25 | echo "Running IPv6 integration tests against the latest addon version" 26 | 27 | install_add_on "$LATEST_ADDON_VERSION" 28 | run_ginkgo_test 29 | 30 | echo "all tests ran successfully in $(($SECONDS / 60)) minutes and $(($SECONDS % 60)) seconds" 31 | -------------------------------------------------------------------------------- /scripts/run-multus-tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # The script runs multus tests on the lastest version with latest AWS-VPC-CNI addon version 4 | 5 | set -e 6 | 7 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 8 | INTEGRATION_TEST_DIR="$SCRIPT_DIR/../test/integration" 9 | 10 | source "$SCRIPT_DIR"/lib/set_kubeconfig.sh 11 | source "$SCRIPT_DIR"/lib/common.sh 12 | source "$SCRIPT_DIR"/lib/cluster.sh 13 | source "$SCRIPT_DIR"/lib/canary.sh 14 | 15 | function run_ginkgo_test() { 16 | local focus=$1 17 | (cd "$INTEGRATION_TEST_DIR/multus" && CGO_ENABLED=0 ginkgo --focus="$focus" -v --timeout 20m --fail-on-pending -- --cluster-kubeconfig="$KUBECONFIG" --cluster-name="$CLUSTER_NAME" --aws-region="$REGION" --aws-vpc-id="$VPC_ID" --ng-name-label-key="kubernetes.io/os" --ng-name-label-val="linux") 18 | } 19 | 20 | check_is_installed kubectl 21 | check_is_installed ginkgo 22 | 23 | load_cluster_details 24 | 25 | LATEST_TAG=${1:-v4.1.4-eksbuild.1_thick} 26 | echo "Installing latest multus manifest with tag: ${LATEST_TAG}" 27 | 28 | kubectl apply -f https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/master/config/multus/${LATEST_TAG}/aws-k8s-multus.yaml 29 | 30 | echo "Running multus ginkgo tests" 31 | run_ginkgo_test 32 | 33 | echo "all tests ran successfully in $(($SECONDS / 60)) minutes and $(($SECONDS % 60)) seconds" 34 | -------------------------------------------------------------------------------- /scripts/run-release-tests.sh: -------------------------------------------------------------------------------- 1 | export RUN_BOTTLEROCKET_TEST=true 2 | chmod +x ./scripts/run-integration-tests.sh 3 | echo "Running bottlerocket test" 4 | ./scripts/run-integration-tests.sh 5 | unset RUN_BOTTLEROCKET_TEST 6 | 7 | export RUN_WARM_IP_TEST=true 8 | echo "Running warm ip test" 9 | ./scripts/run-integration-tests.sh 10 | unset RUN_WARM_IP_TEST 11 | 12 | export RUN_WARM_ENI_TEST=true 13 | echo "Running warm eni test" 14 | ./scripts/run-integration-tests.sh 15 | unset RUN_WARM_ENI_TEST 16 | 17 | export RUN_CONFORMANCE=false 18 | 19 | export RUN_KOPS_TEST=true 20 | echo "Running KOPS test" 21 | ./scripts/run-integration-tests.sh 22 | unset RUN_KOPS_TEST 23 | -------------------------------------------------------------------------------- /scripts/run-soak-test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # The script runs amazon-vpc-cni static canary tests 4 | # The tests in this suite are designed to exercise AZ failure scenarios. 5 | 6 | set -e 7 | 8 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 9 | GINKGO_TEST_BUILD="$SCRIPT_DIR/../test/build" 10 | # TEST_IMAGE_REGISTRY is the registry in test-infra-* accounts where e2e test images are stored 11 | TEST_IMAGE_REGISTRY=${TEST_IMAGE_REGISTRY:-"617930562442.dkr.ecr.us-west-2.amazonaws.com"} 12 | 13 | # If $ENDPOINT is set, as in it is for beta clusters then $ENDPOINT_OPTION, 14 | # defined in lib/cluster.sh will add --eks-endpoint=$ENDPOINT to the ginkgo 15 | # test command 16 | 17 | source "$SCRIPT_DIR"/lib/set_kubeconfig.sh 18 | source "$SCRIPT_DIR"/lib/cluster.sh 19 | source "$SCRIPT_DIR"/lib/canary.sh 20 | 21 | function run_ginkgo_test() { 22 | local focus=$1 23 | echo "Running ginkgo tests with focus: $focus" 24 | 25 | (CGO_ENABLED=0 ginkgo $EXTRA_GINKGO_FLAGS --no-color --focus="$focus" -v --timeout 3h --fail-on-pending $GINKGO_TEST_BUILD/cni.test -- \ 26 | --cluster-kubeconfig="$KUBECONFIG" \ 27 | --cluster-name="$CLUSTER_NAME" \ 28 | --aws-region="$REGION" \ 29 | --aws-vpc-id="$VPC_ID" \ 30 | --ng-name-label-key="kubernetes.io/os" \ 31 | --ng-name-label-val="linux" \ 32 | --test-image-registry=$TEST_IMAGE_REGISTRY \ 33 | --publish-cw-metrics=true \ 34 | $ENDPOINT_OPTION) 35 | } 36 | 37 | load_cluster_details 38 | 39 | run_ginkgo_test "SOAK_TEST" 40 | 41 | echo "all tests ran successfully in $(($SECONDS / 60)) minutes and $(($SECONDS % 60)) seconds" 42 | -------------------------------------------------------------------------------- /scripts/run-static-canary.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # The script runs amazon-vpc-cni static canary tests 4 | # The tests in this suite are designed to exercise AZ failure scenarios. 5 | 6 | set -e 7 | 8 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 9 | GINKGO_TEST_BUILD="$SCRIPT_DIR/../test/build" 10 | # TEST_IMAGE_REGISTRY is the registry in test-infra-* accounts where e2e test images are stored 11 | TEST_IMAGE_REGISTRY=${TEST_IMAGE_REGISTRY:-"617930562442.dkr.ecr.us-west-2.amazonaws.com"} 12 | 13 | # If $ENDPOINT is set, as in it is for beta clusters then $ENDPOINT_OPTION, 14 | # defined in lib/cluster.sh will add --eks-endpoint=$ENDPOINT to the ginkgo 15 | # test command 16 | 17 | source "$SCRIPT_DIR"/lib/set_kubeconfig.sh 18 | source "$SCRIPT_DIR"/lib/cluster.sh 19 | source "$SCRIPT_DIR"/lib/canary.sh 20 | 21 | function run_ginkgo_test() { 22 | local focus=$1 23 | echo "Running ginkgo tests with focus: $focus" 24 | 25 | (CGO_ENABLED=0 ginkgo $EXTRA_GINKGO_FLAGS --no-color --focus="$focus" -v --timeout 10m --fail-on-pending $GINKGO_TEST_BUILD/az-traffic.test -- \ 26 | --cluster-kubeconfig="$KUBECONFIG" \ 27 | --cluster-name="$CLUSTER_NAME" \ 28 | --aws-region="$REGION" \ 29 | --aws-vpc-id="$VPC_ID" \ 30 | --ng-name-label-key="kubernetes.io/os" \ 31 | --ng-name-label-val="linux" \ 32 | --test-image-registry=$TEST_IMAGE_REGISTRY \ 33 | --publish-cw-metrics=true \ 34 | $ENDPOINT_OPTION) 35 | } 36 | 37 | load_cluster_details 38 | 39 | run_ginkgo_test "STATIC_CANARY" 40 | 41 | echo "all tests ran successfully in $(($SECONDS / 60)) minutes and $(($SECONDS % 60)) seconds" 42 | -------------------------------------------------------------------------------- /scripts/test/config/bottlerocket.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: eksctl.io/v1alpha5 3 | kind: ClusterConfig 4 | 5 | metadata: 6 | name: CLUSTER_NAME_PLACEHOLDER 7 | region: us-west-2 8 | 9 | nodeGroups: 10 | - name: ng-bottlerocket 11 | instanceType: m5.large 12 | desiredCapacity: 4 13 | amiFamily: Bottlerocket 14 | iam: 15 | attachPolicyARNs: 16 | - arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy 17 | - arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy 18 | - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly 19 | - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore 20 | bottlerocket: 21 | settings: 22 | motd: "Hello from eksctl!" 23 | -------------------------------------------------------------------------------- /scripts/test/config/perf-cluster.yml: -------------------------------------------------------------------------------- 1 | # A cluster with two managed nodegroups. 2 | --- 3 | apiVersion: eksctl.io/v1alpha5 4 | kind: ClusterConfig 5 | iam: 6 | withOIDC: true 7 | 8 | metadata: 9 | name: CLUSTER_NAME_PLACEHOLDER 10 | region: us-west-2 11 | 12 | managedNodeGroups: 13 | - name: cni-test-single-node-mng 14 | ami: AMI_ID_PLACEHOLDER 15 | amiFamily: AmazonLinux2 16 | instanceType: m5.16xlarge 17 | desiredCapacity: 1 18 | minSize: 1 19 | maxSize: 1 20 | volumeSize: 100 21 | volumeName: /dev/xvda 22 | iam: 23 | withAddonPolicies: 24 | autoScaler: true 25 | overrideBootstrapCommand: | 26 | #!/bin/bash 27 | /etc/eks/bootstrap.sh CLUSTER_NAME_PLACEHOLDER --kubelet-extra-args '--max-pods=740' 28 | 29 | - name: cni-test-multi-node-mng 30 | instanceType: m5.xlarge 31 | desiredCapacity: 99 32 | minSize: 1 33 | maxSize: 100 34 | iam: 35 | withAddonPolicies: 36 | autoScaler: true 37 | volumeSize: 100 38 | volumeName: /dev/xvda 39 | -------------------------------------------------------------------------------- /scripts/test/config/test-cluster.yaml: -------------------------------------------------------------------------------- 1 | # A cluster with two managed nodegroups for test 2 | --- 3 | apiVersion: eksctl.io/v1alpha5 4 | kind: ClusterConfig 5 | 6 | metadata: 7 | name: CLUSTER_NAME_PLACEHOLDER 8 | region: us-west-2 9 | version: "K8S_VERSION_PLACEHOLDER" 10 | 11 | iam: 12 | serviceRoleARN: "ROLE_ARN_PLACEHOLDER" 13 | managedNodeGroups: 14 | - name: cni-test-arm64-mng 15 | instanceType: c6g.xlarge 16 | desiredCapacity: 3 17 | minSize: 3 18 | maxSize: 3 19 | volumeSize: 40 20 | releaseVersion: "" 21 | tags: 22 | group: amazon-vpc-cni-k8s-arm64 23 | 24 | - name: cni-test-x86-mng 25 | instanceType: c5.xlarge 26 | desiredCapacity: 3 27 | minSize: 3 28 | maxSize: 3 29 | volumeSize: 40 30 | releaseVersion: "" 31 | tags: 32 | group: amazon-vpc-cni-k8s-x86 33 | availabilityZones: 34 | - us-west-2a 35 | - us-west-2b 36 | - us-west-2c 37 | - us-west-2d -------------------------------------------------------------------------------- /scripts/test/run-integration-tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eo pipefail 4 | 5 | pushd ./test/integration 6 | 7 | echo "Running integration test with the following configuration: 8 | KUBECONFIG: $KUBECONFIG 9 | CLUSTER_NAME: $CLUSTER_NAME 10 | AWS_REGION: $AWS_REGION" 11 | 12 | 13 | if [[ -n "${ENDPOINT}" ]]; then 14 | ENDPOINT_FLAG="--endpoint $ENDPOINT" 15 | fi 16 | 17 | while getopts "f:" arg; do 18 | case $arg in 19 | f) FOCUS=$OPTARG; 20 | echo "FOCUS: $FOCUS"; 21 | esac 22 | done 23 | 24 | CLUSTER_INFO=$(aws eks describe-cluster --name $CLUSTER_NAME --region $AWS_REGION $ENDPOINT_FLAG) 25 | 26 | VPC_ID=$(echo $CLUSTER_INFO | jq -r '.cluster.resourcesVpcConfig.vpcId') 27 | SERVICE_ROLE_ARN=$(echo $CLUSTER_INFO | jq -r '.cluster.roleArn') 28 | ROLE_NAME=${SERVICE_ROLE_ARN##*/} 29 | TEST_FAILED=false 30 | 31 | START=$SECONDS 32 | 33 | for dir in */ 34 | do 35 | 36 | cd "${dir%*/}" 37 | if [ -n "$FOCUS" ]; then 38 | ( ginkgo --focus="$FOCUS" -v -r -- --cluster-kubeconfig=$KUBECONFIG --cluster-name=$CLUSTER_NAME --aws-region=$AWS_REGION --aws-vpc-id=$VPC_ID ) || TEST_FAILED=true 39 | else 40 | ( ginkgo -v -r -- --cluster-kubeconfig=$KUBECONFIG --cluster-name=$CLUSTER_NAME --aws-region=$AWS_REGION --aws-vpc-id=$VPC_ID ) || TEST_FAILED=true 41 | fi 42 | cd .. 43 | 44 | done 45 | 46 | popd 47 | 48 | # If any of the test failed, exit with non zero exit code 49 | if [ $TEST_FAILED = true ]; then 50 | exit 1 51 | fi 52 | -------------------------------------------------------------------------------- /scripts/update-cni-images.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # script to set the image on aws-node daemonset for running tests 4 | 5 | # Usage: Set test images as ENV variables $AMAZON_K8S_CNI & $AMAZON_K8S_CNI_INIT 6 | # Run script to update aws-node daemonset images 7 | 8 | set -e 9 | 10 | SCRIPTS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 11 | source "$SCRIPTS_DIR/lib/k8s.sh" 12 | : "${REGION=us-west-2}" 13 | 14 | # Select CNI manifest based on regions 15 | if [[ $REGION == "cn-north-1" || $REGION == "cn-northwest-1" ]]; then 16 | AWS_K8S_CNI_MANIFEST="$SCRIPTS_DIR/../config/master/aws-k8s-cni-cn.yaml" 17 | elif [[ $REGION == "us-gov-east-1" ]]; then 18 | AWS_K8S_CNI_MANIFEST="$SCRIPTS_DIR/../config/master/aws-k8s-cni-us-gov-east-1.yaml" 19 | elif [[ $REGION == "us-gov-west-1" ]]; then 20 | AWS_K8S_CNI_MANIFEST="$SCRIPTS_DIR/../config/master/aws-k8s-cni-us-gov-west-1.yaml" 21 | else 22 | AWS_K8S_CNI_MANIFEST="$SCRIPTS_DIR/../config/master/aws-k8s-cni.yaml" 23 | fi 24 | 25 | MANIFEST_IMG_VERSION=`grep "image:" $AWS_K8S_CNI_MANIFEST | cut -d ":" -f3 | cut -d "\"" -f1 | head -1` 26 | IMAGE_REPOSITORY=`grep "image:" $AWS_K8S_CNI_MANIFEST | cut -d ":" -f2 | cut -d "/" -f1 | head -1` 27 | 28 | # Replace the images in aws-k8s-cni.yaml with the tester images when environment variables are set 29 | if [[ -z $AMAZON_K8S_CNI ]]; then 30 | echo "Using latest CNI image from aws-k8s-cni manifest" 31 | else 32 | echo "Replacing CNI image in aws-k8s-cni manifest with $AMAZON_K8S_CNI" 33 | sed -i'.bak' "s,$IMAGE_REPOSITORY/amazon-k8s-cni:$MANIFEST_IMG_VERSION, $AMAZON_K8S_CNI," "$AWS_K8S_CNI_MANIFEST" 34 | fi 35 | if [[ -z $AMAZON_K8S_CNI_INIT ]]; then 36 | echo "Using latest CNI init image from aws-k8s-cni manifest" 37 | else 38 | echo "Replacing CNI init image in aws-k8s-cni manifest with $AMAZON_K8S_CNI_INIT" 39 | sed -i'.bak' "s,$IMAGE_REPOSITORY/amazon-k8s-cni-init:$MANIFEST_IMG_VERSION, $AMAZON_K8S_CNI_INIT," "$AWS_K8S_CNI_MANIFEST" 40 | fi 41 | 42 | echo "Applying $AWS_K8S_CNI_MANIFEST manifest" 43 | kubectl apply -f $AWS_K8S_CNI_MANIFEST 44 | 45 | check_ds_rollout "aws-node" "kube-system" "10m" 46 | -------------------------------------------------------------------------------- /test/README.md: -------------------------------------------------------------------------------- 1 | ## amazon-vpc-cni-k8s Test Framework 2 | The test framework consists of integration tests using the Ginkgo framework invoked manually and using collection of bash scripts using GitHub Workflow and Prow(not publicly available). 3 | 4 | ### Types of Tests 5 | 6 | #### Pull Request Tests 7 | Runs on each Pull Request, verifies the new code changes don't introduce any regression. Given the entire test suite may span for long duration, run only the integration tests. 8 | 9 | #### Nightly Integration Tests 10 | Runs the entire test suite every night using the current GitHub build to catch regression. 11 | 12 | #### Canary Tests 13 | Canary tests run frequently, multiple times in a day on live production environment. Given all integration tests run spans for hours we can only run a limited set of tests of most important features along with tests that have dependencies like Load Balancer Service Creation. These test runs are not publicly accessible at this moment. 14 | 15 | Ginkgo Focus: [CANARY] 16 | 17 | ### Smoke Tests 18 | Smoke test provide fail early mechanism by failing the test if basic functionality doesn't work. This can be used as a pre-requisite for the running the much longer Integration tests. 19 | 20 | Ginkgo Focus: [SMOKE] 21 | 22 | # KOPS 23 | * set RUN_KOPS_TEST=true 24 | * WARNING: will occassionally fail/flake tests, try re-running test a couple times to ensure there is a 25 | 26 | # Bottlerocket 27 | * set RUN_BOTTLEROCKET_TEST=true 28 | 29 | ## How to Manually delete k8s tester Resources (order of deletion) 30 | Cloudformation - (all except cluster, vpc) 31 | EC2 - load balancers, key pair 32 | VPC - Nat gateways, Elastic IPs(after a minute), internet gateway 33 | Cloudformation - cluster 34 | EC2 - network interfaces, security groups 35 | VPC - subnet, route tables 36 | Cloudformation - cluster, vpc(after cluster deletes) 37 | S3 - delete bucket 38 | 39 | #### Work In Progress 40 | - Run Upstream Conformance tests as part of Nightly Integration tests. 41 | - Run all integration tests as part of Nightly Integration tests. 42 | - Run all integration tests on each Pull Request. 43 | -------------------------------------------------------------------------------- /test/_cmd/packet-verifier/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG builder_image=amazonlinux:2 2 | 3 | FROM $builder_image as builder 4 | ENV GO111MODULE=on 5 | ENV GOPROXY=direct 6 | ENV GOOS=linux 7 | ENV GOARCH=amd64 8 | COPY . / 9 | WORKDIR / 10 | RUN yum install -y git golang libpcap-devel 11 | RUN go build -o packet-verifier packet-verifier.go 12 | 13 | FROM amazonlinux:2 14 | RUN yum install -y libpcap-devel 15 | COPY --from=builder packet-verifier /usr/bin/packet-verifier 16 | -------------------------------------------------------------------------------- /test/_cmd/packet-verifier/example/packetverifier_pod.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: packetverifier 5 | annotations: 6 | spec: 7 | hostNetwork: true 8 | restartPolicy: Never 9 | containers: 10 | - name: packetverifier 11 | image: #IMAGE_TAG 12 | command: 13 | - /usr/bin/packet-verifier --ip-to-monitor 10.0.0.0 --vlanid-to-monitor 2 14 | -------------------------------------------------------------------------------- /test/agent/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG golang_image 2 | 3 | FROM $golang_image as builder 4 | 5 | WORKDIR /workspace 6 | ENV GOPROXY direct 7 | 8 | COPY go.mod go.mod 9 | COPY go.sum go.sum 10 | 11 | RUN go mod download 12 | 13 | COPY cmd cmd 14 | COPY pkg pkg 15 | 16 | # Package all testing binaries into one docker file 17 | # which can be used for different test scenarios 18 | 19 | RUN CGO_ENABLED=0 GOOS=linux GO111MODULE=on go build \ 20 | -a -o traffic-server cmd/traffic-server/main.go 21 | 22 | RUN CGO_ENABLED=0 GOOS=linux GO111MODULE=on go build \ 23 | -a -o traffic-client cmd/traffic-client/main.go 24 | 25 | RUN CGO_ENABLED=0 GOOS=linux GO111MODULE=on go build \ 26 | -a -o networking cmd/networking/main.go 27 | 28 | RUN CGO_ENABLED=0 GOOS=linux GO111MODULE=on go build \ 29 | -a -o metric-server cmd/metric-server/main.go 30 | 31 | RUN CGO_ENABLED=0 GOOS=linux GO111MODULE=on go build \ 32 | -a -o snat-utils cmd/snat-utils/main.go 33 | 34 | FROM public.ecr.aws/eks-distro-build-tooling/eks-distro-minimal-base-iptables:latest.2 35 | 36 | WORKDIR / 37 | COPY --from=builder /workspace/ . 38 | -------------------------------------------------------------------------------- /test/agent/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"). You 4 | # may not use this file except in compliance with the License. A copy of 5 | # the License is located at 6 | # 7 | # http://aws.amazon.com/apache2.0/ 8 | # 9 | # or in the "license" file accompanying this file. This file is 10 | # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 11 | # ANY KIND, either express or implied. See the License for the specific 12 | # language governing permissions and limitations under the License. 13 | 14 | VERSION ?= $(shell git rev-parse --short HEAD || echo "unknown") 15 | MULTI_PLATFORM_BUILD_TARGETS = linux/amd64,linux/arm64 16 | IMAGE_NAME =aws-vpc-cni-test-helper 17 | PUBLIC_REPO_IMAGE=public.ecr.aws/$(REGISTRY_ID)/${IMAGE_NAME}:$(VERSION) 18 | PRIVATE_REPO_IMAGE=$(AWS_ACCOUNT).dkr.ecr.$(AWS_REGION).amazonaws.com/$(IMAGE_NAME):$(VERSION) 19 | 20 | GOLANG_VERSION ?= $(shell cat ../../.go-version) 21 | GOLANG_IMAGE ?= public.ecr.aws/eks-distro-build-tooling/golang:$(GOLANG_VERSION)-gcc-al2 22 | 23 | fmt: 24 | go fmt ./... 25 | 26 | # Run go vet against code 27 | vet: 28 | go vet ./... 29 | 30 | publish-private-image: check-env 31 | aws ecr get-login-password --region $(AWS_REGION) | docker login --username AWS --password-stdin $(AWS_ACCOUNT).dkr.ecr.$(AWS_REGION).amazonaws.com 32 | docker buildx build --platform "$(MULTI_PLATFORM_BUILD_TARGETS)" -t ${PRIVATE_REPO_IMAGE} --build-arg golang_image="$(GOLANG_IMAGE)" --push . 33 | 34 | #Ensure to authenticate to public ECR repo. 35 | publish-public-image: check-env-public 36 | docker buildx build --platform "$(MULTI_PLATFORM_BUILD_TARGETS)" -t ${PUBLIC_REPO_IMAGE} --build-arg golang_image="$(GOLANG_IMAGE)" --push . 37 | 38 | check-env: 39 | @:$(call check_var, AWS_ACCOUNT, AWS account ID for publishing docker images) 40 | @:$(call check_var, AWS_REGION, AWS region for publishing docker images) 41 | 42 | check-env-public: 43 | @:$(call check_var, REGISTRY_ID, Registry ID for publishing docker images to public ECR Repo) 44 | 45 | check_var = \ 46 | $(strip $(foreach 1,$1, \ 47 | $(call __check_var,$1,$(strip $(value 2))))) 48 | __check_var = \ 49 | $(if $(value $1),, \ 50 | $(error Undefined variable $1$(if $2, ($2)))) 51 | -------------------------------------------------------------------------------- /test/agent/cmd/metric-server/main.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package main 15 | 16 | import ( 17 | "encoding/json" 18 | "log" 19 | "net/http" 20 | 21 | "github.com/aws/amazon-vpc-cni-k8s/test/agent/pkg/input" 22 | ) 23 | 24 | var connectivityMetric []input.TestStatus 25 | 26 | // metric server stores metrics from test client and returns the aggregated metrics to the 27 | // automation test 28 | func main() { 29 | http.HandleFunc("/submit/metric/connectivity", submitConnectivityMetric) 30 | http.HandleFunc("/get/metric/connectivity", getConnectivityMetric) 31 | log.Fatal(http.ListenAndServe(":8080", nil)) 32 | } 33 | 34 | // adds the metric to list of metrics 35 | func submitConnectivityMetric(_ http.ResponseWriter, r *http.Request) { 36 | decoder := json.NewDecoder(r.Body) 37 | 38 | var status input.TestStatus 39 | err := decoder.Decode(&status) 40 | 41 | if err != nil { 42 | log.Printf("failed to decode the request body: %v", err) 43 | return 44 | } 45 | 46 | log.Printf("received metric %+v", status) 47 | connectivityMetric = append(connectivityMetric, status) 48 | } 49 | 50 | // returns the list of metrics 51 | func getConnectivityMetric(w http.ResponseWriter, r *http.Request) { 52 | metricByte, err := json.Marshal(connectivityMetric) 53 | if err != nil { 54 | log.Printf("failed to marshall: %v", err) 55 | return 56 | } 57 | w.Header().Set("Content-Type", "application/json") 58 | w.Write(metricByte) 59 | } 60 | -------------------------------------------------------------------------------- /test/agent/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aws/amazon-vpc-cni-k8s/test/agent 2 | 3 | go 1.24.1 4 | 5 | require ( 6 | github.com/coreos/go-iptables v0.8.0 7 | github.com/vishvananda/netlink v1.3.1 8 | golang.org/x/sys v0.32.0 9 | ) 10 | 11 | require github.com/vishvananda/netns v0.0.5 // indirect 12 | -------------------------------------------------------------------------------- /test/agent/go.sum: -------------------------------------------------------------------------------- 1 | github.com/coreos/go-iptables v0.8.0 h1:MPc2P89IhuVpLI7ETL/2tx3XZ61VeICZjYqDEgNsPRc= 2 | github.com/coreos/go-iptables v0.8.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= 3 | github.com/vishvananda/netlink v1.3.1 h1:3AEMt62VKqz90r0tmNhog0r/PpWKmrEShJU0wJW6bV0= 4 | github.com/vishvananda/netlink v1.3.1/go.mod h1:ARtKouGSTGchR8aMwmkzC0qiNPrrWO5JS/XMVl45+b4= 5 | github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY= 6 | github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= 7 | golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 8 | golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 9 | golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= 10 | golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 11 | -------------------------------------------------------------------------------- /test/agent/pkg/input/input.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package input 15 | 16 | import "encoding/json" 17 | 18 | type TestStatus struct { 19 | SuccessCount int 20 | FailureCount int 21 | SourcePod string 22 | Failures []Failure 23 | } 24 | 25 | type Failure struct { 26 | DestinationIP string 27 | FailureReason string 28 | } 29 | 30 | type PodNetworkingValidationInput struct { 31 | // CIDR Range associated with the VPC 32 | VPCCidrRange []string 33 | // Prefix for the veth pair on host network ns 34 | VethPrefix string 35 | // List of pod to validate the networking 36 | PodList []Pod 37 | // Should Validate MTU value, by default it will false 38 | ValidateMTU bool 39 | // Expected MTU value 40 | MTU int 41 | // Cluster's IP Family mode 42 | IPFamily string 43 | } 44 | 45 | type Pod struct { 46 | // Name of the pod 47 | PodName string 48 | // Namespace of the pod, used to generate the Link 49 | PodNamespace string 50 | // IPv4 Address of the pod 51 | PodIPv4Address string 52 | // IPv6 Address of the pod 53 | PodIPv6Address string 54 | // Set to true when the Pod is scheduled on IP 55 | // from the Secondary ENI 56 | IsIPFromSecondaryENI bool 57 | } 58 | 59 | func (ip PodNetworkingValidationInput) Serialize() (string, error) { 60 | inputBytes, err := json.Marshal(ip) 61 | if err != nil { 62 | return "", err 63 | } 64 | return string(inputBytes), nil 65 | } 66 | -------------------------------------------------------------------------------- /test/framework/controller/constant.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package controller 15 | 16 | const ( 17 | CNIMetricsHelperChartDir = "/test/helm/charts/cni-metrics-helper" 18 | CNIMetricsHelperReleaseName = "cni-metrics-helper" 19 | CNIMetricHelperNamespace = "kube-system" 20 | TigeraOperatorNamespace = "tigera-operator" 21 | TigeraOperatorReleaseName = "calico" 22 | TigeraOperatorHelmRepo = "https://docs.tigera.io/calico/charts" 23 | TigeraOperatorHelmCharts = "projectcalico/tigera-operator" 24 | ) 25 | -------------------------------------------------------------------------------- /test/framework/controller/installation_manager.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package controller 15 | 16 | import ( 17 | "github.com/aws/amazon-vpc-cni-k8s/test/framework/helm" 18 | "github.com/aws/amazon-vpc-cni-k8s/test/framework/utils" 19 | ) 20 | 21 | type InstallationManager interface { 22 | InstallCNIMetricsHelper(image string, tag string, clusterId string) error 23 | UnInstallCNIMetricsHelper() error 24 | InstallTigeraOperator(version string) error 25 | UninstallTigeraOperator() error 26 | } 27 | 28 | func NewDefaultInstallationManager(manager helm.ReleaseManager) InstallationManager { 29 | return &defaultInstallationManager{releaseManager: manager} 30 | } 31 | 32 | type defaultInstallationManager struct { 33 | releaseManager helm.ReleaseManager 34 | } 35 | 36 | func (d *defaultInstallationManager) InstallCNIMetricsHelper(image string, tag string, clusterId string) error { 37 | values := map[string]interface{}{ 38 | "env": map[string]interface{}{ 39 | "AWS_CLUSTER_ID": clusterId, 40 | }, 41 | "image": map[string]interface{}{ 42 | "repository": image, 43 | "tag": tag, 44 | }, 45 | } 46 | 47 | projectRoot := utils.GetProjectRoot() 48 | _, err := d.releaseManager.InstallUnPackagedRelease(projectRoot+CNIMetricsHelperChartDir, 49 | CNIMetricsHelperReleaseName, CNIMetricHelperNamespace, values) 50 | return err 51 | } 52 | 53 | func (d *defaultInstallationManager) UnInstallCNIMetricsHelper() error { 54 | _, err := d.releaseManager.UninstallRelease(CNIMetricHelperNamespace, CNIMetricsHelperReleaseName) 55 | return err 56 | } 57 | 58 | func (d *defaultInstallationManager) InstallTigeraOperator(version string) error { 59 | _, err := d.releaseManager.InstallPackagedRelease(TigeraOperatorHelmCharts, TigeraOperatorReleaseName, version, TigeraOperatorNamespace, map[string]interface{}{}) 60 | return err 61 | } 62 | 63 | func (d *defaultInstallationManager) UninstallTigeraOperator() error { 64 | _, err := d.releaseManager.UninstallRelease(TigeraOperatorNamespace, TigeraOperatorReleaseName) 65 | return err 66 | } 67 | -------------------------------------------------------------------------------- /test/framework/resources/aws/services/autoscaling.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package services 15 | 16 | import ( 17 | "context" 18 | "fmt" 19 | 20 | "github.com/aws/aws-sdk-go-v2/aws" 21 | "github.com/aws/aws-sdk-go-v2/service/autoscaling" 22 | "github.com/aws/aws-sdk-go-v2/service/autoscaling/types" 23 | ) 24 | 25 | type AutoScaling interface { 26 | DescribeAutoScalingGroup(ctx context.Context, autoScalingGroupName string) ([]types.AutoScalingGroup, error) 27 | } 28 | 29 | // Directly using the client to interact with the service instead of an interface. 30 | type defaultAutoScaling struct { 31 | client *autoscaling.Client 32 | } 33 | 34 | func NewAutoScaling(cfg aws.Config) AutoScaling { 35 | return &defaultAutoScaling{ 36 | client: autoscaling.NewFromConfig(cfg), 37 | } 38 | } 39 | 40 | func (d defaultAutoScaling) DescribeAutoScalingGroup(ctx context.Context, autoScalingGroupName string) ([]types.AutoScalingGroup, error) { 41 | describeAutoScalingGroupIp := &autoscaling.DescribeAutoScalingGroupsInput{ 42 | AutoScalingGroupNames: []string{autoScalingGroupName}, 43 | } 44 | asg, err := d.client.DescribeAutoScalingGroups(ctx, describeAutoScalingGroupIp) 45 | if err != nil { 46 | return nil, err 47 | } 48 | if len(asg.AutoScalingGroups) == 0 { 49 | return nil, fmt.Errorf("failed to find asg %s", autoScalingGroupName) 50 | } 51 | 52 | return asg.AutoScalingGroups, nil 53 | } 54 | -------------------------------------------------------------------------------- /test/framework/resources/aws/services/cloudwatch.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package services 15 | 16 | import ( 17 | "context" 18 | 19 | "github.com/aws/aws-sdk-go-v2/aws" 20 | "github.com/aws/aws-sdk-go-v2/service/cloudwatch" 21 | ) 22 | 23 | type CloudWatch interface { 24 | GetMetricStatistics(ctx context.Context, params *cloudwatch.GetMetricStatisticsInput, optFns ...func(*cloudwatch.Options)) (*cloudwatch.GetMetricStatisticsOutput, error) 25 | PutMetricData(ctx context.Context, params *cloudwatch.PutMetricDataInput, optFns ...func(*cloudwatch.Options)) (*cloudwatch.PutMetricDataOutput, error) 26 | } 27 | 28 | type defaultCloudWatch struct { 29 | client *cloudwatch.Client 30 | } 31 | 32 | func NewCloudWatch(cfg aws.Config) CloudWatch { 33 | return &defaultCloudWatch{ 34 | client: cloudwatch.NewFromConfig(cfg), 35 | } 36 | } 37 | 38 | func (d *defaultCloudWatch) GetMetricStatistics(ctx context.Context, params *cloudwatch.GetMetricStatisticsInput, optFns ...func(*cloudwatch.Options)) (*cloudwatch.GetMetricStatisticsOutput, error) { 39 | return d.client.GetMetricStatistics(ctx, params, optFns...) 40 | } 41 | 42 | func (d *defaultCloudWatch) PutMetricData(ctx context.Context, params *cloudwatch.PutMetricDataInput, optFns ...func(*cloudwatch.Options)) (*cloudwatch.PutMetricDataOutput, error) { 43 | return d.client.PutMetricData(ctx, params, optFns...) 44 | } 45 | -------------------------------------------------------------------------------- /test/framework/resources/k8s/manifest/eniconfig.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package manifest 15 | 16 | import ( 17 | "fmt" 18 | 19 | "github.com/aws/amazon-vpc-cni-k8s/pkg/apis/crd/v1alpha1" 20 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 21 | ) 22 | 23 | type ENIConfigBuilder struct { 24 | name string 25 | subnetID string 26 | securityGroup []string 27 | } 28 | 29 | func NewENIConfigBuilder() *ENIConfigBuilder { 30 | return &ENIConfigBuilder{ 31 | name: "eniConfig-test", 32 | } 33 | } 34 | 35 | func (e *ENIConfigBuilder) Name(name string) *ENIConfigBuilder { 36 | e.name = name 37 | return e 38 | } 39 | 40 | func (e *ENIConfigBuilder) SubnetID(subnetID string) *ENIConfigBuilder { 41 | e.subnetID = subnetID 42 | return e 43 | } 44 | 45 | func (e *ENIConfigBuilder) SecurityGroup(securityGroup []string) *ENIConfigBuilder { 46 | e.securityGroup = securityGroup 47 | return e 48 | } 49 | 50 | func (e *ENIConfigBuilder) Build() (*v1alpha1.ENIConfig, error) { 51 | if e.subnetID == "" { 52 | return nil, fmt.Errorf("subnet id is a required field") 53 | } 54 | 55 | if e.securityGroup == nil { 56 | return &v1alpha1.ENIConfig{ 57 | ObjectMeta: v1.ObjectMeta{ 58 | Name: e.name, 59 | }, 60 | Spec: v1alpha1.ENIConfigSpec{ 61 | Subnet: e.subnetID, 62 | }, 63 | }, nil 64 | } else { 65 | return &v1alpha1.ENIConfig{ 66 | ObjectMeta: v1.ObjectMeta{ 67 | Name: e.name, 68 | }, 69 | Spec: v1alpha1.ENIConfigSpec{ 70 | SecurityGroups: e.securityGroup, 71 | Subnet: e.subnetID, 72 | }, 73 | }, nil 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /test/framework/resources/k8s/resources/configmap.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package resources 15 | 16 | import ( 17 | "context" 18 | 19 | v1 "k8s.io/api/core/v1" 20 | "k8s.io/apimachinery/pkg/types" 21 | "sigs.k8s.io/controller-runtime/pkg/client" 22 | ) 23 | 24 | type ConfigMapManager interface { 25 | GetConfigMap(namespace string, name string) (*v1.ConfigMap, error) 26 | UpdateConfigMap(oldConfigMap *v1.ConfigMap, newConfigMap *v1.ConfigMap) error 27 | } 28 | 29 | type defaultConfigMapManager struct { 30 | k8sClient client.Client 31 | } 32 | 33 | func (d defaultConfigMapManager) GetConfigMap(namespace string, name string) (*v1.ConfigMap, error) { 34 | configMap := v1.ConfigMap{} 35 | return &configMap, d.k8sClient.Get(context.Background(), types. 36 | NamespacedName{Name: name, Namespace: namespace}, &configMap) 37 | } 38 | 39 | func (d defaultConfigMapManager) UpdateConfigMap(oldConfigMap *v1.ConfigMap, newConfigMap *v1.ConfigMap) error { 40 | ctx := context.Background() 41 | return d.k8sClient.Patch(ctx, newConfigMap, client.MergeFrom(oldConfigMap)) 42 | } 43 | 44 | func NewConfigMapManager(k8sClient client.Client) ConfigMapManager { 45 | return &defaultConfigMapManager{k8sClient: k8sClient} 46 | } 47 | -------------------------------------------------------------------------------- /test/framework/resources/k8s/resources/eniconfig.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package resources 15 | 16 | import ( 17 | "context" 18 | 19 | "sigs.k8s.io/controller-runtime/pkg/client" 20 | ) 21 | 22 | type CustomResourceManager interface { 23 | CreateResource(resource client.Object) error 24 | DeleteResource(resource client.Object) error 25 | } 26 | 27 | type defaultCustomResourceManager struct { 28 | k8sClient client.Client 29 | } 30 | 31 | func NewCustomResourceManager(k8sClient client.Client) CustomResourceManager { 32 | return &defaultCustomResourceManager{k8sClient: k8sClient} 33 | } 34 | 35 | func (d *defaultCustomResourceManager) CreateResource(resource client.Object) error { 36 | ctx := context.Background() 37 | return d.k8sClient.Create(ctx, resource) 38 | } 39 | 40 | func (d *defaultCustomResourceManager) DeleteResource(resource client.Object) error { 41 | ctx := context.Background() 42 | return d.k8sClient.Delete(ctx, resource) 43 | } 44 | -------------------------------------------------------------------------------- /test/framework/resources/k8s/resources/events.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package resources 15 | 16 | import ( 17 | "context" 18 | 19 | eventsv1 "k8s.io/api/events/v1" 20 | "sigs.k8s.io/controller-runtime/pkg/client" 21 | ) 22 | 23 | type EventManager interface { 24 | GetEventsWithOptions(opts *client.ListOptions) (eventsv1.EventList, error) 25 | } 26 | 27 | type defaultEventManager struct { 28 | k8sClient client.Client 29 | } 30 | 31 | func NewEventManager(k8sClient client.Client) EventManager { 32 | return &defaultEventManager{k8sClient: k8sClient} 33 | } 34 | 35 | func (d defaultEventManager) GetEventsWithOptions(opts *client.ListOptions) (eventsv1.EventList, error) { 36 | eventList := eventsv1.EventList{} 37 | err := d.k8sClient.List(context.Background(), &eventList, opts) 38 | return eventList, err 39 | } 40 | -------------------------------------------------------------------------------- /test/framework/resources/k8s/resources/networkpolicy.go: -------------------------------------------------------------------------------- 1 | package resources 2 | 3 | import ( 4 | "context" 5 | 6 | "sigs.k8s.io/controller-runtime/pkg/client" 7 | ) 8 | 9 | type NetworkPolicyManager interface { 10 | CreateNetworkPolicy(networkPolicy client.Object) error 11 | DeleteNetworkPolicy(networkPolicy client.Object) error 12 | } 13 | 14 | type defaultNetworkPolicyManager struct { 15 | networkPolicyClient client.Client 16 | } 17 | 18 | func NewNetworkPolicyManager(client client.Client) NetworkPolicyManager { 19 | return &defaultNetworkPolicyManager{client} 20 | } 21 | 22 | func (d *defaultNetworkPolicyManager) CreateNetworkPolicy(networkPolicy client.Object) error { 23 | return d.networkPolicyClient.Create(context.Background(), networkPolicy) 24 | } 25 | 26 | func (d *defaultNetworkPolicyManager) DeleteNetworkPolicy(networkPolicy client.Object) error { 27 | return d.networkPolicyClient.Delete(context.Background(), networkPolicy) 28 | } 29 | -------------------------------------------------------------------------------- /test/framework/resources/k8s/utils/addon.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/aws/amazon-vpc-cni-k8s/test/framework/resources/aws/services" 7 | "github.com/aws/amazon-vpc-cni-k8s/test/framework/utils" 8 | "github.com/pkg/errors" 9 | "k8s.io/apimachinery/pkg/util/wait" 10 | ) 11 | 12 | func WaitTillAddonIsDeleted(eks services.EKS, addonName string, clusterName string) error { 13 | ctx := context.Background() 14 | return wait.PollImmediateUntil(utils.PollIntervalShort, func() (bool, error) { 15 | _, err := eks.DescribeAddon(context.TODO(), services.AddonInput{ 16 | AddonName: addonName, 17 | ClusterName: clusterName, 18 | }) 19 | if err != nil { 20 | return false, err 21 | } 22 | return false, nil 23 | }, ctx.Done()) 24 | } 25 | 26 | func WaitTillAddonIsActive(eks services.EKS, addonName string, clusterName string) error { 27 | ctx := context.Background() 28 | return wait.PollImmediateUntil(utils.PollIntervalShort, func() (bool, error) { 29 | describeAddonOutput, err := eks.DescribeAddon(context.TODO(), services.AddonInput{ 30 | AddonName: addonName, 31 | ClusterName: clusterName, 32 | }) 33 | if err != nil { 34 | return false, err 35 | } 36 | 37 | status := describeAddonOutput.Addon.Status 38 | if status == "CREATE_FAILED" || status == "DEGRADED" { 39 | return false, errors.Errorf("Create Addon Failed, addon status: %s", status) 40 | } 41 | if status == "ACTIVE" { 42 | return true, nil 43 | } 44 | return false, nil 45 | }, ctx.Done()) 46 | } 47 | -------------------------------------------------------------------------------- /test/framework/resources/k8s/utils/node.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package utils 15 | 16 | import ( 17 | "strings" 18 | 19 | v1 "k8s.io/api/core/v1" 20 | ) 21 | 22 | func GetInstanceIDFromNode(node v1.Node) string { 23 | id := strings.Split(node.Spec.ProviderID, "/") 24 | return id[len(id)-1] 25 | } 26 | -------------------------------------------------------------------------------- /test/framework/utils/const.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package utils 15 | 16 | import "time" 17 | 18 | const ( 19 | DefaultTestNamespace = "cni-automation" 20 | AwsNodeNamespace = "kube-system" 21 | AwsNodeName = "aws-node" 22 | AWSInitContainerName = "aws-vpc-cni-init" 23 | MultusNodeName = "kube-multus-ds" 24 | MultusContainerName = "kube-multus" 25 | 26 | // See https://gallery.ecr.aws/eks/aws-vpc-cni-test-helper 27 | TestAgentImage = "networking-e2e-test-images/aws-vpc-cni-test-helper:20231212" 28 | BusyBoxImage = "networking-e2e-test-images/busybox:latest" 29 | NginxImage = "networking-e2e-test-images/nginx:1.25.2" 30 | NetCatImage = "networking-e2e-test-images/netcat-openbsd:v1.0" 31 | CurlImage = "networking-e2e-test-images/curlimages/curl:latest" 32 | 33 | PollIntervalShort = time.Second * 2 34 | PollIntervalMedium = time.Second * 5 35 | PollIntervalLong = time.Second * 20 36 | 37 | DefaultDeploymentReadyTimeout = time.Second * 300 38 | ) 39 | -------------------------------------------------------------------------------- /test/framework/utils/image.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | func GetTestImage(registry string, image string) string { 4 | return registry + "/" + image 5 | } 6 | -------------------------------------------------------------------------------- /test/framework/utils/log.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "github.com/go-logr/logr" 5 | ginkgov2 "github.com/onsi/ginkgo/v2" 6 | zapraw "go.uber.org/zap" 7 | "go.uber.org/zap/zapcore" 8 | "sigs.k8s.io/controller-runtime/pkg/log/zap" 9 | ) 10 | 11 | // NewGinkgoLogger returns new logger with ginkgo backend. 12 | func NewGinkgoLogger() logr.Logger { 13 | encoder := zapcore.NewJSONEncoder(zapraw.NewProductionEncoderConfig()) 14 | return zap.New(zap.UseDevMode(false), 15 | zap.Level(zapraw.InfoLevel), 16 | zap.WriteTo(ginkgov2.GinkgoWriter), 17 | zap.Encoder(encoder)) 18 | } 19 | -------------------------------------------------------------------------------- /test/framework/utils/utils.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package utils 15 | 16 | import ( 17 | "os" 18 | "path/filepath" 19 | "strings" 20 | 21 | appsV1 "k8s.io/api/apps/v1" 22 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 23 | "k8s.io/apimachinery/pkg/types" 24 | ) 25 | 26 | // NamespacedName returns the namespaced name for k8s objects 27 | func NamespacedName(obj v1.Object) types.NamespacedName { 28 | return types.NamespacedName{ 29 | Namespace: obj.GetNamespace(), 30 | Name: obj.GetName(), 31 | } 32 | } 33 | 34 | func GetEnvValueForKeyFromDaemonSet(key string, ds *appsV1.DaemonSet) string { 35 | envVar := ds.Spec.Template.Spec.Containers[0].Env 36 | for _, env := range envVar { 37 | if env.Name == key { 38 | return env.Value 39 | } 40 | } 41 | return "" 42 | } 43 | 44 | func GetProjectRoot() string { 45 | dir, _ := filepath.Abs(filepath.Dir(os.Args[0])) 46 | projectRoot := strings.SplitAfter(dir, "amazon-vpc-cni-k8s")[0] 47 | 48 | if dir == projectRoot { 49 | // in prow tests, the repository name is "vpc-cni" 50 | projectRoot = strings.SplitAfter(dir, "vpc-cni")[0] 51 | } 52 | return projectRoot 53 | } 54 | -------------------------------------------------------------------------------- /test/helm/charts/cni-metrics-helper/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /test/helm/charts/cni-metrics-helper/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: cni-metrics-helper 3 | description: A Helm chart for Kubernetes 4 | type: application 5 | version: 0.1.0 6 | appVersion: 1.16.0 7 | -------------------------------------------------------------------------------- /test/helm/charts/cni-metrics-helper/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* 2 | Expand the name of the chart. 3 | */}} 4 | {{- define "cni-metric-helper.name" -}} 5 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} 6 | {{- end }} 7 | 8 | {{/* 9 | Create a default fully qualified app name. 10 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 11 | If release name contains chart name it will be used as a full name. 12 | */}} 13 | {{- define "cni-metric-helper.fullname" -}} 14 | {{- if .Values.fullnameOverride }} 15 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 16 | {{- else }} 17 | {{- $name := default .Chart.Name .Values.nameOverride }} 18 | {{- if contains $name .Release.Name }} 19 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 20 | {{- else }} 21 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} 22 | {{- end }} 23 | {{- end }} 24 | {{- end }} 25 | 26 | {{/* 27 | Create chart name and version as used by the chart label. 28 | */}} 29 | {{- define "cni-metric-helper.chart" -}} 30 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} 31 | {{- end }} 32 | 33 | {{/* 34 | Common labels 35 | */}} 36 | {{- define "cni-metric-helper.labels" -}} 37 | helm.sh/chart: {{ include "cni-metric-helper.chart" . }} 38 | {{ include "cni-metric-helper.selectorLabels" . }} 39 | {{- if .Chart.AppVersion }} 40 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 41 | {{- end }} 42 | app.kubernetes.io/managed-by: {{ .Release.Service }} 43 | {{- end }} 44 | 45 | {{/* 46 | Selector labels 47 | */}} 48 | {{- define "cni-metric-helper.selectorLabels" -}} 49 | app.kubernetes.io/name: {{ include "cni-metric-helper.name" . }} 50 | app.kubernetes.io/instance: {{ .Release.Name }} 51 | {{- end }} 52 | 53 | {{/* 54 | Create the name of the service account to use 55 | */}} 56 | {{- define "cni-metric-helper.serviceAccountName" -}} 57 | {{- if .Values.serviceAccount.create }} 58 | {{- default (include "cni-metric-helper.fullname" .) .Values.serviceAccount.name }} 59 | {{- else }} 60 | {{- default "default" .Values.serviceAccount.name }} 61 | {{- end }} 62 | {{- end }} 63 | -------------------------------------------------------------------------------- /test/helm/charts/cni-metrics-helper/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ include "cni-metric-helper.fullname" . }} 5 | namespace: {{ .Release.Namespace }} 6 | labels: 7 | {{- include "cni-metric-helper.labels" . | nindent 4 }} 8 | spec: 9 | {{- if not .Values.autoscaling.enabled }} 10 | replicas: {{ .Values.replicaCount }} 11 | {{- end }} 12 | selector: 13 | matchLabels: 14 | {{- include "cni-metric-helper.selectorLabels" . | nindent 6 }} 15 | template: 16 | metadata: 17 | {{- with .Values.podAnnotations }} 18 | annotations: 19 | {{- toYaml . | nindent 8 }} 20 | {{- end }} 21 | labels: 22 | {{- include "cni-metric-helper.selectorLabels" . | nindent 8 }} 23 | spec: 24 | {{- with .Values.imagePullSecrets }} 25 | imagePullSecrets: 26 | {{- toYaml . | nindent 8 }} 27 | {{- end }} 28 | serviceAccountName: {{ include "cni-metric-helper.serviceAccountName" . }} 29 | containers: 30 | - name: {{ .Chart.Name }} 31 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" 32 | imagePullPolicy: {{ .Values.image.pullPolicy }} 33 | env: 34 | {{- range $key, $value := .Values.env }} 35 | - name: {{ $key }} 36 | value: {{ $value | quote }} 37 | {{- end}} 38 | {{- with .Values.nodeSelector }} 39 | nodeSelector: 40 | {{- toYaml . | nindent 8 }} 41 | {{- end }} 42 | {{- with .Values.affinity }} 43 | affinity: 44 | {{- toYaml . | nindent 8 }} 45 | {{- end }} 46 | {{- with .Values.tolerations }} 47 | tolerations: 48 | {{- toYaml . | nindent 8 }} 49 | {{- end }} 50 | -------------------------------------------------------------------------------- /test/helm/charts/cni-metrics-helper/templates/rbac.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.rbac.create }} 2 | apiVersion: "rbac.authorization.k8s.io/v1" 3 | kind: ClusterRole 4 | metadata: 5 | name: {{ include "cni-metric-helper.fullname" . }} 6 | rules: 7 | - apiGroups: 8 | - "" 9 | resources: 10 | - "nodes" 11 | - "pods" 12 | - "pods/proxy" 13 | - "services" 14 | - "resourcequotas" 15 | - "replicationcontrollers" 16 | - "limitranges" 17 | - "persistentvolumeclaims" 18 | - "persistentvolumes" 19 | - "namespaces" 20 | - "endpoints" 21 | verbs: 22 | - "list" 23 | - "watch" 24 | - "get" 25 | - apiGroups: 26 | - "extensions" 27 | resources: 28 | - "daemonsets" 29 | - "deployments" 30 | - "replicasets" 31 | verbs: 32 | - "list" 33 | - "watch" 34 | - apiGroups: 35 | - "apps" 36 | resources: 37 | - "statefulsets" 38 | verbs: 39 | - "list" 40 | - "watch" 41 | - apiGroups: 42 | - "batch" 43 | resources: 44 | - "cronjobs" 45 | - "jobs" 46 | verbs: 47 | - "list" 48 | - "watch" 49 | - apiGroups: 50 | - "autoscaling" 51 | resources: 52 | - "horizontalpodautoscalers" 53 | verbs: 54 | - "list" 55 | - "watch" 56 | --- 57 | apiVersion: "rbac.authorization.k8s.io/v1" 58 | kind: "ClusterRoleBinding" 59 | metadata: 60 | name: {{ include "cni-metric-helper.fullname" . }} 61 | roleRef: 62 | apiGroup: "rbac.authorization.k8s.io" 63 | kind: "ClusterRole" 64 | name: {{ include "cni-metric-helper.fullname" . }} 65 | subjects: 66 | - kind: "ServiceAccount" 67 | name: {{ include "cni-metric-helper.fullname" . }} 68 | namespace: {{ .Release.Namespace }} 69 | {{- end}} -------------------------------------------------------------------------------- /test/helm/charts/cni-metrics-helper/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.serviceAccount.create -}} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: {{ include "cni-metric-helper.serviceAccountName" . }} 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | {{- include "cni-metric-helper.labels" . | nindent 4 }} 9 | {{- with .Values.serviceAccount.annotations }} 10 | annotations: 11 | {{- toYaml . | nindent 4 }} 12 | {{- end }} 13 | {{- end }} 14 | -------------------------------------------------------------------------------- /test/helm/charts/cni-metrics-helper/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for cni-metric-helper. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | replicaCount: 1 6 | 7 | image: 8 | repository: 602401143452.dkr.ecr.us-west-2.amazonaws.com/cni-metrics-helper 9 | pullPolicy: Always 10 | tag: "v1.11.2" 11 | 12 | imagePullSecrets: [] 13 | nameOverride: "" 14 | fullnameOverride: "" 15 | 16 | serviceAccount: 17 | create: true 18 | annotations: {} 19 | name: "cni-metrics-helper" 20 | 21 | ingress: 22 | enabled: false 23 | annotations: {} 24 | # kubernetes.io/ingress.class: nginx 25 | # kubernetes.io/tls-acme: "true" 26 | hosts: 27 | - host: chart-example.local 28 | paths: [] 29 | tls: [] 30 | # - secretName: chart-example-tls 31 | # hosts: 32 | # - chart-example.local 33 | 34 | env: 35 | USE_CLOUDWATCH: "true" 36 | AWS_CLUSTER_ID: "" 37 | 38 | rbac: 39 | create: true 40 | 41 | resources: {} 42 | # We usually recommend not to specify default resources and to leave this as a conscious 43 | # choice for the user. This also increases chances charts run on environments with little 44 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 45 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 46 | # limits: 47 | # cpu: 100m 48 | # memory: 128Mi 49 | # requests: 50 | # cpu: 100m 51 | # memory: 128Mi 52 | 53 | autoscaling: 54 | enabled: false 55 | minReplicas: 1 56 | maxReplicas: 100 57 | targetCPUUtilizationPercentage: 80 58 | # targetMemoryUtilizationPercentage: 80 59 | 60 | nodeSelector: 61 | kubernetes.io/os: "linux" 62 | 63 | tolerations: [] 64 | 65 | affinity: {} 66 | -------------------------------------------------------------------------------- /test/helm/helm-lint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | 4 | set +x 5 | 6 | SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )" 7 | AM_HELM_CHART=$SCRIPTPATH/../../charts/aws-vpc-cni/ 8 | TMP_DIR="$SCRIPTPATH/../../build" 9 | PLATFORM=$(uname | tr '[:upper:]' '[:lower:]') 10 | HELM3_VERSION="3.5.3" 11 | HELM2_VERSION="2.16.10" 12 | HELM_DIR="${SCRIPTPATH}/../../charts" 13 | 14 | mkdir -p $TMP_DIR 15 | 16 | if [ ! -x "$TMP_DIR/helm" ]; then 17 | echo "🥑 Downloading the \"helm3\" binary" 18 | curl -L https://get.helm.sh/helm-v$HELM3_VERSION-$PLATFORM-amd64.tar.gz | tar zxf - -C $TMP_DIR 19 | mv $TMP_DIR/$PLATFORM-amd64/helm $TMP_DIR/. 20 | chmod +x $TMP_DIR/helm 21 | echo "👍 Downloaded the \"helm\" binary" 22 | fi 23 | 24 | if [ ! -x "$TMP_DIR/helm2" ]; then 25 | echo "🥑 Downloading the \"helm2\" binary" 26 | curl -L https://get.helm.sh/helm-v$HELM2_VERSION-$PLATFORM-amd64.tar.gz | tar zxf - -C $TMP_DIR 27 | mv $TMP_DIR/$PLATFORM-amd64/helm $TMP_DIR/helm2 28 | chmod +x $TMP_DIR/helm2 29 | echo "👍 Downloaded the \"helm2\" binary" 30 | fi 31 | export PATH=$TMP_DIR:$PATH 32 | 33 | echo "==============================================================================" 34 | echo " Linting Helm Chart w/ Helm v3" 35 | echo "==============================================================================" 36 | helm lint $AM_HELM_CHART 37 | 38 | echo "==============================================================================" 39 | echo " Linting Helm Chart w/ Helm v2" 40 | echo "==============================================================================" 41 | helm2 lint $AM_HELM_CHART 42 | 43 | echo "✅ Helm Linting for v2 and v3 have successfully completed!" 44 | 45 | echo "==============================================================================" 46 | echo " Generate Template w/ Helm v3" 47 | echo "==============================================================================" 48 | 49 | helm template aws-vpc-cni "${HELM_DIR}/aws-vpc-cni" --debug --namespace=kube-system -f "${HELM_DIR}/aws-vpc-cni/values.yaml" > /dev/null 50 | 51 | echo "==============================================================================" 52 | echo " Generate Template w/ Helm v2" 53 | echo "==============================================================================" 54 | 55 | helm2 template --name aws-vpc-cni "${HELM_DIR}/aws-vpc-cni" --debug --namespace=kube-system -f "${HELM_DIR}/aws-vpc-cni/values.yaml" > /dev/null 56 | 57 | echo "✅ Helm template generation for v2 and v3 have successfully completed!" 58 | -------------------------------------------------------------------------------- /test/integration/az-traffic/pod_az_traffic_suite_test.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package az_traffic 15 | 16 | import ( 17 | "fmt" 18 | "testing" 19 | 20 | "github.com/aws/amazon-vpc-cni-k8s/test/framework" 21 | "github.com/aws/amazon-vpc-cni-k8s/test/framework/utils" 22 | 23 | . "github.com/onsi/ginkgo/v2" 24 | . "github.com/onsi/gomega" 25 | ) 26 | 27 | func TestAZConnectivity(t *testing.T) { 28 | RegisterFailHandler(Fail) 29 | RunSpecs(t, "CNI AZ Traffic Test Suite") 30 | } 31 | 32 | var _ = BeforeSuite(func() { 33 | f = framework.New(framework.GlobalOptions) 34 | 35 | By("creating test namespace") 36 | _ = f.K8sResourceManagers.NamespaceManager().CreateNamespace(utils.DefaultTestNamespace) 37 | 38 | By(fmt.Sprintf("getting the node with the node label key %s and value %s", 39 | f.Options.NgNameLabelKey, f.Options.NgNameLabelVal)) 40 | _, err := f.K8sResourceManagers.NodeManager().GetNodes(f.Options.NgNameLabelKey, f.Options.NgNameLabelVal) 41 | Expect(err).ToNot(HaveOccurred()) 42 | 43 | }) 44 | 45 | var _ = AfterSuite(func() { 46 | By("deleting test namespace") 47 | _ = f.K8sResourceManagers.NamespaceManager(). 48 | DeleteAndWaitTillNamespaceDeleted(utils.DefaultTestNamespace) 49 | }) 50 | -------------------------------------------------------------------------------- /test/integration/custom-networking-sgpp/trunk_test.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package custom_networking_sgpp 15 | 16 | import ( 17 | "context" 18 | 19 | k8sUtils "github.com/aws/amazon-vpc-cni-k8s/test/framework/resources/k8s/utils" 20 | . "github.com/onsi/ginkgo/v2" 21 | . "github.com/onsi/gomega" 22 | ) 23 | 24 | var _ = Describe("Trunk ENI Security Group Test", func() { 25 | Context("when validating security group on trunk ENI", func() { 26 | It("should match security group in ENIConfig", func() { 27 | instanceID := k8sUtils.GetInstanceIDFromNode(targetNode) 28 | instance, err := f.CloudServices.EC2().DescribeInstance(context.TODO(), instanceID) 29 | Expect(err).ToNot(HaveOccurred()) 30 | 31 | trunkSGMatch := false 32 | for _, nwInterface := range instance.NetworkInterfaces { 33 | if *nwInterface.InterfaceType == "trunk" { 34 | for _, group := range nwInterface.Groups { 35 | if *group.GroupId == customNetworkingSGID { 36 | trunkSGMatch = true 37 | break 38 | } 39 | } 40 | if trunkSGMatch { 41 | break 42 | } 43 | } 44 | } 45 | Expect(trunkSGMatch).To(BeTrue()) 46 | }) 47 | }) 48 | }) 49 | -------------------------------------------------------------------------------- /test/integration/ipamd/common.go: -------------------------------------------------------------------------------- 1 | package ipamd 2 | 3 | import ( 4 | "github.com/aws/amazon-vpc-cni-k8s/test/framework" 5 | "github.com/aws/aws-sdk-go-v2/service/ec2/types" 6 | ) 7 | 8 | var primaryInstance types.Instance 9 | var f *framework.Framework 10 | var err error 11 | 12 | func ceil(x, y int) int { 13 | return (x + y - 1) / y 14 | } 15 | 16 | func Max(x, y int) int { 17 | if x < y { 18 | return y 19 | } 20 | return x 21 | } 22 | 23 | // MinIgnoreZero returns smaller of two number, if any number is zero returns the other number 24 | func MinIgnoreZero(x, y int) int { 25 | if x == 0 { 26 | return y 27 | } 28 | if y == 0 { 29 | return x 30 | } 31 | if x < y { 32 | return x 33 | } 34 | return y 35 | } 36 | -------------------------------------------------------------------------------- /test/integration/ipv6/pod_v6_networking_suite_test.go: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"). You may 4 | // not use this file except in compliance with the License. A copy of the 5 | // License is located at 6 | // 7 | // http://aws.amazon.com/apache2.0/ 8 | // 9 | // or in the "license" file accompanying this file. This file is distributed 10 | // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | // express or implied. See the License for the specific language governing 12 | // permissions and limitations under the License. 13 | 14 | package ipv6 15 | 16 | import ( 17 | "fmt" 18 | "testing" 19 | 20 | "github.com/aws/amazon-vpc-cni-k8s/test/framework" 21 | k8sUtils "github.com/aws/amazon-vpc-cni-k8s/test/framework/resources/k8s/utils" 22 | "github.com/aws/amazon-vpc-cni-k8s/test/framework/utils" 23 | 24 | . "github.com/onsi/ginkgo/v2" 25 | . "github.com/onsi/gomega" 26 | v1 "k8s.io/api/core/v1" 27 | ) 28 | 29 | var primaryNode v1.Node 30 | 31 | func TestCNIv6PodNetworking(t *testing.T) { 32 | RegisterFailHandler(Fail) 33 | RunSpecs(t, "CNI Pod Networking Suite") 34 | } 35 | 36 | var _ = BeforeSuite(func() { 37 | f = framework.New(framework.GlobalOptions) 38 | 39 | By("creating test namespace") 40 | _ = f.K8sResourceManagers.NamespaceManager().CreateNamespace(utils.DefaultTestNamespace) 41 | 42 | By(fmt.Sprintf("getting the node with the node label key %s and value %s", 43 | f.Options.NgNameLabelKey, f.Options.NgNameLabelVal)) 44 | nodes, err := f.K8sResourceManagers.NodeManager().GetNodes(f.Options.NgNameLabelKey, f.Options.NgNameLabelVal) 45 | Expect(err).ToNot(HaveOccurred()) 46 | 47 | By("verifying that more than 1 node is available for the test") 48 | Expect(len(nodes.Items)).Should(BeNumerically(">", 1)) 49 | 50 | // Set the primary node used for testing 51 | primaryNode = nodes.Items[0] 52 | }) 53 | 54 | var _ = AfterSuite(func() { 55 | By("deleting test namespace") 56 | _ = f.K8sResourceManagers.NamespaceManager().DeleteAndWaitTillNamespaceDeleted(utils.DefaultTestNamespace) 57 | 58 | k8sUtils.UpdateEnvVarOnDaemonSetAndWaitUntilReady(f, "aws-node", "kube-system", 59 | "aws-node", map[string]string{ 60 | AWS_VPC_ENI_MTU: "9001", 61 | AWS_VPC_K8S_CNI_VETHPREFIX: "eni", 62 | }, 63 | map[string]struct{}{ 64 | "WARM_IP_TARGET": {}, 65 | "WARM_ENI_TARGET": {}, 66 | }) 67 | }) 68 | -------------------------------------------------------------------------------- /test/integration/multus/multus_setup_suite_test.go: -------------------------------------------------------------------------------- 1 | package multus 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/aws/amazon-vpc-cni-k8s/test/framework" 8 | "github.com/aws/amazon-vpc-cni-k8s/test/framework/utils" 9 | 10 | . "github.com/onsi/ginkgo/v2" 11 | . "github.com/onsi/gomega" 12 | ) 13 | 14 | var f *framework.Framework 15 | 16 | func TestMultusSetup(t *testing.T) { 17 | RegisterFailHandler(Fail) 18 | RunSpecs(t, "Multus Setup Suite") 19 | } 20 | 21 | var _ = BeforeSuite(func() { 22 | f = framework.New(framework.GlobalOptions) 23 | 24 | By("Check if Multus Daemonset is Ready") 25 | _, err := f.K8sResourceManagers.DaemonSetManager().GetDaemonSet(utils.AwsNodeNamespace, utils.MultusNodeName) 26 | Expect(err).NotTo(HaveOccurred()) 27 | 28 | err = f.K8sResourceManagers.DaemonSetManager().CheckIfDaemonSetIsReady(utils.AwsNodeNamespace, utils.MultusNodeName) 29 | Expect(err).NotTo(HaveOccurred()) 30 | 31 | By(fmt.Sprintf("getting the node with the node label key %s and value %s if specified, else get all nodes", 32 | f.Options.NgNameLabelKey, f.Options.NgNameLabelVal)) 33 | nodes, err := f.K8sResourceManagers.NodeManager().GetNodes(f.Options.NgNameLabelKey, f.Options.NgNameLabelVal) 34 | Expect(err).ToNot(HaveOccurred()) 35 | 36 | By("verifying that atleast 1 node is present for the test") 37 | Expect(len(nodes.Items)).Should(BeNumerically(">", 0)) 38 | }) 39 | -------------------------------------------------------------------------------- /test/integration/multus/multus_setup_test.go: -------------------------------------------------------------------------------- 1 | package multus 2 | 3 | import ( 4 | "fmt" 5 | 6 | . "github.com/onsi/ginkgo/v2" 7 | . "github.com/onsi/gomega" 8 | ) 9 | 10 | var _ = Describe("test Multus Deployment", func() { 11 | Context("validate Multus Deployment", func() { 12 | It("multus pod logs shouldnt have any errors", func() { 13 | By("Check Multus pod logs running on all worker nodes") 14 | multusPods, err := f.K8sResourceManagers.PodManager().GetPodsWithLabelSelector("name", "multus") 15 | Expect(err).NotTo(HaveOccurred()) 16 | 17 | for _, pod := range multusPods.Items { 18 | podStr := fmt.Sprintf("Validating logs for pod: %v in Namespace: %v", pod.Name, pod.Namespace) 19 | By(podStr) 20 | logs, err := f.K8sResourceManagers.PodManager().PodLogs(pod.Namespace, pod.Name) 21 | Expect(err).NotTo(HaveOccurred()) 22 | fmt.Fprintln(GinkgoWriter, logs) 23 | } 24 | }) 25 | }) 26 | }) 27 | -------------------------------------------------------------------------------- /testdata/amazon-eks-cni-policy-v4.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Statement": [ 4 | { 5 | "Effect": "Allow", 6 | "Action": [ 7 | "ec2:AssignPrivateIpAddresses", 8 | "ec2:AttachNetworkInterface", 9 | "ec2:CreateNetworkInterface", 10 | "ec2:DeleteNetworkInterface", 11 | "ec2:DescribeInstances", 12 | "ec2:DescribeTags", 13 | "ec2:DescribeNetworkInterfaces", 14 | "ec2:DescribeInstanceTypes", 15 | "ec2:DetachNetworkInterface", 16 | "ec2:ModifyNetworkInterfaceAttribute", 17 | "ec2:UnassignPrivateIpAddresses" 18 | ], 19 | "Resource": "*" 20 | }, 21 | { 22 | "Effect": "Allow", 23 | "Action": [ 24 | "ec2:CreateTags" 25 | ], 26 | "Resource": [ 27 | "arn:aws:ec2:*:*:network-interface/*" 28 | ] 29 | } 30 | ] 31 | } -------------------------------------------------------------------------------- /testdata/deploy-130-pods.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: deploy-130-pods 5 | spec: 6 | replicas: 1 7 | selector: 8 | matchLabels: 9 | app: deploy-130-pods 10 | template: 11 | metadata: 12 | name: test-pod-130 13 | labels: 14 | app: deploy-130-pods 15 | tier: backend 16 | track: stable 17 | spec: 18 | containers: 19 | - name: hello 20 | image: public.ecr.aws/eks-distro/kubernetes/pause:3.9 21 | ports: 22 | - name: http 23 | containerPort: 80 24 | nodeSelector: 25 | eks.amazonaws.com/nodegroup: cni-test-multi-node-mng 26 | -------------------------------------------------------------------------------- /testdata/deploy-5000-pods.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: deploy-5000-pods 5 | spec: 6 | replicas: 1 7 | selector: 8 | matchLabels: 9 | app: deploy-5000-pods 10 | template: 11 | metadata: 12 | name: test-pod-5000 13 | labels: 14 | app: deploy-5000-pods 15 | tier: backend 16 | track: stable 17 | spec: 18 | containers: 19 | - name: hello 20 | image: public.ecr.aws/eks-distro/kubernetes/pause:3.9 21 | ports: 22 | - name: http 23 | containerPort: 80 24 | nodeSelector: 25 | eks.amazonaws.com/nodegroup: cni-test-multi-node-mng 26 | -------------------------------------------------------------------------------- /testdata/deploy-730-pods.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: deploy-730-pods 5 | spec: 6 | replicas: 1 7 | selector: 8 | matchLabels: 9 | app: deploy-730-pods 10 | template: 11 | metadata: 12 | name: test-pod-730 13 | labels: 14 | app: deploy-730-pods 15 | tier: backend 16 | track: stable 17 | spec: 18 | containers: 19 | - name: hello 20 | image: public.ecr.aws/eks-distro/kubernetes/pause:3.9 21 | ports: 22 | - name: http 23 | containerPort: 80 24 | nodeSelector: 25 | eks.amazonaws.com/nodegroup: cni-test-single-node-mng 26 | -------------------------------------------------------------------------------- /testdata/dummy-role-policy.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Statement": [ 4 | { 5 | "Action": [ 6 | "s3:GetBucketLocation", 7 | "s3:GetEncryptionConfiguration", 8 | "s3:ListBucket", 9 | "s3:ListBucketVersions" 10 | ], 11 | "Effect": "Allow", 12 | "Resource": [ 13 | "*" 14 | ] 15 | }] 16 | } 17 | -------------------------------------------------------------------------------- /testdata/executable: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "Hello!" 4 | -------------------------------------------------------------------------------- /testdata/regular-file.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/c9d6f7baeb2f4b2975f71d53b3099bc87f68fbf4/testdata/regular-file.txt -------------------------------------------------------------------------------- /utils/constants.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | const ( 4 | // EnableImdsOnlyMode is used to specify that EC2 API calls should be skipped and only IMDS metadata should be 5 | // used to get ENI information. 6 | EnvEnableImdsOnlyMode = "ENABLE_IMDS_ONLY_MODE" 7 | ) 8 | -------------------------------------------------------------------------------- /utils/imds/imds.go: -------------------------------------------------------------------------------- 1 | package imds 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "io" 7 | 8 | "github.com/aws/aws-sdk-go-v2/config" 9 | "github.com/aws/aws-sdk-go-v2/feature/ec2/imds" 10 | ) 11 | 12 | // EC2Metadata wraps the methods from the amazon-sdk-go's ec2metadata package 13 | // type EC2Metadata interface { 14 | // GetMetadata(path string) (string, error) 15 | // Region() (string, error) 16 | // } 17 | 18 | func GetMetaData(key string) (string, error) { 19 | cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRetryMaxAttempts(10)) 20 | if err != nil { 21 | return "", fmt.Errorf("unable to load SDK config, %v", err) 22 | } 23 | 24 | client := imds.NewFromConfig(cfg) 25 | requestedData, err := client.GetMetadata(context.TODO(), &imds.GetMetadataInput{ 26 | Path: key, 27 | }) 28 | if err != nil { 29 | return "", fmt.Errorf("get instance metadata: failed to retrieve %s - %s", key, err) 30 | } 31 | content, err := io.ReadAll(requestedData.Content) 32 | if err != nil { 33 | return "", fmt.Errorf("get instance metadata: failed to read %s - %s", key, err) 34 | } 35 | return string(content), nil 36 | } 37 | -------------------------------------------------------------------------------- /utils/utils.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "os" 5 | "strconv" 6 | "strings" 7 | 8 | log "github.com/sirupsen/logrus" 9 | ) 10 | 11 | // Parse environment variable and return boolean representation of string, or default value if environment variable is unset 12 | func GetBoolAsStringEnvVar(env string, defaultVal bool) bool { 13 | if val, ok := os.LookupEnv(env); ok { 14 | parsedVal, err := strconv.ParseBool(val) 15 | if err == nil { 16 | return parsedVal 17 | } 18 | log.Errorf("Failed to parse variable %s with value %s as boolean", env, val) 19 | return defaultVal 20 | } 21 | // Environment variable is not set, so return default value 22 | return defaultVal 23 | } 24 | 25 | // Parse environment variable and return integer representation of string, or default value if environment variable is unset 26 | func GetIntFromStringEnvVar(env string, defaultVal int) (int, error, string) { 27 | if val, ok := os.LookupEnv(env); ok { 28 | parsedVal, err := strconv.Atoi(val) 29 | if err == nil { 30 | return parsedVal, nil, val 31 | } 32 | log.Errorf("Failed to parse variable %s with value %s as integer", env, val) 33 | return -1, err, val 34 | } 35 | // Environment variable is not set, so return default value 36 | return defaultVal, nil, "" 37 | } 38 | 39 | // If environment variable is set, return set value, otherwise return default value 40 | func GetEnv(env, defaultVal string) string { 41 | if val, ok := os.LookupEnv(env); ok { 42 | return val 43 | } 44 | return defaultVal 45 | } 46 | 47 | // NetworkPolicyEnforcingMode is the mode of network policy enforcement 48 | type NetworkPolicyEnforcingMode string 49 | 50 | const ( 51 | // None : no network policy enforcement 52 | None NetworkPolicyEnforcingMode = "none" 53 | // Strict : strict network policy enforcement 54 | Strict NetworkPolicyEnforcingMode = "strict" 55 | // Standard :standard network policy enforcement 56 | Standard NetworkPolicyEnforcingMode = "standard" 57 | ) 58 | 59 | // IsValidNetworkPolicyEnforcingMode checks if the input string matches any of the enum values 60 | func IsValidNetworkPolicyEnforcingMode(input string) bool { 61 | switch strings.ToLower(input) { 62 | case string(None), string(Strict), string(Standard): 63 | return true 64 | default: 65 | return false 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /utils/utils_test.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "os" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | const ( 11 | defaultPathEnv = "/host/opt/cni/bin" 12 | defaultBoolEnv = false 13 | defaultIntEnv = 30 14 | 15 | envPath = "Path" 16 | envBool = "Bool" 17 | envInt = "Integer" 18 | ) 19 | 20 | // Validate that GetBoolAsStringEnvVar runs against acceptable format input without error 21 | func TestGetBoolAsStringEnvVar(t *testing.T) { 22 | // Test environment flag variable not set 23 | tmp := GetBoolAsStringEnvVar(envBool, defaultBoolEnv) 24 | assert.Equal(t, tmp, defaultBoolEnv) 25 | 26 | // Test basic Boolean as string set with acceptable format 27 | os.Setenv(envBool, "True") 28 | tmp = GetBoolAsStringEnvVar(envBool, defaultBoolEnv) 29 | assert.Equal(t, tmp, true) 30 | 31 | // Test basic Boolean as string set with unacceptable format 32 | os.Setenv(envBool, "TrUe") 33 | defer os.Unsetenv(envBool) 34 | tmp = GetBoolAsStringEnvVar(envBool, defaultBoolEnv) 35 | assert.Equal(t, tmp, defaultBoolEnv) 36 | } 37 | 38 | // Validate that GetEnv runs without error against environment variable with type other than boolean as string 39 | func TestGetEnv(t *testing.T) { 40 | // Test environment flag variable not set 41 | tmp := GetEnv(envPath, defaultPathEnv) 42 | assert.Equal(t, tmp, defaultPathEnv) 43 | 44 | // Test environment flag variable set 45 | os.Setenv(envPath, "/host/opt/cni/bin/test") 46 | defer os.Unsetenv(envPath) 47 | tmp = GetEnv(envPath, defaultPathEnv) 48 | assert.Equal(t, tmp, "/host/opt/cni/bin/test") 49 | } 50 | 51 | // Validate that GetIntFromStringEnvVar runs against acceptable format input without error 52 | func TestGetIntFromStringEnvVar(t *testing.T) { 53 | // Test environment flag variable not set 54 | tmp, _, _ := GetIntFromStringEnvVar(envInt, defaultIntEnv) 55 | assert.Equal(t, tmp, defaultIntEnv) 56 | 57 | // Test basic Integer as string set with acceptable format 58 | os.Setenv(envInt, "20") 59 | tmp, _, _ = GetIntFromStringEnvVar(envInt, defaultIntEnv) 60 | assert.Equal(t, tmp, 20) 61 | 62 | // Test basic Integer as string set with unacceptable format 63 | os.Setenv(envInt, "2O") 64 | defer os.Unsetenv(envInt) 65 | tmp, _, _ = GetIntFromStringEnvVar(envInt, defaultIntEnv) 66 | assert.Equal(t, tmp, -1) 67 | } 68 | --------------------------------------------------------------------------------