Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Support to ory hydra running in secure mode #62

Merged
merged 29 commits into from
May 10, 2021
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
6491a99
Support to ory hydra running in secure mode
fjvierap Dec 18, 2020
d769f7d
feat: adjust readme
fjvierap Dec 18, 2020
daf5c44
Add namespace bases roles instead of cluster
fjvierap Feb 11, 2021
7d66a70
Add log message when enable insecure skip verify
fjvierap Apr 23, 2021
d90f5a9
Add setup log for insecure verify
fjvierap Apr 23, 2021
509ee6a
Adjust README.md
fjvierap Apr 23, 2021
90f8234
Merge remote-tracking branch 'origin/master' into namespace
fjvierap Apr 23, 2021
715ee4a
Add error for not existent tls trust store
fjvierap Apr 28, 2021
51a4e30
Merge pull request #1 from fjvierap/namespace
fjvierap Apr 28, 2021
e16c267
Adjust rbac
fjvierap Apr 28, 2021
b75d417
Add unit test for create http client
fjvierap May 5, 2021
5364f44
Remove HydraClientMaker
fjvierap May 5, 2021
d403834
Improve error handling
fjvierap May 10, 2021
d12ad0a
Add helpers to makefile for testing that package
fjvierap May 10, 2021
9b8f463
build: update CRDs and k8s dependencies (#68)
colunira May 10, 2021
9d56503
docs: Incorporates changes from version v0.0.20
May 10, 2021
14611a8
Support to ory hydra running in secure mode
fjvierap Dec 18, 2020
7f2bf13
feat: adjust readme
fjvierap Dec 18, 2020
cde714e
Add namespace bases roles instead of cluster
fjvierap Feb 11, 2021
bbd2830
Add log message when enable insecure skip verify
fjvierap Apr 23, 2021
a210259
Add setup log for insecure verify
fjvierap Apr 23, 2021
00d3a80
Adjust README.md
fjvierap Apr 23, 2021
1ff476c
Add error for not existent tls trust store
fjvierap Apr 28, 2021
b8622e0
Adjust rbac
fjvierap Apr 28, 2021
ba61fce
Add unit test for create http client
fjvierap May 5, 2021
9c5a153
Remove HydraClientMaker
fjvierap May 5, 2021
27558c3
Improve error handling
fjvierap May 10, 2021
aaf8870
Add helpers to makefile for testing that package
fjvierap May 10, 2021
80230cd
Merge branch 'master' of https://github.com/fjvierap/hydra-maester
fjvierap May 10, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,12 @@ To deploy the controller, edit the value of the ```--hydra-url``` argument in th

### Command-line flags

| Name | Required | Description | Default value | Example values |
|-----------------|----------|------------------------------|---------------|------------------------------------------------------|
| **hydra-url** | yes | ORY Hydra's service address | - | ` ory-hydra-admin.ory.svc.cluster.local` |
| **hydra-port** | no | ORY Hydra's service port | `4445` | `4445` |
| Name | Required | Description | Default value | Example values |
|----------------------------|----------|----------------------------------------|---------------|------------------------------------------------------|
| **hydra-url** | yes | ORY Hydra's service address | - | ` ory-hydra-admin.ory.svc.cluster.local` |
| **hydra-port** | no | ORY Hydra's service port | `4445` | `4445` |
| **tls-trust-store** | no | TLS cert path for hydra client | `""` | `/etc/ssl/certs/ca-certificates.crt` |
| **insecure-skip-verify** | no | Skip http client insecure verification | `false` | `true` or `false` |

## Development

Expand Down
20 changes: 9 additions & 11 deletions controllers/oauth2client_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ const (
FinalizerName = "finalizer.ory.hydra.sh"
)

type HydraClientMakerFunc func(hydrav1alpha1.OAuth2ClientSpec) (HydraClientInterface, error)

type clientMapKey struct {
url string
port int
Expand All @@ -56,10 +54,9 @@ type HydraClientInterface interface {

// OAuth2ClientReconciler reconciles a OAuth2Client object
type OAuth2ClientReconciler struct {
HydraClient HydraClientInterface
HydraClientMaker HydraClientMakerFunc
Log logr.Logger
otherClients map[clientMapKey]HydraClientInterface
HydraClient HydraClientInterface
Log logr.Logger
otherClients map[clientMapKey]HydraClientInterface
client.Client
}

Expand Down Expand Up @@ -333,10 +330,6 @@ func parseSecret(secret apiv1.Secret, authMethod hydrav1alpha1.TokenEndpointAuth

func (r *OAuth2ClientReconciler) getHydraClientForClient(oauth2client hydrav1alpha1.OAuth2Client) (HydraClientInterface, error) {
spec := oauth2client.Spec
if spec.HydraAdmin == (hydrav1alpha1.HydraAdmin{}) {
r.Log.Info(fmt.Sprintf("using default client"))
return r.HydraClient, nil
}
key := clientMapKey{
url: spec.HydraAdmin.URL,
port: spec.HydraAdmin.Port,
Expand All @@ -346,7 +339,12 @@ func (r *OAuth2ClientReconciler) getHydraClientForClient(oauth2client hydrav1alp
if c, ok := r.otherClients[key]; ok {
return c, nil
}
return r.HydraClientMaker(spec)
if r.HydraClient == nil {
return nil, errors.New("Not default client or other clients configured")
}
r.Log.Info(fmt.Sprintf("using default client"))
return r.HydraClient, nil

}

// Helper functions to check and remove string from a slice of strings.
Expand Down
3 changes: 0 additions & 3 deletions controllers/oauth2client_controller_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -470,9 +470,6 @@ func getAPIReconciler(mgr ctrl.Manager, mock controllers.HydraClientInterface) r
Client: mgr.GetClient(),
Log: ctrl.Log.WithName("controllers").WithName("OAuth2Client"),
HydraClient: mock,
HydraClientMaker: func(hydrav1alpha1.OAuth2ClientSpec) (controllers.HydraClientInterface, error) {
return mock, nil
},
}
}

Expand Down
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ go 1.13

require (
github.com/go-logr/logr v0.1.0
github.com/go-openapi/runtime v0.19.24
github.com/onsi/ginkgo v1.6.0
github.com/onsi/gomega v1.4.2
github.com/pkg/errors v0.8.1
github.com/stretchr/testify v1.3.0
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd
github.com/stretchr/testify v1.6.1
golang.org/x/net v0.0.0-20200602114024-627f9648deb9
k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b
k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d
k8s.io/client-go v11.0.1-0.20190409021438-1a26190bd76a+incompatible
Expand Down
213 changes: 213 additions & 0 deletions go.sum

Large diffs are not rendered by default.

33 changes: 33 additions & 0 deletions helpers/http_client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package helpers

import (
"crypto/tls"
"net/http"

ctrl "sigs.k8s.io/controller-runtime"

httptransport "github.com/go-openapi/runtime/client"
)

func CreateHttpClient(insecureSkipVerify bool, tlsTrustStore string) *http.Client {
fjvierap marked this conversation as resolved.
Show resolved Hide resolved
setupLog := ctrl.Log.WithName("setup")
tr := &http.Transport{}
httpClient := &http.Client{}
if insecureSkipVerify {
setupLog.Info("configuring TLS with InsecureSkipVerify")
tr.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
httpClient.Transport = tr
}
if tlsTrustStore != "" {
setupLog.Info("configuring TLS with tlsTrustStore")
ops := httptransport.TLSClientOptions{
CA: tlsTrustStore,
InsecureSkipVerify: insecureSkipVerify,
}
if tlsClient, err := httptransport.TLSClient(ops); err != nil {
setupLog.Error(err, "Error while getting TLSClient, default http client will be used")
return tlsClient
}
}
return httpClient
}
35 changes: 35 additions & 0 deletions helpers/http_client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package helpers
fjvierap marked this conversation as resolved.
Show resolved Hide resolved

import (
"io/ioutil"
"os"
"testing"

"github.com/stretchr/testify/require"
fjvierap marked this conversation as resolved.
Show resolved Hide resolved
)

func TestCreateHttpClient(t *testing.T) {
t.Run("should create insecureSkipVerify client", func(t *testing.T) {
client := CreateHttpClient(true, "")
fjvierap marked this conversation as resolved.
Show resolved Hide resolved
require.NotNil(t, client)
})

t.Run("should create client with insecureSkipVerify and wrong tlsTrustStore", func(t *testing.T) {
tlsTrustStore := "some path"
client := CreateHttpClient(true, tlsTrustStore)
fjvierap marked this conversation as resolved.
Show resolved Hide resolved
require.Nil(t, client)
})

t.Run("should create client with and tlsTrustStore", func(t *testing.T) {
file, err := ioutil.TempFile("/tmp", "test")
require.Nil(t, err)
client := CreateHttpClient(true, file.Name())
fjvierap marked this conversation as resolved.
Show resolved Hide resolved
defer os.Remove(file.Name())
require.NotNil(t, client)
})

t.Run("should create client without and tlsTrustStore", func(t *testing.T) {
client := CreateHttpClient(true, "")
fjvierap marked this conversation as resolved.
Show resolved Hide resolved
require.NotNil(t, client)
})
}
76 changes: 33 additions & 43 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ package main
import (
"flag"
"fmt"
"net/http"
"net/url"
"os"
"time"

"github.com/ory/hydra-maester/helpers"

"github.com/ory/hydra-maester/hydra"

hydrav1alpha1 "github.com/ory/hydra-maester/api/v1alpha1"
Expand All @@ -49,19 +50,20 @@ func init() {

func main() {
var (
metricsAddr, hydraURL, endpoint, forwardedProto, syncPeriod string
hydraPort int
enableLeaderElection bool
metricsAddr, hydraURL, endpoint, forwardedProto, syncPeriod, tlsTrustStore string
hydraPort int
enableLeaderElection, insecureSkipVerify bool
)

flag.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.")
flag.StringVar(&hydraURL, "hydra-url", "", "The address of ORY Hydra")
flag.IntVar(&hydraPort, "hydra-port", 4445, "Port ORY Hydra is listening on")
flag.StringVar(&endpoint, "endpoint", "/clients", "ORY Hydra's client endpoint")
flag.StringVar(&forwardedProto, "forwarded-proto", "", "If set, this adds the value as the X-Forwarded-Proto header in requests to the ORY Hydra admin server")
flag.StringVar(&tlsTrustStore, "tls-trust-store", "", "trust store certificate path. If set ca will be set in http client to connect with hydra admin")
flag.StringVar(&syncPeriod, "sync-period", "10h", "Determines the minimum frequency at which watched resources are reconciled")
flag.BoolVar(&enableLeaderElection, "enable-leader-election", false,
"Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager.")
flag.BoolVar(&enableLeaderElection, "enable-leader-election", false, "Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager.")
flag.BoolVar(&insecureSkipVerify, "insecure-skip-verify", false, "If set, http client will be configured to skip insecure verification to connect with hydra admin")
flag.Parse()

ctrl.SetLogger(zap.Logger(true))
Expand Down Expand Up @@ -96,19 +98,24 @@ func main() {
ForwardedProto: forwardedProto,
},
}
hydraClientMaker := getHydraClientMaker(defaultSpec)
hydraClient, err := hydraClientMaker(defaultSpec)
if tlsTrustStore != "" {
if _, err := os.Stat(tlsTrustStore); err != nil {
setupLog.Error(err, "cannot parse tls trust store")
os.Exit(1)
}
}

hydraClient := getHydraClient(defaultSpec, tlsTrustStore, insecureSkipVerify)
if err != nil {
setupLog.Error(err, "making default hydra client", "controller", "OAuth2Client")
os.Exit(1)

}

err = (&controllers.OAuth2ClientReconciler{
Client: mgr.GetClient(),
Log: ctrl.Log.WithName("controllers").WithName("OAuth2Client"),
HydraClient: hydraClient,
HydraClientMaker: hydraClientMaker,
Client: mgr.GetClient(),
Log: ctrl.Log.WithName("controllers").WithName("OAuth2Client"),
HydraClient: hydraClient,
}).SetupWithManager(mgr)
if err != nil {
setupLog.Error(err, "unable to create controller", "controller", "OAuth2Client")
Expand All @@ -123,39 +130,22 @@ func main() {
}
}

func getHydraClientMaker(defaultSpec hydrav1alpha1.OAuth2ClientSpec) controllers.HydraClientMakerFunc {

return controllers.HydraClientMakerFunc(func(spec hydrav1alpha1.OAuth2ClientSpec) (controllers.HydraClientInterface, error) {

if spec.HydraAdmin.URL == "" {
spec.HydraAdmin.URL = defaultSpec.HydraAdmin.URL
}
if spec.HydraAdmin.Port == 0 {
spec.HydraAdmin.Port = defaultSpec.HydraAdmin.Port
}
if spec.HydraAdmin.Endpoint == "" {
spec.HydraAdmin.Endpoint = defaultSpec.HydraAdmin.Endpoint
}
if spec.HydraAdmin.ForwardedProto == "" {
spec.HydraAdmin.ForwardedProto = defaultSpec.HydraAdmin.ForwardedProto
}
func getHydraClient(spec hydrav1alpha1.OAuth2ClientSpec, tlsTrustStore string, insecureSkipVerify bool) controllers.HydraClientInterface {

address := fmt.Sprintf("%s:%d", spec.HydraAdmin.URL, spec.HydraAdmin.Port)
u, err := url.Parse(address)
if err != nil {
return nil, fmt.Errorf("unable to parse ORY Hydra's URL: %w", err)
}

client := &hydra.Client{
HydraURL: *u.ResolveReference(&url.URL{Path: spec.HydraAdmin.Endpoint}),
HTTPClient: &http.Client{},
}
address := fmt.Sprintf("%s:%d", spec.HydraAdmin.URL, spec.HydraAdmin.Port)
u, err := url.Parse(address)
if err != nil {
return nil
}

if spec.HydraAdmin.ForwardedProto != "" && spec.HydraAdmin.ForwardedProto != "off" {
client.ForwardedProto = spec.HydraAdmin.ForwardedProto
}
client := &hydra.Client{
HydraURL: *u.ResolveReference(&url.URL{Path: spec.HydraAdmin.Endpoint}),
HTTPClient: helpers.CreateHttpClient(insecureSkipVerify, tlsTrustStore),
}

return client, nil
})
if spec.HydraAdmin.ForwardedProto != "" && spec.HydraAdmin.ForwardedProto != "off" {
client.ForwardedProto = spec.HydraAdmin.ForwardedProto
}

return client
}