diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 3ad7673..0b3212e 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -2,6 +2,7 @@ "name": "k8s-gateway-api.dev", "image": "ghcr.io/linkerd/dev-proxy:v11", "extensions": [ + "DavidAnson.vscode-markdownlint", "NathanRidley.autotrim", "rust-lang.rust-analyzer", "skellock.just", diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml new file mode 100644 index 0000000..a13c761 --- /dev/null +++ b/.github/workflows/integration.yml @@ -0,0 +1,56 @@ +name: integration + +on: + pull_request: + paths: + - Cargo.toml + - '**/*.rs' + - .github/workflows/integration.yml + +permissions: + contents: read + +env: + CARGO_INCREMENTAL: 0 + CARGO_NET_RETRY: 10 + RUSTUP_MAX_RETRIES: 10 + RUST_VERSION: 1.60.0 + K3D_VERSION: v5.4.1 + +jobs: + test: + strategy: + matrix: + k8s: + - v1.21 + - v1.23 + timeout-minutes: 5 + runs-on: ubuntu-latest + steps: + - name: Install rust + run: | + rm -rf $HOME/.cargo + curl --proto =https --tlsv1.3 -fLsSv https://sh.rustup.rs | sh -s -- -y --default-toolchain "${RUST_VERSION}" + source $HOME/.cargo/env + echo "PATH=$PATH" >> $GITHUB_ENV + cargo version + # Setup a cluster + - run: curl --proto =https --tlsv1.3 -fLsSv https://raw.githubusercontent.com/k3d-io/k3d/${K3D_VERSION}/install.sh | bash + - run: k3d --version + - run: k3d cluster create --no-lb --k3s-arg '--no-deploy=local-storage,traefik,servicelb,metrics-server@server:*' --image +${{ matrix.k8s }} + - run: kubectl version + # Install CRDs + - uses: actions/checkout@dcd71f646680f2efd8db4afa5ad64fdcba30e748 + with: + repository: kubernetes-sigs/gateway-api + ref: 3f4b981dd6669f67398d753a6f278b241d669953 # 0.5.0-dev + path: gateway-api + - run: kubectl apply -k gateway-api/config/crd/experimental/ + # Setup just + - uses: extractions/setup-just@aa5d15c144db4585980a44ebfdd2cf337c4f14cb + - uses: actions/checkout@dcd71f646680f2efd8db4afa5ad64fdcba30e748 + # Run tests + - run: just fetch + - run: just test-build --package=integration + - run: just test --package=integration + diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 25b9282..b9cfb8c 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -15,7 +15,6 @@ env: CARGO_NET_RETRY: 10 RUSTUP_MAX_RETRIES: 10 RUST_VERSION: 1.60.0 - K3D_VERSION: v5.4.1 jobs: fmt: @@ -41,6 +40,8 @@ jobs: - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b - run: just fetch - run: just clippy + - run: just clippy --all-features + - run: just clippy --package=integration docs: timeout-minutes: 10 @@ -53,36 +54,3 @@ jobs: - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b - run: just fetch - run: just docs - - test: - timeout-minutes: 5 - runs-on: ubuntu-latest - steps: - - name: Install rust - run: | - rm -rf $HOME/.cargo - curl --proto =https --tlsv1.3 -fLsSv https://sh.rustup.rs | sh -s -- -y --default-toolchain "${RUST_VERSION}" - source $HOME/.cargo/env - echo "PATH=$PATH" >> $GITHUB_ENV - cargo version - # Setup a cluster - - run: curl --proto =https --tlsv1.3 -fLsSv https://raw.githubusercontent.com/k3d-io/k3d/${K3D_VERSION}/install.sh | bash - - run: k3d --version - - run: k3d cluster create --no-lb --k3s-arg '--no-deploy=local-storage,traefik,servicelb,metrics-server@server:*' - - run: kubectl version - # Install CRDs - - uses: actions/checkout@dcd71f646680f2efd8db4afa5ad64fdcba30e748 - with: - repository: kubernetes-sigs/gateway-api - ref: v0.4.3 - path: gateway-api - - run: kubectl apply -f gateway-api/config/crd/v1alpha2/ - # Setup just - - uses: extractions/setup-just@aa5d15c144db4585980a44ebfdd2cf337c4f14cb - - uses: actions/checkout@dcd71f646680f2efd8db4afa5ad64fdcba30e748 - # Run tests - - run: just fetch - - run: just test-build - - run: just test - - diff --git a/.github/workflows/markdown.yml b/.github/workflows/markdown.yml new file mode 100644 index 0000000..e40a748 --- /dev/null +++ b/.github/workflows/markdown.yml @@ -0,0 +1,22 @@ +name: markdown + +permissions: + contents: read + +on: + pull_request: + paths: + - '**/*.md' + - .github/workflows/markdown.yml + +jobs: + markdownlint: + timeout-minutes: 5 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b + - uses: DavidAnson/markdownlint-cli2-action@744f913a124058ee903768d3adb92a4847e5d132 + with: + globs: | + **/*.md + !target/** diff --git a/Cargo.toml b/Cargo.toml index ea5ea97..3490078 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ members = [ [package] name = "k8s-gateway-api" -version = "0.4.0" +version = "0.5.0" edition = "2021" license = "Apache-2.0" repository = "https://github.com/linkerd/k8s-gateway-api" @@ -14,6 +14,10 @@ rust-version = "1.60" keywords = ["kubernetes", "gateway"] description = "Rust bindings for the Kubenetes Gateway API" +[features] +default = [] +experimental = [] + [dependencies] kube = { version = "0.73", default-features = false, features = ["derive"] } k8s-openapi = { version = "0.15", features = ["schemars"] } @@ -22,10 +26,11 @@ serde = { version = "1", features = ["derive"] } serde_json = "1" [dev-dependencies] -k8s-openapi = { version = "0.15", default-features = false, features = ["v1_24"] } +k8s-openapi = { version = "0.15", default-features = false, features = ["v1_21"] } [package.metadata.docs.rs] rustdoc-args = ["--cfg", "docsrs"] features = [ + "experimental", "k8s-openapi/v1_24", ] diff --git a/README.md b/README.md index a332329..9d4dd03 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,30 @@ # k8s-gateway-api -(Unofficial) Rust bindings for the [Kubernetes Gateway API][ref]. +(Unofficial) Rust bindings for the [Kubernetes Gateway API][site]. -Based on . +Based on [gateway-api-v0.5.0-dev]. [![Crates.io][crate-badge]][crate-url] [![Documentation][docs-badge]][docs-url] [![License][lic-badge]](LICENSE) -[crate-badge]: https://img.shields.io/crates/v/k8s-gateway-api.svg -[crate-url]: https://crates.io/crates/k8s-gateway-api -[docs-badge]: https://docs.rs/k8s-gateway-api/badge.svg -[docs-url]: https://docs.rs/k8s-gateway-api -[docs-url]: https://img.shields.io/crates/l/k8s-gateway-api -[lic-badge]: https://img.shields.io/crates/l/k8s-gateway-api - ## Status This crate is experimental. -It defines all of the v1alpha2 Gateway API types with documentation. +It defines all of the *v1beta1* Gateway API types with documentation, as well as +the *v1alpha2* types when the `experimental` feature is enabled. ### TODO * Express validation constraints * Rustify/Linkify documentation -* Support Linkerd-specific extensions (via feature flag). -[ref]: https://gateway-api.sigs.k8s.io/ +[gateway-api-v0.5.0-dev]: https://github.com/kubernetes-sigs/gateway-api/tree/4f86f0bd65173b04dadb558f63fbbd53330736d2 +[site]: https://gateway-api.sigs.k8s.io/ +[crate-badge]: https://img.shields.io/crates/v/k8s-gateway-api.svg +[crate-url]: https://crates.io/crates/k8s-gateway-api +[docs-badge]: https://docs.rs/k8s-gateway-api/badge.svg +[docs-url]: https://docs.rs/k8s-gateway-api +[docs-url]: https://img.shields.io/crates/l/k8s-gateway-api +[lic-badge]: https://img.shields.io/crates/l/k8s-gateway-api diff --git a/integration/Cargo.toml b/integration/Cargo.toml index f968b04..4cf0542 100644 --- a/integration/Cargo.toml +++ b/integration/Cargo.toml @@ -6,6 +6,7 @@ license = "Apache-2.0" publish = false [dev-dependencies] +k8s-openapi = { version = "0.15", features = ["v1_21"] } tokio = { version = "1", features = ["macros", "rt"] } tracing = "0.1" k8s-gateway-api = { path = ".." } diff --git a/integration/tests/gateway.rs b/integration/tests/gateway.rs index 7124cdb..672cfed 100644 --- a/integration/tests/gateway.rs +++ b/integration/tests/gateway.rs @@ -1,4 +1,4 @@ -use k8s_gateway_api::v1alpha2::{ +use k8s_gateway_api::{ AllowedRoutes, Gateway, GatewaySpec, GatewayTlsConfig, Listener, RouteGroupKind, SecretObjectReference, }; diff --git a/integration/tests/httproute.rs b/integration/tests/httproute.rs index 9d0487e..6980844 100644 --- a/integration/tests/httproute.rs +++ b/integration/tests/httproute.rs @@ -1,4 +1,4 @@ -use k8s_gateway_api::v1alpha2::{ +use k8s_gateway_api::{ BackendRef, HttpBackendRef, HttpHeaderMatch, HttpRoute, HttpRouteMatch, HttpRouteRule, HttpRouteSpec, }; diff --git a/src/v1alpha2/policy.rs b/src/exp/policy.rs similarity index 98% rename from src/v1alpha2/policy.rs rename to src/exp/policy.rs index b4a5134..63efc71 100644 --- a/src/v1alpha2/policy.rs +++ b/src/exp/policy.rs @@ -1,4 +1,4 @@ -use super::*; +use crate::*; /// PolicyTargetReference identifies an API object to apply policy to. This /// should be used as part of Policy resources that can target Gateway API diff --git a/src/v1alpha2/referencepolicy.rs b/src/exp/referencegrant.rs similarity index 79% rename from src/v1alpha2/referencepolicy.rs rename to src/exp/referencegrant.rs index f6aa675..40b280d 100644 --- a/src/v1alpha2/referencepolicy.rs +++ b/src/exp/referencegrant.rs @@ -1,26 +1,24 @@ -use super::*; +use crate::*; -/// ReferencePolicy identifies kinds of resources in other namespaces that are +/// ReferenceGrant identifies kinds of resources in other namespaces that are /// trusted to reference the specified kinds of resources in the same namespace /// as the policy. /// -/// Each ReferencePolicy can be used to represent a unique trust relationship. +/// Each ReferenceGrant can be used to represent a unique trust relationship. /// Additional Reference Policies can be used to add to the set of trusted /// sources of inbound references for the namespace they are defined within. /// -/// All cross-namespace references in Gateway API (with the exception of cross-namespace -/// Gateway-route attachment) require a ReferencePolicy. -/// -/// Support: Core +/// All cross-namespace references in Gateway API (with the exception of +/// cross-namespace Gateway-route attachment) require a ReferenceGrant. #[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)] -pub struct ReferencePolicy { +pub struct ReferenceGrant { /// From describes the trusted namespaces and kinds that can reference the /// resources described in "To". Each entry in this list must be considered /// to be an additional place that references can be valid from, or to put /// this another way, entries must be combined using OR. /// - /// Support: Cor - pub from: Vec, + /// Support: Core + pub from: Vec, /// To describes the resources that may be referenced by the resources /// described in "From". Each entry in this list must be considered to be an @@ -28,12 +26,12 @@ pub struct ReferencePolicy { /// way, entries must be combined using OR. /// /// Support: Core - pub to: Vec, + pub to: Vec, } -/// ReferencePolicyFrom describes trusted namespaces and kinds. +/// ReferenceGrantFrom describes trusted namespaces and kinds. #[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)] -pub struct ReferencePolicyFrom { +pub struct ReferenceGrantFrom { /// Group is the group of the referent. /// /// When empty, the Kubernetes core API group is inferred. @@ -57,10 +55,10 @@ pub struct ReferencePolicyFrom { pub namespace: Namespace, } -/// ReferencePolicyTo describes what Kinds are allowed as targets of the +/// ReferenceGrantTo describes what Kinds are allowed as targets of the /// references. #[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)] -pub struct ReferencePolicyTo { +pub struct ReferenceGrantTo { /// Group is the group of the referent. /// When empty, the Kubernetes core API group is inferred. /// diff --git a/src/v1alpha2/tcproute.rs b/src/exp/tcproute.rs similarity index 99% rename from src/v1alpha2/tcproute.rs rename to src/exp/tcproute.rs index b5d94e9..05f383d 100644 --- a/src/v1alpha2/tcproute.rs +++ b/src/exp/tcproute.rs @@ -1,4 +1,4 @@ -use super::*; +use crate::*; /// TCPRoute provides a way to route TCP requests. When combined with a Gateway /// listener, it can be used to forward connections on the port specified by the diff --git a/src/v1alpha2/tlsroute.rs b/src/exp/tlsroute.rs similarity index 98% rename from src/v1alpha2/tlsroute.rs rename to src/exp/tlsroute.rs index 605da50..88eec3c 100644 --- a/src/v1alpha2/tlsroute.rs +++ b/src/exp/tlsroute.rs @@ -1,4 +1,4 @@ -use super::*; +use crate::*; /// The TLSRoute resource is similar to TCPRoute, but can be configured to match /// against TLS-specific metadata. This allows more flexibility in matching @@ -78,7 +78,7 @@ pub struct TlsRouteRule { /// Service with no endpoints), the rule performs no forwarding; if no /// filters are specified that would result in a response being sent, the /// underlying implementation must actively reject request attempts to this - /// backend, by rejecting the connection or returning a 404 status code. + /// backend, by rejecting the connection or returning a 500 status code. /// Request rejections must respect weight; if an invalid backend is /// requested to have 80% of requests, then 80% of requests must be rejected /// instead. diff --git a/src/v1alpha2/udproute.rs b/src/exp/udproute.rs similarity index 98% rename from src/v1alpha2/udproute.rs rename to src/exp/udproute.rs index 5bc8cf5..c62e3c8 100644 --- a/src/v1alpha2/udproute.rs +++ b/src/exp/udproute.rs @@ -1,4 +1,4 @@ -use super::*; +use crate::*; #[derive( Clone, Debug, kube::CustomResource, serde::Deserialize, serde::Serialize, schemars::JsonSchema, diff --git a/src/v1alpha2/gateway.rs b/src/gateway.rs similarity index 99% rename from src/v1alpha2/gateway.rs rename to src/gateway.rs index ef81674..4fc764e 100644 --- a/src/v1alpha2/gateway.rs +++ b/src/gateway.rs @@ -1,4 +1,5 @@ -use super::*; +use crate::*; +use k8s_openapi::apimachinery::pkg::apis::meta::v1 as metav1; use std::collections::BTreeMap; /// Gateway represents an instance of a service-traffic handling infrastructure @@ -8,7 +9,7 @@ use std::collections::BTreeMap; )] #[kube( group = "gateway.networking.k8s.io", - version = "v1alpha2", + version = "v1beta1", kind = "Gateway", status = "GatewayStatus", namespaced @@ -49,7 +50,7 @@ pub struct GatewaySpec { /// provided in the incoming client request MUST be matched to a Listener to /// find the correct set of Routes. The incoming hostname MUST be matched /// using the Hostname field for each Listener in order of most to least - /// specific. That is, exact matches must be processed before wildcard + /// specific. That is, exact matches must be processed before wildcard /// matches. /// /// If this field specifies multiple Listeners that have the same Port value diff --git a/src/v1alpha2/gatewayclass.rs b/src/gatewayclass.rs similarity index 97% rename from src/v1alpha2/gatewayclass.rs rename to src/gatewayclass.rs index 9a7c240..ed1f75e 100644 --- a/src/v1alpha2/gatewayclass.rs +++ b/src/gatewayclass.rs @@ -1,4 +1,5 @@ -use super::*; +use crate::*; +use k8s_openapi::apimachinery::pkg::apis::meta::v1 as metav1; // GatewayClass describes a class of Gateways available to the user for creating // Gateway resources. @@ -22,7 +23,7 @@ use super::*; )] #[kube( group = "gateway.networking.k8s.io", - version = "v1alpha2", + version = "v1beta1", kind = "GatewayClass", status = "GatewayClassStatus" )] diff --git a/src/v1alpha2/httproute.rs b/src/httproute.rs similarity index 98% rename from src/v1alpha2/httproute.rs rename to src/httproute.rs index 4a526b4..d176b44 100644 --- a/src/v1alpha2/httproute.rs +++ b/src/httproute.rs @@ -1,4 +1,4 @@ -use super::*; +use crate::*; /// HTTPRoute provides a way to route HTTP requests. This includes the /// capability to match requests by hostname, path, header, or query param. @@ -15,7 +15,7 @@ use super::*; )] #[kube( group = "gateway.networking.k8s.io", - version = "v1alpha2", + version = "v1beta1", kind = "HTTPRoute", struct = "HttpRoute", status = "HttpRouteStatus", @@ -150,8 +150,8 @@ pub struct HttpRouteRule { /// BackendRefs defines the backend(s) where matching requests should be /// sent. /// - /// A 404 status code MUST be returned if there are no BackendRefs or filters - /// specified that would result in a response being sent. + /// A 500 status code MUST be returned if there are no BackendRefs or + /// filters specified that would result in a response being sent. /// /// A BackendRef is considered invalid when it refers to: /// @@ -160,11 +160,11 @@ pub struct HttpRouteRule { /// * a resource in another namespace when the reference has not been /// explicitly allowed by a ReferencePolicy (or equivalent concept). /// - /// When a BackendRef is invalid, 404 status codes MUST be returned for + /// When a BackendRef is invalid, 500 status codes MUST be returned for /// requests that would have otherwise been routed to an invalid backend. If /// multiple backends are specified, and some are invalid, the proportion of /// requests that would otherwise have been routed to an invalid backend - /// MUST receive a 404 status code. + /// MUST receive a 500 status code. /// /// When a BackendRef refers to a Service that has no ready endpoints, it is /// recommended to return a 503 status code. diff --git a/src/lib.rs b/src/lib.rs index 2535ad0..80d3d8b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,5 +8,24 @@ // TODO(ver): We should deny missing_docs, but this doesn't play with // CustomResource derivations. -/// The v1alpha2 API version. -pub mod v1alpha2; +mod gateway; +mod gatewayclass; +mod httproute; +mod object_reference; +mod shared; + +pub use self::{gateway::*, gatewayclass::*, httproute::*, object_reference::*, shared::*}; + +#[cfg(feature = "experimental")] +mod exp { + mod policy; + mod referencegrant; + mod tcproute; + mod tlsroute; + mod udproute; + + pub use self::{policy::*, referencegrant::*, tcproute::*, tlsroute::*, udproute::*}; +} + +#[cfg(feature = "experimental")] +pub use self::exp::*; diff --git a/src/v1alpha2/object_reference.rs b/src/object_reference.rs similarity index 99% rename from src/v1alpha2/object_reference.rs rename to src/object_reference.rs index 0bdf3fd..22ac581 100644 --- a/src/v1alpha2/object_reference.rs +++ b/src/object_reference.rs @@ -1,4 +1,4 @@ -use super::*; +use crate::*; /// LocalObjectReference identifies an API object within the namespace of the /// referrer. diff --git a/src/v1alpha2/shared.rs b/src/shared.rs similarity index 99% rename from src/v1alpha2/shared.rs rename to src/shared.rs index 5495721..60ee14e 100644 --- a/src/v1alpha2/shared.rs +++ b/src/shared.rs @@ -1,4 +1,4 @@ -use super::*; +use k8s_openapi::apimachinery::pkg::apis::meta::v1 as metav1; /// ParentReference identifies an API object (usually a Gateway) that can be considered /// a parent of this resource (usually a route). The only kind of parent resource diff --git a/src/v1alpha2.rs b/src/v1alpha2.rs deleted file mode 100644 index 7502fec..0000000 --- a/src/v1alpha2.rs +++ /dev/null @@ -1,16 +0,0 @@ -use k8s_openapi::apimachinery::pkg::apis::meta::v1 as metav1; - -mod gateway; -mod gatewayclass; -mod httproute; -mod object_reference; -mod policy; -mod referencepolicy; -mod shared; -mod tcproute; -mod tlsroute; - -pub use self::{ - gateway::*, gatewayclass::*, httproute::*, object_reference::*, policy::*, referencepolicy::*, - shared::*, tcproute::*, tlsroute::*, -};