diff --git a/BUILD.md b/BUILD.md index 33daa12a..630fa593 100644 --- a/BUILD.md +++ b/BUILD.md @@ -1,11 +1,14 @@ # CCM for Equinix Metal Build and Design + The Cloud Controller Manager (CCM) Equinix Metal plugin enables a Kubernetes cluster to interface directly with Equinix Metal cloud services. ## Deploy + Read how to deploy the Kubernetes CCM for Equinix Metal in the [README.md](./README.md)! ## Building + To build the binary, run: ``` @@ -29,6 +32,7 @@ make build OS=linux ARCH=arm64 ``` ## Docker Image + To build a docker image, run: ``` @@ -38,17 +42,18 @@ make image The image will be tagged with `:latest` ## CI/CD/Release pipeline + The CI/CD/Release pipeline is run via the following steps: -* `make ci`: builds the binary, runs all tests, builds the OCI image -* `make cd`: takes the image from the prior stage, tags it with the name of the branch and git hash from the commit, and pushes to the docker registry -* `make release`: takes the image from the `ci` stage, tags it with the git tag, and pushes to the docker registry +- `make ci`: builds the binary, runs all tests, builds the OCI image +- `make cd`: takes the image from the prior stage, tags it with the name of the branch and git hash from the commit, and pushes to the docker registry +- `make release`: takes the image from the `ci` stage, tags it with the git tag, and pushes to the docker registry The assumptions about workflow are as follows: -* `make ci` can be run anywhere. The built binaries and OCI image will be named and tagged as per `make build` and `make image` above. -* `make cd` should be run only on a merge into `main`. It generally will be run only in a CI system, e.g. [drone](https://drone.io) or [github actions](https://github.com/features/actions). It requires passing both `CONFIRM=true` to tell it that it is ok to push, and `BRANCH_NAME=${BRANCH_NAME}` to tell it what tag should be used in addition to the git hash. For example, to push out the current commit as main: `make cd CONFIRM=true BRANCH_NAME=main` -* `make release` should be run only on applying a tag to `main`, although it can run elsewhere. It generally will be run only in a CI system. It requires passing both `CONFIRM=true` to tell it that it is ok to push, and `RELEASE_TAG=${RELEASE_TAG}` to tell it what tag this release should be. For example, to push out a tagged version `v1.2.3` on the current commit: `make release CONFIRM=true RELEASE_TAG=v1.2.3`. +- `make ci` can be run anywhere. The built binaries and OCI image will be named and tagged as per `make build` and `make image` above. +- `make cd` should be run only on a merge into `main`. It generally will be run only in a CI system, e.g. [drone](https://drone.io) or [github actions](https://github.com/features/actions). It requires passing both `CONFIRM=true` to tell it that it is ok to push, and `BRANCH_NAME=${BRANCH_NAME}` to tell it what tag should be used in addition to the git hash. For example, to push out the current commit as main: `make cd CONFIRM=true BRANCH_NAME=main` +- `make release` should be run only on applying a tag to `main`, although it can run elsewhere. It generally will be run only in a CI system. It requires passing both `CONFIRM=true` to tell it that it is ok to push, and `RELEASE_TAG=${RELEASE_TAG}` to tell it what tag this release should be. For example, to push out a tagged version `v1.2.3` on the current commit: `make release CONFIRM=true RELEASE_TAG=v1.2.3`. For both `make cd` and `make release`, if you wish to push out a _different_ commit, then check that one out first. @@ -67,15 +72,15 @@ The Equinix Metal CCM follows the standard design principles for external cloud The main entrypoint command is in [main.go](./main.go), and provides fairly standard boilerplate for CCM. -1. import the Equinix Metal implementation as `import _ "github.com/equinix/cloud-provider-equinix-metal/metal"`: +1. import the Equinix Metal implementation as `import _ "github.com/kubernetes-sigs/cloud-provider-equinix-metal/metal"`: 1. calls `init()`, which.. 1. registers the Equinix Metal provider 1. import the main app from [k8s.io/kubernetes/cmd/cloud-controller-manager/app](https://godoc.org/k8s.io/kubernetes/cmd/cloud-controller-manager/app) 1. `main()`: 1. initialize the command - 1. call `command.Execute()` + 1. call `command.Execute()` -The Equinix Metal-specific logic is in [github.com/equinix/cloud-provider-equinix-metal/metal](./metal/), which, as described before, +The Equinix Metal-specific logic is in [github.com/kubernetes-sigs/cloud-provider-equinix-metal/metal](./metal/), which, as described before, is imported into `main.go`. The blank `import _` is used solely for the side-effects, i.e. to cause the `init()` function in [metal/cloud.go](./metal/cloud.go) to run before executing the command. This `init()` registers the Equinix Metal cloud provider via `cloudprovider.RegisterCloudProvider`, where `cloudprovider` is @@ -100,8 +105,8 @@ The `cloud struct` itself is created via `newCloud()`, also in [cloud.go](./meta initializes the `struct` with the `packngo.Client`, as well as `struct`s for each of the sub-components that are supported: [LoadBalancer](https://pkg.go.dev/k8s.io/cloud-provider#LoadBalancer) and [InstancesV2](https://pkg.go.dev/k8s.io/cloud-provider#InstancesV2). The specific logic for each of these is contained in its own file: -* `InstancesV2`: [devices.go](./metal/devices.go) -* `LoadBalancer`: [loadbalancers.go](./metal/loadbalancers.go) +- `InstancesV2`: [devices.go](./metal/devices.go) +- `LoadBalancer`: [loadbalancers.go](./metal/loadbalancers.go) The other calls to `cloud` return `nil`, indicating they are not supported. @@ -112,10 +117,10 @@ To add support for additional elements of [cloudprovider.Interface](https://godo 1. Modify `newCloud()` in [cloud.go](./metal/cloud.go) to populate the `cloud struct`, using `newX()`, e.g. to support `Routes()`, populate with `newRoutes`. 1. Create a file to support the new functionality, with the name of the file matching the functionality, e.g. for `Routes`, name the file `routes.go`. 1. In the new file: - * Create a `type struct` with at least the `client` and `project` properties, as well as any others required, e.g. `type routes struct` - * Create a `func newX()` to create and populate the `struct` - * Add necessary `func` with the correct receiver to implement the new functionality, per [cloudprovider.Interface](https://godoc.org/k8s.io/cloud-provider#Interface) - * Create a test file for the new file, testing each functionality, e.g. `routes_test.go`. See the section below on testing. + - Create a `type struct` with at least the `client` and `project` properties, as well as any others required, e.g. `type routes struct` + - Create a `func newX()` to create and populate the `struct` + - Add necessary `func` with the correct receiver to implement the new functionality, per [cloudprovider.Interface](https://godoc.org/k8s.io/cloud-provider#Interface) + - Create a test file for the new file, testing each functionality, e.g. `routes_test.go`. See the section below on testing. ### Testing @@ -126,9 +131,9 @@ To simplify matters, the Equinix Metal CCM leverages [packet-api-server](https:/ to simulate a true Equinix Metal API. All of the tests leverage `testGetValidCloud()` from [cloud_test.go](./metal/cloud_test.go) to: -* launch a simulated Equinix Metal API server that will terminate at the end of tests -* create an instance of `cloud` that is configured to connect to the simulated API server -* create an instance of [store.Memory](https://godoc.org/github.com/packethost/packet-api-server/pkg/store#Memory) so you can manipulate the "backend data" that the API server returns +- launch a simulated Equinix Metal API server that will terminate at the end of tests +- create an instance of `cloud` that is configured to connect to the simulated API server +- create an instance of [store.Memory](https://godoc.org/github.com/packethost/packet-api-server/pkg/store#Memory) so you can manipulate the "backend data" that the API server returns To run any test: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 84599e2b..d2426869 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -12,7 +12,7 @@ issue open for the pull request you are creating, please create one. Frequently, pull requests may be merged or closed while the underlying issue being addressed is not fully addressed. Issues are a place to discuss the problem in need of a solution. Pull requests are a place to discuss an implementation of one -particular answer to that problem. A pull request may not address all (or any) +particular answer to that problem. A pull request may not address all (or any) of the problems expressed in the issue, so it is important to track these separately. @@ -24,7 +24,7 @@ All public functions and variables should include at least a short description of the functionality they provide. Comments should be formatted according to . -Documentation at will be +Documentation at will be generated from these comments. Although the Equinix Metal CCM is intended more as a standalone runtime container than @@ -70,11 +70,11 @@ It will be named and tagged `equinix/cloud-provider-equinix-metal:latest-${ARCH} You can override any of the above as follows: -* `BUILD_IMAGE`: name of the image, instead of the default `equinix/cloud-provider-equinix-metal` -* `BUILD_TAG`: base tag for the image, instead of the default `latest` -* `ARCH`: architecture to build for, and extension to tag -* `OS`: OS to build for, not included in the tag, defaults to `linux` -* `TAGGED_ARCH_IMAGE`: to replace the entire tag, defaults to `$(BUILD_IMAGE):$(BUILD_TAG)-$(ARCH)` +- `BUILD_IMAGE`: name of the image, instead of the default `equinix/cloud-provider-equinix-metal` +- `BUILD_TAG`: base tag for the image, instead of the default `latest` +- `ARCH`: architecture to build for, and extension to tag +- `OS`: OS to build for, not included in the tag, defaults to `linux` +- `TAGGED_ARCH_IMAGE`: to replace the entire tag, defaults to `$(BUILD_IMAGE):$(BUILD_TAG)-$(ARCH)` ### Automation (CI/CD) @@ -84,11 +84,13 @@ It is possible to test the github actions using your own fork of this repository you have github actions support enabled in your repository settings. If you want to test publishing container images to quay.io, you will need to set the following secrets: + - QUAY_ORG - QUAY_USERNAME - QUAY_PASSWORD If you want to test publishing container images to dockerhub, you will need to set the following secrets: + - DOCKER_ORG - DOCKER_USERNAME - DOCKER_PASSWORD diff --git a/Makefile b/Makefile index d92c7307..711bf2cb 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ SHELL=/bin/sh BINARY ?= cloud-provider-equinix-metal BUILD_IMAGE?=equinix/cloud-provider-equinix-metal BUILDER_IMAGE?=equinix/go-build -PACKAGE_NAME?=github.com/equinix/cloud-provider-equinix-metal +PACKAGE_NAME?=github.com/kubernetes-sigs/cloud-provider-equinix-metal GIT_VERSION?=$(shell git log -1 --format="%h") VERSION?=$(GIT_VERSION) RELEASE_TAG ?= $(shell git tag --points-at HEAD) diff --git a/README.md b/README.md index c6639313..c5709f21 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ # Kubernetes Cloud Controller Manager for Equinix Metal -[![GitHub release](https://img.shields.io/github/release/equinix/cloud-provider-equinix-metal/all.svg?style=flat-square)](https://github.com/equinix/cloud-provider-equinix-metal/releases) -[![Go Report Card](https://goreportcard.com/badge/github.com/equinix/cloud-provider-equinix-metal)](https://goreportcard.com/report/github.com/equinix/cloud-provider-equinix-metal) -![Continuous Integration](https://github.com/equinix/cloud-provider-equinix-metal/workflows/Continuous%20Integration/badge.svg) +[![GitHub release](https://img.shields.io/github/release/equinix/cloud-provider-equinix-metal/all.svg?style=flat-square)](https://github.com/kubernetes-sigs/cloud-provider-equinix-metal/releases) +[![Go Report Card](https://goreportcard.com/badge/github.com/kubernetes-sigs/cloud-provider-equinix-metal)](https://goreportcard.com/report/github.com/kubernetes-sigs/cloud-provider-equinix-metal) +![Continuous Integration](https://github.com/kubernetes-sigs/cloud-provider-equinix-metal/workflows/Continuous%20Integration/badge.svg) [![Docker Pulls](https://img.shields.io/docker/pulls/equinix/cloud-provider-equinix-metal.svg)](https://hub.docker.com/r/equinix/cloud-provider-equinix-metal/) [![Slack](https://slack.equinixmetal.com/badge.svg)](https://slack.equinixmetal.com/) [![Twitter Follow](https://img.shields.io/twitter/follow/equinixmetal.svg?style=social&label=Follow)](https://twitter.com/intent/follow?screen_name=equinixmetal&user_id=788180534543339520) @@ -180,7 +180,7 @@ Example: ``` RELEASE=v3.6.2 -kubectl apply -f https://github.com/equinix/cloud-provider-equinix-metal/releases/download/${RELEASE}/deployment.yaml +kubectl apply -f https://github.com/kubernetes-sigs/cloud-provider-equinix-metal/releases/download/${RELEASE}/deployment.yaml ``` The CCM uses multiple configuration options. See the [configuration][#Configuration] section for all of the options. @@ -233,7 +233,7 @@ This section lists each configuration option, and whether it can be set by each | Kubernetes Service annotation to set EIP metro | | `METAL_ANNOTATION_EIP_METRO` | `annotationEIPMetro` | `"metal.equinix.com/eip-metro"` | | Kubernetes Service annotation to set EIP facility | | `METAL_ANNOTATION_EIP_FACILITY` | `annotationEIPFacility` | `"metal.equinix.com/eip-facility"` | | Tag for control plane Elastic IP | | `METAL_EIP_TAG` | `eipTag` | No control plane Elastic IP | -| ID for control plane Equinix Metal Load Balancer | | `METAL_LOAD_BALANCER_ID` | `loadBalancerID` | No control plane Equinix Metal Load Balancer | +| ID for control plane Equinix Metal Load Balancer | | `METAL_LOAD_BALANCER_ID` | `loadBalancerID` | No control plane Equinix Metal Load Balancer | | Kubernetes API server port for Elastic IP | | `METAL_API_SERVER_PORT` | `apiServerPort` | Same as `kube-apiserver` on control plane nodes, same as `0` | | Filter for cluster nodes on which to enable BGP | | `METAL_BGP_NODE_SELECTOR` | `bgpNodeSelector` | All nodes | | Use host IP for Control Plane endpoint health checks | | `METAL_EIP_HEALTH_CHECK_USE_HOST_IP` | `eipHealthCheckUseHostIP` | false | @@ -340,7 +340,6 @@ The value of the loadbalancing configuration is `:///` where: For loadbalancing for Kubernetes `Service` of `type=LoadBalancer`, the following implementations are supported: - - [Equinix Metal Load Balancer](#EquinixMetalLoadBalancer) - [kube-vip](#kube-vip) - [MetalLB](#metallb) @@ -354,6 +353,7 @@ API calls to support a load balancer, and providing configuration for supported Equinix Metal Load Balancer (EMLB) is a beta service that is available to a limited number of Equinix Metal customers that provides managed layer 4 load balancers. When the EMLB option is enabled, for user-deployed Kubernetes `Service` of `type=LoadBalancer`, the Equinix Metal CCM: + - creates an Equinix Metal Load Balancer for the service - creates listener ports on the Equinix Metal Load Balancer for each port on the service - creates origin pools for each listener port that send traffic to the corresponding NodePorts in your cluster @@ -364,7 +364,7 @@ To enable EMLB, set the configuration `METAL_LOAD_BALANCER` or config `loadbalan emlb:// ``` -Where `` is the Equinix metro in which you want CCM to deploy your external load balancers. For example, to deploy your load balancers in Silicon Valley, you would set the configuration to `emlb://sv`. Note that EMLB is available in a limited number of Equinix metros (as of this writing, `sv`, `da`, and `ny`). +Where `` is the Equinix metro in which you want CCM to deploy your external load balancers. For example, to deploy your load balancers in Silicon Valley, you would set the configuration to `emlb://sv`. Note that EMLB is available in a limited number of Equinix metros (as of this writing, `sv`, `da`, and `ny`). ##### kube-vip @@ -384,7 +384,7 @@ To enable it, set the configuration `METAL_LOAD_BALANCER` or config `loadbalance kube-vip:// ``` -Directions on using configuring kube-vip in this method are available at the kube-vip [site]() +Directions on using configuring kube-vip in this method are available at the kube-vip [site]() If `kube-vip` management is enabled, then CCM does the following. @@ -601,14 +601,14 @@ You have several options for control plane load-balancing: #### Equinix Metal Load Balancer -If you have configured the CCM to use Equinix Metal Load Balancers (EMLB) for service load balancing, you can also choose to use EMLB for control plane load balancing. To enable control plane load balancing with EMLB: +If you have configured the CCM to use Equinix Metal Load Balancers (EMLB) for service load balancing, you can also choose to use EMLB for control plane load balancing. To enable control plane load balancing with EMLB: 1. Create a Load Balancer using the Equinix Metal API or Web UI 1. When starting the CCM - set the [configuration](#Configuration) for load balancing with EMLB, e.g. env var `METAL_LOAD_BALANCER=emlb://`, where `` is the metro in which you want the CCM to create your load balancers - set the [configuration](#Configuration) for the control plane EIP tag, e.g. env var `METAL_LOAD_BALANCER_ID=`, where `` is the ID of the Load Balancer you created earlier -When run with the correct configuration, on startup, CCM will automatically update your Load Balancer to send traffic to your control plane nodes. +When run with the correct configuration, on startup, CCM will automatically update your Load Balancer to send traffic to your control plane nodes. #### Elastic IP Load Balancer diff --git a/SUPPORT.md b/SUPPORT.md index ceaa1b2e..b569c3ac 100644 --- a/SUPPORT.md +++ b/SUPPORT.md @@ -1,17 +1,17 @@ # Support Please [open a GitHub Issue] stating any problems that you encounter using this -software. Be sure to leave a descriptive report of the problem, including the +software. Be sure to leave a descriptive report of the problem, including the environment you were running in and the expected behavior. Be careful not to include any sensitive information such as API Keys, IP addresses or their ranges, or any resource identifiers (UUID or ID) of your organizations, projects, or devices. As an open-source project, the priority, timing, or eventual resolution is not -guaranteed. Issues will be addressed based on priorities that may or may not +guaranteed. Issues will be addressed based on priorities that may or may not be reflected in Github or issue comments. For other forms of support, including our Slack community, visit . -[open a GitHub Issue]: https://github.com/equinix/cloud-provider-equinix-metal/issues/new +[open a GitHub Issue]: https://github.com/kubernetes-sigs/cloud-provider-equinix-metal/issues/new diff --git a/deploy/chart/Chart.yaml b/deploy/chart/Chart.yaml index 97a83ff8..e0d24dc7 100644 --- a/deploy/chart/Chart.yaml +++ b/deploy/chart/Chart.yaml @@ -1,10 +1,9 @@ apiVersion: v2 name: cloud-provider-equinix-metal -description: Kubernetes Cloud Provider for Equinix Metal +description: Kubernetes Cloud Provider for Equinix Metal type: application version: "0.1.0" appVersion: "main" home: https://metal.equinix.com sources: - - https://github.com/equinix/cloud-provider-equinix-metal - + - https://github.com/kubernetes-sigs/cloud-provider-equinix-metal diff --git a/go.mod b/go.mod index 936d94ac..8fc7db89 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/equinix/cloud-provider-equinix-metal +module github.com/kubernetes-sigs/cloud-provider-equinix-metal go 1.21 diff --git a/main.go b/main.go index bc35f403..e44b8c19 100644 --- a/main.go +++ b/main.go @@ -15,7 +15,7 @@ import ( _ "k8s.io/component-base/metrics/prometheus/version" // for version metric registration "k8s.io/klog/v2" - "github.com/equinix/cloud-provider-equinix-metal/metal" + "github.com/kubernetes-sigs/cloud-provider-equinix-metal/metal" ) func main() { diff --git a/metal/loadbalancers.go b/metal/loadbalancers.go index ce7aa434..6b339ee9 100644 --- a/metal/loadbalancers.go +++ b/metal/loadbalancers.go @@ -12,11 +12,11 @@ import ( "strconv" "strings" - "github.com/equinix/cloud-provider-equinix-metal/metal/loadbalancers" - "github.com/equinix/cloud-provider-equinix-metal/metal/loadbalancers/emlb" - "github.com/equinix/cloud-provider-equinix-metal/metal/loadbalancers/empty" - "github.com/equinix/cloud-provider-equinix-metal/metal/loadbalancers/kubevip" - "github.com/equinix/cloud-provider-equinix-metal/metal/loadbalancers/metallb" + "github.com/kubernetes-sigs/cloud-provider-equinix-metal/metal/loadbalancers" + "github.com/kubernetes-sigs/cloud-provider-equinix-metal/metal/loadbalancers/emlb" + "github.com/kubernetes-sigs/cloud-provider-equinix-metal/metal/loadbalancers/empty" + "github.com/kubernetes-sigs/cloud-provider-equinix-metal/metal/loadbalancers/kubevip" + "github.com/kubernetes-sigs/cloud-provider-equinix-metal/metal/loadbalancers/metallb" metal "github.com/equinix/equinix-sdk-go/services/metalv1" v1 "k8s.io/api/core/v1" diff --git a/metal/loadbalancers/empty/empty.go b/metal/loadbalancers/empty/empty.go index ccc83492..d896779c 100644 --- a/metal/loadbalancers/empty/empty.go +++ b/metal/loadbalancers/empty/empty.go @@ -4,7 +4,7 @@ package empty import ( "context" - "github.com/equinix/cloud-provider-equinix-metal/metal/loadbalancers" + "github.com/kubernetes-sigs/cloud-provider-equinix-metal/metal/loadbalancers" v1 "k8s.io/api/core/v1" "k8s.io/client-go/kubernetes" ) diff --git a/metal/loadbalancers/kubevip/kubevip.go b/metal/loadbalancers/kubevip/kubevip.go index 252f2c40..f8a7d8b1 100644 --- a/metal/loadbalancers/kubevip/kubevip.go +++ b/metal/loadbalancers/kubevip/kubevip.go @@ -4,7 +4,7 @@ package kubevip import ( "context" - "github.com/equinix/cloud-provider-equinix-metal/metal/loadbalancers" + "github.com/kubernetes-sigs/cloud-provider-equinix-metal/metal/loadbalancers" v1 "k8s.io/api/core/v1" "k8s.io/client-go/kubernetes" ) diff --git a/metal/loadbalancers/metallb/metallb.go b/metal/loadbalancers/metallb/metallb.go index eb03bb64..b19fd54c 100644 --- a/metal/loadbalancers/metallb/metallb.go +++ b/metal/loadbalancers/metallb/metallb.go @@ -7,7 +7,7 @@ import ( "strconv" "strings" - "github.com/equinix/cloud-provider-equinix-metal/metal/loadbalancers" + "github.com/kubernetes-sigs/cloud-provider-equinix-metal/metal/loadbalancers" metallbv1beta1 "go.universe.tf/metallb/api/v1beta1" v1 "k8s.io/api/core/v1" "k8s.io/client-go/kubernetes"