GEP-2722: Goals and UX for gwctl

  • Issue: #2722
  • Status: Memorandum

TLDR

TLDR: This GEP proposes gwctl, a new command line tool designed to streamline the experience of working with Gateway API resources. It offers a familiar kubectl-like interface for viewing resources while providing more detailed and informative output that is specifically focused on the Gateway API. For advanced filtering and other in-depth features, gwctl can be effectively used alongside kubectl.

Motivations

  • Limited kubectl customizability for CRDs:
    • kubectl’s customization capabilities for CRDs (through additionalPrinterColumns) is constrained, limiting the ability to create optimal views for Gateway API resources.
  • Complex policy attachment management:
    • As described in GEP-713, policies present a valuable mechanism for expanding the capabilities of Gateway API resources. However, discoverability poses a challenge due to the absence of a clear connection between resources and their associated policies. There have been growing questions around suitability of policies as a means to provide extensions.
  • Challenging multi-resource model navigation:
    • Comprehending the relationships between multiple Gateway API resources can be challenging within kubectl.

Goals

  • Greater control over output formatting and presentation:
    • Offer greater control over output formatting and presentation, enhancing visibility and understanding of Gateway API resources.
  • Improved policy discoverability, increasing adoption and usability:
    • Make policies easily discoverable, aiding in the adoption and fostering broader acceptance of policies as an extension mechanism.
  • Simplified multi-resource model navigation:
    • Facilitate navigation of the multi-resource model by making connections between Gateway API resources explicit, aiding in configuration, troubleshooting, and issue identification.
  • Proactive error detection and reporting:
    • Leverage native understanding of resource relationships to proactively detect and report on potential configuration errors, further simplifying issue identification and resolution. This would complement the ability of users to readily pinpoint configuration problems themselves.
  • Provide incentive for policy implementations that are consistent across cloud providers:
    • Encourage the adoption of consistent policy implementations across different Gateway API providers, promoting interoperability and predictability.

Commands Specification

Milestone 1

Supported Commands:

  • get: Retrieves information about specified resources without including additional information from related resources.
  • describe: Provides detailed information about specified resources, including augmented information from related resources.

Supported Resources:

  • gatewayclass
  • gateways
  • httproutes
  • namespaces
  • backends (not a native k8s resource)
  • policycrds (not a native k8s resource)
  • policies (not a native k8s resource)

Filtering Options:

  • -n Namespace: Filters resources by namespace. Applicable to all resources except cluster-scoped resources.
  • -l Labels: Filters resources by labels. Applicable to all resources.
  • -A All Namespaces: Fetches resources across all namespaces (redundant for cluster-scoped resources).
  • -t Target Resource: Filters policies based on the target resource type they apply to. Applicable only to the policies resource.
    • Syntax: -t <key1>=<value1>,<key2>=<value2>,...
    • Supported keys:
      • kind: Resource kind (e.g., “httproute”, “gateway”)
      • namespace: Resource namespace
      • name: Resource name
      • group: Resource API group

Output Formats:

  • describe: Fixed format, not customizable. Shows comprehensive resource information with details from related resources.

  • get:

    • One-line format (default): Displays basic resource information in a single line.
    • YAML format (-o yaml): Presents resource information in the YAML data format.
    • JSON format (-o json): Presents resource information in the JSON data format.
    • Wide format (-o wide): Includes additional columns beyond those displayed in the one-line format.

Output columns while using get

ResourceOutput ColumnsDescriptionVisibility (Defaults to always unless specified otherwise)
gatewayclassNAMEName of the GatewayClass
CONTROLLERController managing the GatewayClass
ACCEPTEDWhether the GatewayClass is accepted by the controller
AGEAge of the GatewayClass
GATEWAYSCount of Gateways using this GatewayClass-o wide
DESCRIPTIONDescription from the GatewayClass-o wide
gatewayNAMEName of the Gateway
CLASSClass of the Gateway
ADDRESSESAddresses of the Gateway (displayed using + n more)
PORTSPorts exposed by the Gateway
PROGRAMMEDWhether the Gateway is programmed
AGEAge of the Gateway
POLICIESCount of policies affecting this Gateway-o wide
HTTPROUTESCount of HTTPRoutes that are attached to this Gateway-o wide
httprouteNAMESPACENamespace of the HTTPRoute
NAMEName of the HTTPRoute
HOSTNAMESHostnames associated with the HTTPRoute
PARENT REFSCount of parent references of the HTTPRoute (e.g., Gateways)
AGEAge of the HTTPRoute
POLICIESCount of policies affecting this HTTPRoute-o wide
namespaceNAMEName of the namespace
STATUSStatus of the namespace
AGEAge of the namespace
POLICIESCount of policies affecting this Namespace-o wide
backendNAMEName of the backend
TYPEType of the backend (currently only supports Services)
REFERRED BY ROUTESHTTPRoutes that refer to the backend (displayed using + n more)
AGEAge of the backend
POLICIESCount of policies affecting this Backend-o wide
policycrdNAMEName of the Policy CRD in the form <kind.group>
POLICY TYPEType of policy defined by the CRD (Inherited or Direct)
SCOPEScope of the policy (Namespaced or Cluster)
POLICIES COUNTCount of policy resources of this particular type.-o wide
AGEAge of the Policy CRD
policyNAMEName of the policy
KINDThe kind of policy in the form <kind.group>
TARGET NAMEName of the resource the policy applies to
TARGET KINDThe kind of target resource in the form
POLICY TYPEType of policy (Inherited or Direct)
AGEAge of the Policy CRD

Additional Notes:

  • The behavior of get and describe commands is similar to kubectl, with get focusing on concise resource information and describe providing comprehensive details.
  • backends represent resources that can be attached as backends to HTTPRoutes (currently limited to k8s services).
  • policycrds and policies are not native k8s resources but represent subsets of CRDs and custom resource objects related to policies. (policycrds are identified by PolicyLabelKey)

Examples of commands that should be supported:

  • gwctl get gateways -n foo (Lists basic information about Gateways in the “foo” namespace)
  • gwctl get httproutes -l version=v1,app=myapp (Lists basic information about HTTPRoutes with the labels “version=v1” and “app=myapp”)
  • gwctl get gateways -n foo -o yaml (Shows detailed Gateway information in YAML format within the “foo” namespace)
  • gwctl get httproutes -l version=v1,app=myapp -o json (Shows detailed HTTPRoute information in JSON format with specified labels)
  • gwctl describe gateways my-gateway (Provides comprehensive details about the “my-gateway” Gateway, including information from related resources)
  • gwctl describe policies my-policy (Shows detailed information about the “my-policy” policy, encompassing data from relevant any related resources when applicable)
  • gwctl get policies -t kind=httproute (Lists basic information about policies that apply to HTTPRoutes)

Distribution

To ensure gwctl is widely accessible and easy to adopt, the following distribution mechanisms will be provided:

  • Prebuilt Binaries: Prebuilt binaries for various platforms (Linux, macOS, Windows) will be made available for download. Tooling like GoReleaser can be used to streamline some of the build processes. Binaries will be offered in two variants:
    • gwctl for standalone use.
    • kubectl-gw for use as a kubectl plugin (kubectl gw).
  • Kubectl Plugin Integration: gwctl will be integrated with Krew, the kubectl plugin manager. This should immensely help with improving discoverability of the plugin, allowing easier installation, and handling automatic updates for the user.
  • Versioning: gwctl versions will be aligned with Gateway API releases (for the time when gwctl is developed within the same repository as Gateway API)
    • As gwctl matures, the need for maintaining it within the primary Gateway API repository will be reassessed. Factors such as a potential divergence in release cadence, independent contributor growth or the desire to reduce the triage workload for Gateway API maintainers could motivate a move to a separate repository.

Future Milestones

  • Each output of describe will include an extra Analysis field. This field will display any errors or other analysis information associated with the resource.
  • Investigate the feasibility and any advantages of using Graphviz or webview for visualizing data and presenting information in a visually appealing manner.
  • Evaluate how gwctl can be extended to support Mesh use cases

References

Sample outputs

The example outputs provided below serve as a guideline for the implementation, outlining the range of values that may be presented:

  • gwctl get gatewayclass -o wide

    1. NAME CONTROLLER ACCEPTED AGE DESCRIPTION Gateways
    2. bar-com-internal-gateway-class bar.baz/internal-gateway-class True 100d Internal Load Balancer 10
    3. foo-com-external-gateway-class foo.com/external-gateway-class True 365d External Load Balancer 25
  • gwctl get gateway -o wide

    1. NAME CLASS ADDRESSES PORTS PROGRAMMED AGE POLICIES HTTPROUTES
    2. demo-gateway-2 external-class 10.0.0.1 80 True 20d 10 5
    3. abc-gateway-12345 internal-class 192.168.100.5 443,8080 False 5d 2 1
    4. random-gateway regional-internal-class 10.11.12.13 8443 Unknown 3s 3 5
  • gwctl get httproute -o wide

    1. NAMESPACE NAME HOSTNAMES PARENT REFS AGE POLICIES
    2. default foo-httproute-1 example.com,example2.com + 1 more ns2/demo-gateway-2 5m 2
    3. default qmn-httproute-100 example.com demo-gateway-1 5m 1
    4. ns1 bar-route-21 foo.com,bar.com + 5 more default/demo-gateway-200 5m 3
    5. ns2 bax-httproute-18777 None ns1/demo-gateway-345 5m 4
  • gwctl get namespace -o wide

    1. NAME STATUS AGE POLICIES
    2. default Active 46d 3
    3. kube-system Active 46d 5
  • gwctl get backend -o wide

    1. NAME TYPE REFERRED BY ROUTES AGE POLICIES
    2. foo-svc Service foo-httproute-1,abc-httproute-33 + 4 more 45m 5
    3. bar-baz-svc Service bar-httproute 11d 1
  • gwctl get policycrds -o wide

    1. NAME POLICY TYPE SCOPE POLICIES COUNT AGE
    2. healthcheckpolicies.foo.com Direct Namespaced 1 5d
    3. retryonpolicies.foo.com Direct Namespaced 2 4d
    4. timeoutpolicies.bar.com Inherited Cluster 1 10m
    5. tlsminimumversionpolicies.baz.com Direct Namespaced 3 45s
  • gwctl get policies -o wide

    1. NAME KIND TARGET NAME TARGET KIND POLICY TYPE AGE
    2. demo-timeout-policy-on-gatewayclass TimeoutPolicy.foo.com foo-com-external-gateway-class GatewayClass Inherited 10d
    3. demo-timeout-policy-on-namespace TimeoutPolicy.foo.com default Namespace Inherited 10d
    4. demo-health-check-1 HealthCheckPolicy.bar.com demo-gateway-1 Gateway Direct 10d
    5. demo-retry-policy-1 RetryOnPolicy.baz.com demo-gateway-1 Gateway Direct 10d
    6. demo-retry-policy-2 RetryOnPolicy.baz.com demo-httproute-2 HTTPRoute Direct 10d
    7. demo-tls-min-version-policy-1 TLSMinimumVersionPolicy.foobar.com demo-gateway-3 Gateway Direct 10d
    8. demo-tls-min-version-policy-2 TLSMinimumVersionPolicy.foobar.com demo-gateway-4 Gateway Direct 10d
  • gwctl describe gateway demo-gateway

    1. Name: demo-gateway
    2. Namespace: default
    3. Labels: <none>
    4. Annotations:
    5. annotation.foo: value1
    6. annotation.bar.baz: abcdefghijkl
    7. API Version: gateway.networking.k8s.io/v1beta1
    8. Kind: Gateway
    9. Metadata:
    10. creationTimestamp: "2023-12-01T18:29:41Z"
    11. finalizers:
    12. - gateway.finalizer.networking.io
    13. generation: 4
    14. resourceVersion: "310164667"
    15. uid: ed046878-f659-4908-b80f-b88c9617ba8a
    16. Spec:
    17. gatewayClassName: l7-global-external-managed
    18. listeners:
    19. - allowedRoutes:
    20. namespaces:
    21. from: Same
    22. name: http
    23. port: 80
    24. protocol: HTTP
    25. Status:
    26. addresses:
    27. - type: IPAddress
    28. value: 10.0.0.1
    29. conditions:
    30. - lastTransitionTime: "2023-12-01T18:49:25Z"
    31. message: ""
    32. observedGeneration: 3
    33. reason: Programmed
    34. status: "True"
    35. type: Programmed
    36. listeners:
    37. - attachedRoutes: 1
    38. conditions:
    39. - lastTransitionTime: "2023-12-01T18:49:25Z"
    40. message: Some message
    41. observedGeneration: 3
    42. reason: Ready
    43. status: "True"
    44. type: Ready
    45. name: http
    46. supportedKinds:
    47. - group: gateway.networking.k8s.io
    48. kind: HTTPRoute
    49. AttachedRoutes:
    50. Kind Name Namespace
    51. ---- ---- ---------
    52. HTTPRoute demo-health-check-1 default
    53. TCPRoute demo-retry-policy-1 default
    54. DirectlyAttachedPolicies:
    55. TYPE NAME
    56. ---- ----
    57. TimeoutPolicy.foo.com demo-timeout-policy-on-gatewayclass
    58. RetryOnPolicy.baz.com demo-retry-policy-1
    59. InheritedPolicies:
    60. TYPE NAME TARGET KIND TARGET NAME
    61. ---- ---- ----------- -----------
    62. TimeoutPolicy.foo.com demo-timeout-policy-on-gatewayclass GatewayClass abc-gatewayclass
    63. EffectivePolicies:
    64. HealthCheckPolicy.foo.com:
    65. sampleParentField:
    66. sampleField: hello
    67. RetryOnPolicy.foo.com:
    68. sampleParentField:
    69. sampleField: namaste
    70. TimeoutPolicy.bar.com:
    71. timeout1: parent
    72. timeout2: child
    73. timeout3: parent
    74. timeout4: child
    75. Events:
    76. Type Reason Age From Message
    77. ---- ------ ---- ---- -------
    78. Normal SYNC 2m12s (x46 over 138m) sc-gateway-controller SYNC on default/demo-gateway was a success
  • gwctl describe httproute demo-httproute

    1. Name: demo-httproute
    2. Namespace: default
    3. Labels: <none>
    4. Annotations: <none>
    5. API Version: gateway.networking.k8s.io/v1beta1
    6. Kind: HTTPRoute
    7. Metadata:
    8. creationTimestamp: "2023-11-09T09:45:03Z"
    9. generation: 1
    10. resourceVersion: "290416533"
    11. uid: 716d9e5f-f57a-4e56-81f6-c579d5d17471
    12. Spec:
    13. hostnames:
    14. - example.com
    15. parentRefs:
    16. - group: gateway.networking.k8s.io
    17. kind: Gateway
    18. name: demo-gateway
    19. rules:
    20. - backendRefs:
    21. - group: ""
    22. kind: Service
    23. name: demo-svc
    24. port: 80
    25. weight: 1
    26. matches:
    27. - path:
    28. type: PathPrefix
    29. value: /example
    30. Status:
    31. parents:
    32. - conditions:
    33. - lastTransitionTime: "2023-12-01T18:49:14Z"
    34. message: ""
    35. observedGeneration: 1
    36. reason: ReconciliationSucceeded
    37. status: "True"
    38. type: Reconciled
    39. controllerName: networking.io/gateway
    40. parentRef:
    41. group: gateway.networking.k8s.io
    42. kind: Gateway
    43. name: demo-gateway
    44. DirectlyAttachedPolicies:
    45. TYPE NAME
    46. ---- ----
    47. HealthCheckPolicy.foo.com demo-health-check-1
    48. RetryOnPolicy.baz.com demo-retry-policy-1
    49. InheritedPolicies:
    50. TYPE NAME TARGET KIND TARGET NAME
    51. ---- ---- ----------- -----------
    52. TimeoutPolicy.foo.com demo-timeout-policy-on-gatewayclass GatewayClass abc-gatewayclass
    53. RetryOnPolicy.baz.com demo-retry-policy-1 Gateway abc-gateway
    54. EffectivePolicies:
    55. HealthCheckPolicy.foo.com:
    56. sampleParentField:
    57. sampleField: hello
    58. RetryOnPolicy.foo.com:
    59. sampleParentField:
    60. sampleField: namaste
    61. TimeoutPolicy.bar.com:
    62. timeout1: parent
    63. timeout2: child
    64. timeout3: parent
    65. timeout4: child
    66. Events:
    67. Type Reason Age From Message
    68. ---- ------ ---- ---- -------
    69. Normal SYNC 2m12s (x46 over 138m) sc-gateway-controller SYNC on default/demo-gateway was a success
  • gwctl describe gatewayclass foo-com-external-gateway-class

    1. Name: foo-com-external-gateway-class
    2. Labels: <none>
    3. Annotations <none>
    4. API Version gateway.networking.k8s.io/v1beta1
    5. Kind: GatewayClass
    6. Metadata:
    7. creationTimestamp: "2023-06-28T17:33:03Z"
    8. generation: 1
    9. resourceVersion: "108322484"
    10. uid: 80cea521-5416-41c4-b5d1-2ee30f5366a6
    11. ControllerName: foo.com/external-gateway-class
    12. Description: Create an external load balancer
    13. Status:
    14. conditions:
    15. - lastTransitionTime: "2023-05-22T17:29:47Z"
    16. message: ""
    17. observedGeneration: 1
    18. reason: Accepted
    19. status: "True"
    20. type: Accepted
    21. DirectlyAttachedPolicies:
    22. TYPE NAME
    23. ---- ----
    24. TimeoutPolicy.bar.com demo-timeout-policy-on-gatewayclass