Skip to content

Commit

Permalink
Merge pull request #43 from Kuadrant/httproute-kuadrant-extensions
Browse files Browse the repository at this point in the history
Kuadrant extensions
  • Loading branch information
eguzki authored Nov 29, 2023
2 parents 12b3aa3 + 6405744 commit 0c7c28e
Show file tree
Hide file tree
Showing 42 changed files with 2,163 additions and 322 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/code-style.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ jobs:
runs-on: ubuntu-latest

steps:
- name: Set up Go 1.16.x
uses: actions/setup-go@v2
- name: Set up Go 1.21.x
uses: actions/setup-go@v4
with:
go-version: 1.16.x
go-version: 1.21.x
id: go

- name: Check out code
Expand Down
8 changes: 5 additions & 3 deletions .github/workflows/commands.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,18 @@ jobs:
install:
name: Run kuadrantctl install
runs-on: ubuntu-latest
env:
KIND_CLUSTER_NAME: kuadrantctl-local
steps:
- name: Set up Go 1.20.x
- name: Set up Go 1.21.x
uses: actions/setup-go@v4
with:
go-version: 1.20.x
go-version: 1.21.x
id: go
- name: Check out code
uses: actions/checkout@v3
- name: Create k8s Kind Cluster
uses: helm/kind-action@v1.2.0
uses: helm/kind-action@v1.8.0
with:
version: v0.20.0
config: utils/kind-cluster.yaml
Expand Down
29 changes: 29 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---

name: Release

on:
release:
types: [created]

permissions:
contents: write
packages: write

jobs:
release-matrix:
name: Release Go Binary
runs-on: ubuntu-latest
strategy:
matrix:
# build and publish in parallel: linux/amd64, linux/arm64, darwin/amd64, darwin/arm64
goos: [linux, darwin]
goarch: [amd64, arm64]
steps:
- uses: actions/checkout@v3
- uses: wangyoucao577/go-release-action@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
goos: ${{ matrix.goos }}
goarch: ${{ matrix.goarch }}
goversion: 1.21.4
12 changes: 6 additions & 6 deletions .github/workflows/testing.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ jobs:
name: Build executable
runs-on: ubuntu-latest
steps:
- name: Set up Go 1.20.x
- name: Set up Go 1.21.x
uses: actions/setup-go@v4
with:
go-version: 1.20.x
go-version: 1.21.x
id: go
- name: Check out code
uses: actions/checkout@v2
Expand All @@ -28,17 +28,17 @@ jobs:
name: Run tests
runs-on: ubuntu-latest
env:
KIND_CLUSTER_NAME: kuadrant-local
KIND_CLUSTER_NAME: kuadrantctl-local
steps:
- name: Set up Go 1.20.x
- name: Set up Go 1.21.x
uses: actions/setup-go@v4
with:
go-version: 1.20.x
go-version: 1.21.x
id: go
- name: Check out code
uses: actions/checkout@v3
- name: Create k8s Kind Cluster
uses: helm/kind-action@v1.2.0
uses: helm/kind-action@v1.8.0
with:
version: v0.20.0
config: utils/kind-cluster.yaml
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ env-setup:
$(MAKE) olm-install
$(MAKE) gateway-api-install
$(MAKE) istio-install
$(MAKE) deploy-gateway

## local-setup: Sets up Kind cluster with GatewayAPI manifests and istio GW, nothing Kuadrant. Build and install kuadrantctl binary
.PHONY: local-setup
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Use `go install` to install the latest version of the library. This command will
```
go install github.com/kuadrant/kuadrantctl@latest
```
> Golang 1.20+ required
> Golang 1.21+ required
## Commands
* [Install Kuadrant](doc/install.md)
Expand Down
109 changes: 15 additions & 94 deletions cmd/generate_gatewayapi_httproute.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,73 +13,30 @@ import (
)

var (
generateGatewayAPIHTTPRouteOAS string
generateGatewayAPIHTTPRouteHost string
generateGatewayAPIHTTPRouteSvcName string
generateGatewayAPIHTTPRouteSvcNamespace string
generateGatewayAPIHTTPRouteSvcPort int32
generateGatewayAPIHTTPRouteGateways []string
generateGatewayAPIHTTPRouteOAS string
)

//kuadrantctl generate istio virtualservice --namespace myns --oas petstore.yaml --public-host www.kuadrant.io --service-name myservice --gateway kuadrant-gateway
// --namespace myns
// --service-name myservice
// --public-host www.kuadrant.io
// --gateway kuadrant-gateway
// -- service-port 80
//kuadrantctl generate gatewayapi httproute --oas [OAS_FILE_PATH | OAS_URL | @]

func generateGatewayApiHttpRouteCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "httproute",
Short: "Generate Gateway API HTTPRoute from OpenAPI 3.x",
Long: "Generate Gateway API HTTPRoute from OpenAPI 3.x",
RunE: func(cmd *cobra.Command, args []string) error {
return generateGatewayApiHttpRoute(cmd, args)
},
Short: "Generate Gateway API HTTPRoute from OpenAPI 3.0.X",
Long: "Generate Gateway API HTTPRoute from OpenAPI 3.0.X",
RunE: runGenerateGatewayApiHttpRoute,
}

// OpenAPI ref
cmd.Flags().StringVar(&generateGatewayAPIHTTPRouteOAS, "oas", "", "/path/to/file.[json|yaml|yml] OR http[s]://domain/resource/path.[json|yaml|yml] OR - (required)")
cmd.Flags().StringVar(&generateGatewayAPIHTTPRouteOAS, "oas", "", "/path/to/file.[json|yaml|yml] OR http[s]://domain/resource/path.[json|yaml|yml] OR @ (required)")
err := cmd.MarkFlagRequired("oas")
if err != nil {
panic(err)
}

// service ref
cmd.Flags().StringVar(&generateGatewayAPIHTTPRouteSvcName, "service-name", "", "Service name (required)")
err = cmd.MarkFlagRequired("service-name")
if err != nil {
panic(err)
}

// service namespace
cmd.Flags().StringVarP(&generateGatewayAPIHTTPRouteSvcNamespace, "namespace", "n", "", "Service namespace (required)")
err = cmd.MarkFlagRequired("namespace")
if err != nil {
panic(err)
}

// service host
cmd.Flags().StringVar(&generateGatewayAPIHTTPRouteHost, "public-host", "", "Public host (required)")
err = cmd.MarkFlagRequired("public-host")
if err != nil {
panic(err)
}

// service port
cmd.Flags().Int32VarP(&generateGatewayAPIHTTPRouteSvcPort, "port", "p", 80, "Service Port (required)")

// gateway
cmd.Flags().StringSliceVar(&generateGatewayAPIHTTPRouteGateways, "gateway", []string{}, "Gateways (required)")
err = cmd.MarkFlagRequired("gateway")
if err != nil {
panic(err)
}

return cmd
}

func generateGatewayApiHttpRoute(cmd *cobra.Command, args []string) error {
func runGenerateGatewayApiHttpRoute(cmd *cobra.Command, args []string) error {
oasDataRaw, err := utils.ReadExternalResource(generateGatewayAPIHTTPRouteOAS)
if err != nil {
return err
Expand All @@ -96,10 +53,7 @@ func generateGatewayApiHttpRoute(cmd *cobra.Command, args []string) error {
return fmt.Errorf("OpenAPI validation error: %w", err)
}

httpRoute, err := generateGatewayAPIHTTPRoute(cmd, doc)
if err != nil {
return err
}
httpRoute := buildHTTPRoute(doc)

jsonData, err := json.Marshal(httpRoute)
if err != nil {
Expand All @@ -110,52 +64,19 @@ func generateGatewayApiHttpRoute(cmd *cobra.Command, args []string) error {
return nil
}

func generateGatewayAPIHTTPRoute(cmd *cobra.Command, doc *openapi3.T) (*gatewayapiv1beta1.HTTPRoute, error) {

//loop through gateway
// https://github.com/getkin/kin-openapi
gatewaysRef := []gatewayapiv1beta1.ParentReference{}
for _, gateway := range generateGatewayAPIHTTPRouteGateways {
gatewaysRef = append(gatewaysRef, gatewayapiv1beta1.ParentReference{
Name: gatewayapiv1beta1.ObjectName(gateway),
})
}

port := gatewayapiv1beta1.PortNumber(generateGatewayAPIHTTPRouteSvcPort)
service := fmt.Sprintf("%s.%s.svc", generateGatewayAPIHTTPRouteSvcName, generateGatewayAPIHTTPRouteSvcNamespace)
matches, err := gatewayapi.HTTPRouteMatchesFromOAS(doc)
if err != nil {
return nil, err
}

httpRoute := gatewayapiv1beta1.HTTPRoute{
func buildHTTPRoute(doc *openapi3.T) *gatewayapiv1beta1.HTTPRoute {
return &gatewayapiv1beta1.HTTPRoute{
TypeMeta: v1.TypeMeta{
Kind: "HTTPRoute",
APIVersion: "gateway.networking.k8s.io/v1beta1",
Kind: "HTTPRoute",
},
ObjectMeta: gatewayapi.HTTPRouteObjectMetaFromOAS(doc),
Spec: gatewayapiv1beta1.HTTPRouteSpec{
CommonRouteSpec: gatewayapiv1beta1.CommonRouteSpec{
ParentRefs: gatewaysRef,
},
Hostnames: []gatewayapiv1beta1.Hostname{
gatewayapiv1beta1.Hostname(generateGatewayAPIHTTPRouteHost),
},
Rules: []gatewayapiv1beta1.HTTPRouteRule{
{
BackendRefs: []gatewayapiv1beta1.HTTPBackendRef{
{
BackendRef: gatewayapiv1beta1.BackendRef{
BackendObjectReference: gatewayapiv1beta1.BackendObjectReference{
Name: gatewayapiv1beta1.ObjectName(service),
Port: &port,
},
},
},
},
Matches: matches,
},
ParentRefs: gatewayapi.HTTPRouteGatewayParentRefsFromOAS(doc),
},
Hostnames: gatewayapi.HTTPRouteHostnamesFromOAS(doc),
Rules: gatewayapi.HTTPRouteRulesFromOAS(doc),
},
}
return &httpRoute, nil
}
3 changes: 3 additions & 0 deletions cmd/generate_kuadrant.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,8 @@ func generateKuadrantCommand() *cobra.Command {
Long: "Generate Kuadrant resources",
}

cmd.AddCommand(generateKuadrantRateLimitPolicyCommand())
cmd.AddCommand(generateKuadrantAuthPolicyCommand())

return cmd
}
97 changes: 97 additions & 0 deletions cmd/generate_kuadrant_authpolicy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package cmd

import (
"encoding/json"
"fmt"

"github.com/getkin/kin-openapi/openapi3"
kuadrantapiv1beta2 "github.com/kuadrant/kuadrant-operator/api/v1beta2"
"github.com/spf13/cobra"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"

"github.com/kuadrant/kuadrantctl/pkg/gatewayapi"
"github.com/kuadrant/kuadrantctl/pkg/kuadrantapi"
"github.com/kuadrant/kuadrantctl/pkg/utils"
)

//kuadrantctl generate kuadrant authpolicy --oas [OAS_FILE_PATH | OAS_URL | @]

func generateKuadrantAuthPolicyCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "authpolicy",
Short: "Generate Kuadrant AuthPolicy from OpenAPI 3.0.X",
Long: "Generate Kuadrant AuthPolicy from OpenAPI 3.0.X",
RunE: runGenerateKuadrantAuthPolicy,
}

// OpenAPI ref
cmd.Flags().StringVar(&generateGatewayAPIHTTPRouteOAS, "oas", "", "/path/to/file.[json|yaml|yml] OR http[s]://domain/resource/path.[json|yaml|yml] OR @ (required)")
err := cmd.MarkFlagRequired("oas")
if err != nil {
panic(err)
}

return cmd
}

func runGenerateKuadrantAuthPolicy(cmd *cobra.Command, args []string) error {
oasDataRaw, err := utils.ReadExternalResource(generateGatewayAPIHTTPRouteOAS)
if err != nil {
return err
}

openapiLoader := openapi3.NewLoader()
doc, err := openapiLoader.LoadFromData(oasDataRaw)
if err != nil {
return err
}

err = doc.Validate(openapiLoader.Context)
if err != nil {
return fmt.Errorf("OpenAPI validation error: %w", err)
}

ap := buildAuthPolicy(doc)

jsonData, err := json.Marshal(ap)
if err != nil {
return err
}

fmt.Fprintln(cmd.OutOrStdout(), string(jsonData))
return nil
}

func buildAuthPolicy(doc *openapi3.T) *kuadrantapiv1beta2.AuthPolicy {
routeMeta := gatewayapi.HTTPRouteObjectMetaFromOAS(doc)

ap := &kuadrantapiv1beta2.AuthPolicy{
TypeMeta: v1.TypeMeta{
APIVersion: "kuadrant.io/v1beta2",
Kind: "AuthPolicy",
},
ObjectMeta: kuadrantapi.AuthPolicyObjectMetaFromOAS(doc),
Spec: kuadrantapiv1beta2.AuthPolicySpec{
TargetRef: gatewayapiv1alpha2.PolicyTargetReference{
Group: gatewayapiv1beta1.Group("gateway.networking.k8s.io"),
Kind: gatewayapiv1beta1.Kind("HTTPRoute"),
Name: gatewayapiv1beta1.ObjectName(routeMeta.Name),
},
// Currently only authentication rules enforced
AuthScheme: kuadrantapiv1beta2.AuthSchemeSpec{
Authentication: kuadrantapi.AuthPolicyAuthenticationSchemeFromOAS(doc),
},
RouteSelectors: kuadrantapi.AuthPolicyTopRouteSelectorsFromOAS(doc),
},
}

if routeMeta.Namespace != "" {
ap.Spec.TargetRef.Namespace = &[]gatewayapiv1beta1.Namespace{
gatewayapiv1beta1.Namespace(routeMeta.Namespace),
}[0]
}

return ap
}
Loading

0 comments on commit 0c7c28e

Please sign in to comment.