Skip to content

Commit

Permalink
Basic Authentication - #399
Browse files Browse the repository at this point in the history
**WIP:** Still debugging.

See <#399> for further information.
  • Loading branch information
Mohamed Bana committed May 27, 2022
1 parent b530b39 commit f9b8752
Show file tree
Hide file tree
Showing 11 changed files with 208 additions and 45 deletions.
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ help: ## Display this help.

##@ Development

.PHONY: dev-update
dev-update: docker-build update cycle deploy-envoyfleet ## Update cluster with local changes (usually after you have modified the code).

.PHONY: create-env
create-env: ## Spin up a local development cluster with Minikube and install kusk Gateway
./development/cluster/create-env.sh
Expand Down
2 changes: 1 addition & 1 deletion examples/auth-basic/auth-basic-api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ spec:
auth-upstream:
host:
hostname: envoy-auth-basic-http-service.svc.cluster.local
port: 9092
port: 9002
upstream:
service:
name: httpbin
Expand Down
6 changes: 3 additions & 3 deletions examples/auth-basic/auth-basic-manifest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ spec:
memory: "128Mi"
cpu: "500m"
ports:
- containerPort: 9092
- containerPort: 9002
---
apiVersion: v1
kind: Service
Expand All @@ -33,8 +33,8 @@ metadata:
name: envoy-auth-basic-http-service
spec:
ports:
- port: 9092
targetPort: 9092
- port: 9002
targetPort: 9002
selector:
app: envoy-auth-basic-http-service
---
Expand Down
20 changes: 9 additions & 11 deletions examples/auth-basic/auth-basic-staticroute.yaml
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
apiVersion: gateway.kusk.io/v1alpha1
kind: StaticRoute
metadata:
name: httpbin-sample
name: auth-static-route
spec:
# should work with localhost, example.org
hosts: [ "localhost", "*"]
hosts: ["localhost", "*"]
paths:
# Root goes to httpbin
/:
# Root goes to httpbin
/static:
get: &root_route
route:
upstream:
host:
hostname: httpbin.default.svc.cluster.local
port: 8080
hostname: auth-basic-http-authentication-service
port: 9002
rewrite:
pattern: "^/$"
substitution: "/get"
Expand All @@ -22,13 +22,13 @@ spec:
put: *root_route
head: *root_route
# /static -> /
/static:
/static/redirect:
get:
redirect:
path_redirect: "/"
path_redirect: "/static-root"
response_code: 308
# /get2 routed to k8s service httpbin in default namespace with rewrite to /get
/get2:
/static/get:
get:
route:
upstream:
Expand All @@ -39,5 +39,3 @@ spec:
rewrite:
pattern: "^/get2$"
substitution: "/get"


124 changes: 124 additions & 0 deletions examples/auth-basic/auth-basic.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
apiVersion: gateway.kusk.io/v1alpha1
kind: API
metadata:
name: auth-basic
spec:
fleet:
name: default
namespace: default
# service name and port should be specified inside x-kusk annotation
spec: |
openapi: 3.0.0
info:
title: auth-basic
description: auth-basic
version: '0.0.1'
schemes:
- http
- https
x-kusk:
auth:
scheme: basic
auth-upstream:
host:
hostname: auth-basic-http-authentication-service.default.svc.cluster.local
port: 9002
upstream:
service:
name: httpbin
namespace: default
port: 8080
paths:
"/auth":
get:
description: Returns GET data.
operationId: "/auth"
responses: {}
"/auth/home":
get:
description: Returns GET data.
operationId: "/auth/home"
responses: {}
"/auth/get":
get:
description: Returns GET data.
operationId: "/auth/get"
responses: {}
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: auth-basic-http-authentication-service
name: auth-basic-http-authentication-service
spec:
replicas: 1
selector:
matchLabels:
app: auth-basic-http-authentication-service
template:
metadata:
labels:
app: auth-basic-http-authentication-service
spec:
containers:
- name: auth-basic-http-authentication-service
image: banaioltd/envoy-auth-basic-http-service:latest
resources:
limits:
memory: "128Mi"
cpu: "500m"
ports:
- containerPort: 9002
---
apiVersion: v1
kind: Service
metadata:
labels:
app: auth-basic-http-authentication-service
name: auth-basic-http-authentication-service
spec:
ports:
- port: 9002
targetPort: 9002
selector:
app: auth-basic-http-authentication-service
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: httpbin
name: httpbin
spec:
replicas: 1
selector:
matchLabels:
app: httpbin
template:
metadata:
labels:
app: httpbin
spec:
containers:
- name: httpbin
image: kennethreitz/httpbin
resources:
limits:
memory: "128Mi"
cpu: "500m"
# ports:
# - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
labels:
app: httpbin
name: httpbin
spec:
ports:
- port: 8080
targetPort: 80
selector:
app: httpbin
6 changes: 1 addition & 5 deletions internal/controllers/config_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ func (c *KubeEnvoyConfigManager) UpdateConfiguration(ctx context.Context, fleetI
}
}

httpConnectionManagerBuilder, err := config.NewHCMBuilder()
httpConnectionManagerBuilder, err := config.NewHCMBuilder( /* TODO(MBana): Figure out how to pass `opts` here*/ nil)
if err != nil {
return fmt.Errorf("failed to get HTTP connection manager: %w", err)
}
Expand Down Expand Up @@ -179,10 +179,6 @@ func (c *KubeEnvoyConfigManager) UpdateConfiguration(ctx context.Context, fleetI
httpConnectionManagerBuilder.AddAccessLog(accessLogBuilder.GetAccessLog())
}

// Add auth configuration to HTTPConnectionManager
httpConnectionManager := httpConnectionManagerBuilder.GetHTTPConnectionManager()
_ = httpConnectionManager

if err := httpConnectionManagerBuilder.Validate(); err != nil {
l.Error(err, "Failed validation for HttpConnectionManager", "fleet", fleetIDstr)
return fmt.Errorf("failed validation for HttpConnectionManager")
Expand Down
2 changes: 1 addition & 1 deletion internal/controllers/envoyfleet_resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ func (e *EnvoyFleetResources) generateDeployment(ctx context.Context) error {
ImagePullPolicy: corev1.PullIfNotPresent,
Command: []string{"/bin/sh", "-c"},
Args: []string{
"envoy -c /etc/envoy/envoy.yaml --service-node $POD_NAME",
"envoy -c /etc/envoy/envoy.yaml --log-level debug --service-node $POD_NAME",
},
Env: []corev1.EnvVar{
{
Expand Down
22 changes: 20 additions & 2 deletions internal/controllers/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ func UpdateConfigFromAPIOpts(envoyConfiguration *config.EnvoyConfiguration, prox
}
}

// // Validate and Proxy to the upstream
// Validate and Proxy to the upstream
case finalOpts.Validation != nil && finalOpts.Validation.Request != nil && finalOpts.Validation.Request.Enabled != nil && *finalOpts.Validation.Request.Enabled:
upstreamHostname, upstreamPort := getUpstreamHost(finalOpts.Upstream)

Expand Down Expand Up @@ -284,7 +284,25 @@ func UpdateConfigFromAPIOpts(envoyConfiguration *config.EnvoyConfiguration, prox
rt.Action = routeRoute

routesToAddToVirtualHost = append(routesToAddToVirtualHost, rt)

// Auth
case finalOpts.Auth != nil:
fmt.Println("-----")
fmt.Printf("finalOpts.Auth not nil, finalOpts.Auth=%+v\n", finalOpts.Auth)
clusterName := "auth-basic-http-authentication-service"
upstreamServiceHost := "auth-basic-http-authentication-service"
var upstreamServicePort uint32 = 9002
if !envoyConfiguration.ClusterExist(clusterName) {
fmt.Printf("cluster does not exist - add: %s %s:%d\n", clusterName, upstreamServiceHost, upstreamServicePort)
envoyConfiguration.AddCluster(
clusterName,
upstreamServiceHost,
upstreamServicePort,
)
}
if envoyConfiguration.ClusterExist(clusterName) {
fmt.Printf("cluster does not exist - skip add: %s %s:%d\n", clusterName, upstreamServiceHost, upstreamServicePort)
}
fmt.Println("-----")
// Default - proxy to the upstream
default:
upstreamHostname, upstreamPort := getUpstreamHost(finalOpts.Upstream)
Expand Down
35 changes: 23 additions & 12 deletions internal/envoy/config/hcm.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ import (
"github.com/envoyproxy/go-control-plane/pkg/wellknown"
"google.golang.org/protobuf/types/known/anypb"
"google.golang.org/protobuf/types/known/durationpb"

"github.com/kubeshop/kusk-gateway/pkg/options"
)

const (
Expand All @@ -46,15 +48,7 @@ type hcmBuilder struct {
httpConnectionManager *hcm.HttpConnectionManager
}

// x-kusk:
// auth:
// scheme: basic
// auth-upstream:
// host:
// hostname: envoy-auth-basic-http-service.svc.cluster.local
// port: 9092

func NewHCMBuilder() (*hcmBuilder, error) {
func NewHCMBuilder( /* TODO(MBana): Figure out how to use `opts` here*/ opts *options.Options) (*hcmBuilder, error) {
rl := &ratelimit.LocalRateLimit{
StatPrefix: "http_local_rate_limiter",
}
Expand All @@ -63,12 +57,14 @@ func NewHCMBuilder() (*hcmBuilder, error) {
return nil, fmt.Errorf("cannot marshal ratelimit configuration: %w", err)
}

uri := fmt.Sprintf("http://%s:%d", "envoy-auth-basic-http-service.svc.cluster.local", 9092)
// uri := fmt.Sprintf("http://%s:%d", "auth-basic-http-authentication-service.svc.cluster.local", 9002)
// // uri := fmt.Sprintf("%s:%d", "auth-basic-http-authentication-service", 9002)

pathPrefix := ""
// uri := fmt.Sprintf("http://%s:%d", "auth-basic-http-authentication-service.default.svc.cluster.local", 9002)
uri := fmt.Sprintf("%s:%d", "auth-basic-http-authentication-service.default.svc.cluster.local", 9002)

httpUpstreamType := &envoy_config_core_v3.HttpUri_Cluster{
Cluster: "envoy-auth-basic-http-service",
Cluster: "auth-basic-http-authentication-service",
}
serverUri := &envoy_config_core_v3.HttpUri{
// https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/http_uri.proto#envoy-v3-api-msg-config-core-v3-httpuri
Expand All @@ -78,6 +74,7 @@ func NewHCMBuilder() (*hcmBuilder, error) {
Seconds: 60,
},
}
pathPrefix := ""
authorizationResponse := &envoy_auth_v3.AuthorizationResponse{
AllowedUpstreamHeaders: &envoy_type_matcher_v3.ListStringMatcher{
Patterns: []*envoy_type_matcher_v3.StringMatcher{
Expand All @@ -90,10 +87,23 @@ func NewHCMBuilder() (*hcmBuilder, error) {
},
},
}
// authorizationRequest := &envoy_auth_v3.AuthorizationRequest{
// AllowedHeaders: &envoy_type_matcher_v3.ListStringMatcher{
// Patterns: []*envoy_type_matcher_v3.StringMatcher{
// {
// MatchPattern: &envoy_type_matcher_v3.StringMatcher_Exact{
// Exact: "Authorization",
// },
// IgnoreCase: true,
// },
// },
// },
// }
httpService := &envoy_auth_v3.HttpService{
ServerUri: serverUri,
PathPrefix: pathPrefix,
AuthorizationResponse: authorizationResponse,
// AuthorizationRequest: authorizationRequest,
}
services := &envoy_auth_v3.ExtAuthz_HttpService{
HttpService: httpService,
Expand Down Expand Up @@ -128,6 +138,7 @@ func NewHCMBuilder() (*hcmBuilder, error) {
Name: wellknown.CORS,
},
{
// Name: "envoy.filters.http.ext_authz", // TODO(MBana): Replace with `Name: wellknown.HTTPExternalAuthorization`
Name: wellknown.HTTPExternalAuthorization,
ConfigType: &hcm.HttpFilter_TypedConfig{
TypedConfig: anyAuthorization,
Expand Down
11 changes: 1 addition & 10 deletions pkg/options/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,6 @@ SOFTWARE.

package options

// x-kusk:
// ...
// auth:
// scheme: basic
// path_prefix: /login #optional
// auth-upstream:
// host:
// hostname: example.com
// port: 80

type Auth struct {
Scheme string `json:"scheme,omitempty" yaml:"scheme,omitempty"`
PathPrefix *string `json:"path_prefix,omitempty" yaml:"path_prefix,omitempty"`
Expand All @@ -52,6 +42,7 @@ type AuthUpstreamHost struct {
func (a *Auth) Validate() error {
return nil

// TODO(MBana): Double-check if we should do validation here.
// return v.ValidateStruct(&a,
// v.Field(&a.Scheme, v.In("http", "https")),
// v.Field(&a.Scheme, v.In("basic")),
Expand Down
Loading

0 comments on commit f9b8752

Please sign in to comment.