-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #36 from Kuadrant/generate-istiointegration
Generate istiointegration
- Loading branch information
Showing
16 changed files
with
547 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,4 +30,4 @@ jobs: | |
make install | ||
- name: run command | ||
run: | | ||
kuadrantctl install | ||
bin/kuadrantctl install |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package cmd | ||
|
||
import ( | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
func generateCommand() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "generate", | ||
Short: "Commands related to kubernetes object generation", | ||
Long: "Commands related to kubernetes object generation", | ||
} | ||
|
||
cmd.AddCommand(generateIstioCommand()) | ||
|
||
return cmd | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package cmd | ||
|
||
import ( | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
func generateIstioCommand() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "istio", | ||
Short: "Generate Istio resources", | ||
Long: "Generate Istio resorces", | ||
} | ||
|
||
cmd.AddCommand(generateIstioVirtualServiceCommand()) | ||
cmd.AddCommand(generateIstioAuthorizationPolicyCommand()) | ||
|
||
return cmd | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
package cmd | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"strings" | ||
|
||
"github.com/getkin/kin-openapi/openapi3" | ||
"github.com/spf13/cobra" | ||
istiosecurityapi "istio.io/api/security/v1beta1" | ||
istiotypeapi "istio.io/api/type/v1beta1" | ||
istiosecurity "istio.io/client-go/pkg/apis/security/v1beta1" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
|
||
"github.com/kuadrant/kuadrant-controller/pkg/common" | ||
istioutils "github.com/kuadrant/kuadrantctl/pkg/istio" | ||
"github.com/kuadrant/kuadrantctl/pkg/utils" | ||
) | ||
|
||
var ( | ||
generateIstioAPOAS string | ||
generateIstioAPPublicHost string | ||
generateIstioGatewayLabels []string | ||
) | ||
|
||
func generateIstioAuthorizationPolicyCommand() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "authorizationpolicy", | ||
Short: "Generate Istio AuthorizationPolicy", | ||
Long: "Generate Istio AuthorizationPolicy", | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
return runGenerateIstioAuthorizationPolicyCommand(cmd, args) | ||
}, | ||
} | ||
|
||
// OpenAPI ref | ||
cmd.Flags().StringVar(&generateIstioAPOAS, "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) | ||
} | ||
|
||
// public host | ||
cmd.Flags().StringVar(&generateIstioAPPublicHost, "public-host", "", "The address used by a client when attempting to connect to a service (required)") | ||
err = cmd.MarkFlagRequired("public-host") | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
// gateway labels | ||
cmd.Flags().StringSliceVar(&generateIstioGatewayLabels, "gateway-label", []string{}, "Gateway label (required)") | ||
err = cmd.MarkFlagRequired("gateway-label") | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
return cmd | ||
} | ||
|
||
func runGenerateIstioAuthorizationPolicyCommand(cmd *cobra.Command, args []string) error { | ||
dataRaw, err := utils.ReadExternalResource(generateIstioAPOAS) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
openapiLoader := openapi3.NewLoader() | ||
doc, err := openapiLoader.LoadFromData(dataRaw) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
err = doc.Validate(openapiLoader.Context) | ||
if err != nil { | ||
return fmt.Errorf("OpenAPI validation error: %w", err) | ||
} | ||
|
||
ap, err := generateIstioAuthorizationPolicy(cmd, doc) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
jsonData, err := json.Marshal(ap) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
fmt.Fprintln(cmd.OutOrStdout(), string(jsonData)) | ||
|
||
return nil | ||
} | ||
|
||
func generateIstioAuthorizationPolicy(cmd *cobra.Command, doc *openapi3.T) (*istiosecurity.AuthorizationPolicy, error) { | ||
objectName, err := utils.K8sNameFromOpenAPITitle(doc) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
matchLabels := map[string]string{} | ||
for idx := range generateIstioGatewayLabels { | ||
labels := strings.Split(generateIstioGatewayLabels[idx], "=") | ||
if len(labels) != 2 { | ||
return nil, fmt.Errorf("gateway labels have wrong syntax: %s", generateIstioGatewayLabels[idx]) | ||
} | ||
|
||
matchLabels[labels[0]] = labels[1] | ||
} | ||
|
||
rules := istioutils.AuthorizationPolicyRulesFromOpenAPI(doc, generateIstioAPPublicHost) | ||
|
||
authPolicy := &istiosecurity.AuthorizationPolicy{ | ||
TypeMeta: metav1.TypeMeta{ | ||
Kind: "AuthorizationPolicy", | ||
APIVersion: "security.istio.io/v1beta1", | ||
}, | ||
ObjectMeta: metav1.ObjectMeta{ | ||
// Missing namespace | ||
Name: objectName, | ||
}, | ||
Spec: istiosecurityapi.AuthorizationPolicy{ | ||
Selector: &istiotypeapi.WorkloadSelector{ | ||
MatchLabels: matchLabels, | ||
}, | ||
Rules: rules, | ||
Action: istiosecurityapi.AuthorizationPolicy_CUSTOM, | ||
ActionDetail: &istiosecurityapi.AuthorizationPolicy_Provider{ | ||
Provider: &istiosecurityapi.AuthorizationPolicy_ExtensionProvider{ | ||
Name: common.KuadrantAuthorizationProvider, | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
return authPolicy, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
package cmd | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
|
||
"github.com/getkin/kin-openapi/openapi3" | ||
"github.com/spf13/cobra" | ||
istionetworkingapi "istio.io/api/networking/v1beta1" | ||
istionetworking "istio.io/client-go/pkg/apis/networking/v1beta1" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
|
||
istioutils "github.com/kuadrant/kuadrantctl/pkg/istio" | ||
"github.com/kuadrant/kuadrantctl/pkg/utils" | ||
) | ||
|
||
var ( | ||
generateIstioVSOAS string | ||
generateIstioVSPublicHost string | ||
generateIstioVSServiceName string | ||
generateIstioVSServiceNamespace string | ||
generateIstioVSServicePort int32 | ||
generateIstioVSGateways []string | ||
) | ||
|
||
func generateIstioVirtualServiceCommand() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "virtualservice", | ||
Short: "Generate Istio VirtualService from OpenAPI 3.x", | ||
Long: "Generate Istio VirtualService from OpenAPI 3.x", | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
return rungenerateistiovirtualservicecommand(cmd, args) | ||
}, | ||
} | ||
|
||
// OpenAPI ref | ||
cmd.Flags().StringVar(&generateIstioVSOAS, "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) | ||
} | ||
|
||
// public host | ||
cmd.Flags().StringVar(&generateIstioVSPublicHost, "public-host", "", "The address used by a client when attempting to connect to a service (required)") | ||
err = cmd.MarkFlagRequired("public-host") | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
// service name | ||
cmd.Flags().StringVar(&generateIstioVSServiceName, "service-name", "", "Service name (required)") | ||
err = cmd.MarkFlagRequired("service-name") | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
// service namespace | ||
cmd.Flags().StringVarP(&generateIstioVSServiceNamespace, "service-namespace", "", "", "Service namespace (required)") | ||
err = cmd.MarkFlagRequired("service-namespace") | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
// service port | ||
cmd.Flags().Int32VarP(&generateIstioVSServicePort, "service-port", "p", 80, "Service port") | ||
|
||
// gateways | ||
cmd.Flags().StringSliceVar(&generateIstioVSGateways, "gateway", []string{}, "Gateways (required)") | ||
err = cmd.MarkFlagRequired("gateway") | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
return cmd | ||
} | ||
|
||
func rungenerateistiovirtualservicecommand(cmd *cobra.Command, args []string) error { | ||
dataRaw, err := utils.ReadExternalResource(generateIstioVSOAS) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
openapiLoader := openapi3.NewLoader() | ||
doc, err := openapiLoader.LoadFromData(dataRaw) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
err = doc.Validate(openapiLoader.Context) | ||
if err != nil { | ||
return fmt.Errorf("OpenAPI validation error: %w", err) | ||
} | ||
|
||
vs, err := generateIstioVirtualService(cmd, doc) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
jsonData, err := json.Marshal(vs) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
fmt.Fprintln(cmd.OutOrStdout(), string(jsonData)) | ||
return nil | ||
} | ||
|
||
func generateIstioVirtualService(cmd *cobra.Command, doc *openapi3.T) (*istionetworking.VirtualService, error) { | ||
objectName, err := utils.K8sNameFromOpenAPITitle(doc) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
destination := &istionetworkingapi.Destination{ | ||
Host: fmt.Sprintf("%s.%s.svc", generateIstioVSServiceName, generateIstioVSServiceNamespace), | ||
Port: &istionetworkingapi.PortSelector{Number: uint32(generateIstioVSServicePort)}, | ||
} | ||
|
||
httpRoutes, err := istioutils.HTTPRoutesFromOpenAPI(doc, destination) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
vs := &istionetworking.VirtualService{ | ||
TypeMeta: metav1.TypeMeta{ | ||
Kind: "VirtualService", | ||
APIVersion: "networking.istio.io/v1beta1", | ||
}, | ||
ObjectMeta: metav1.ObjectMeta{ | ||
// Missing namespace | ||
Name: objectName, | ||
}, | ||
Spec: istionetworkingapi.VirtualService{ | ||
Gateways: generateIstioVSGateways, | ||
Hosts: []string{generateIstioVSPublicHost}, | ||
Http: httpRoutes, | ||
}, | ||
} | ||
|
||
return vs, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
## Generate Istio AuthorizationPolicy objects | ||
|
||
The `kuadrantctl generate istio authorizationpolicy` command generates an [Istio AuthorizationPolicy](https://istio.io/latest/docs/reference/config/security/authorization-policy/) | ||
from your [OpenAPI Specification (OAS) 3.x](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.2.md) and kubernetes service information. | ||
|
||
### OpenAPI specification | ||
|
||
OpenAPI document resource can be provided by one of the following channels: | ||
* Filename in the available path. | ||
* URL format (supported schemes are HTTP and HTTPS). The CLI will try to download from the given address. | ||
* Read from stdin standard input stream. | ||
|
||
### Usage : | ||
|
||
```shell | ||
$ kuadrantctl generate istio authorizationpolicy -h | ||
Generate Istio AuthorizationPolicy | ||
|
||
Usage: | ||
kuadrantctl generate istio authorizationpolicy [flags] | ||
|
||
Flags: | ||
--gateway-label strings Gateway label (required) | ||
-h, --help help for authorizationpolicy | ||
--oas string /path/to/file.[json|yaml|yml] OR http[s]://domain/resource/path.[json|yaml|yml] OR - (required) | ||
--public-host string The address used by a client when attempting to connect to a service (required) | ||
|
||
Global Flags: | ||
-v, --verbose verbose output | ||
``` |
Oops, something went wrong.