feat: Reconcile missing and updated OAuth2 Clients (#46)

This commit is contained in:
Jakub Kabza 2020-02-11 17:05:41 +01:00 committed by GitHub
parent cf90a964fc
commit ef9f2e2538
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 69 additions and 55 deletions

View File

@ -8,7 +8,7 @@ all: manager
# Run tests # Run tests
test: generate fmt vet manifests test: generate fmt vet manifests
go test ./api/... ./controllers/... ./hydra... -coverprofile cover.out go test ./api/... ./controllers/... ./hydra/... -coverprofile cover.out
# Run integration tests on local KIND cluster # Run integration tests on local KIND cluster
# TODO: modify once integration tests have been implemented # TODO: modify once integration tests have been implemented

View File

@ -117,8 +117,6 @@ func (r *OAuth2ClientReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error
} }
if oauth2client.Generation != oauth2client.Status.ObservedGeneration {
var secret apiv1.Secret var secret apiv1.Secret
if err := r.Get(ctx, types.NamespacedName{Name: oauth2client.Spec.SecretName, Namespace: req.Namespace}, &secret); err != nil { if err := r.Get(ctx, types.NamespacedName{Name: oauth2client.Spec.SecretName, Namespace: req.Namespace}, &secret); err != nil {
if apierrs.IsNotFound(err) { if apierrs.IsNotFound(err) {
@ -160,6 +158,11 @@ func (r *OAuth2ClientReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error
} }
if found { if found {
//conclude reconciliation if the client exists and has not been updated
if oauth2client.Generation == oauth2client.Status.ObservedGeneration {
return ctrl.Result{}, nil
}
if fetched.Owner != fmt.Sprintf("%s/%s", oauth2client.Name, oauth2client.Namespace) { if fetched.Owner != fmt.Sprintf("%s/%s", oauth2client.Name, oauth2client.Namespace) {
conflictErr := errors.Errorf("ID provided in secret %s/%s is assigned to another resource", secret.Name, secret.Namespace) conflictErr := errors.Errorf("ID provided in secret %s/%s is assigned to another resource", secret.Name, secret.Namespace)
if updateErr := r.updateReconciliationStatusError(ctx, &oauth2client, hydrav1alpha1.StatusInvalidSecret, conflictErr); updateErr != nil { if updateErr := r.updateReconciliationStatusError(ctx, &oauth2client, hydrav1alpha1.StatusInvalidSecret, conflictErr); updateErr != nil {
@ -177,7 +180,6 @@ func (r *OAuth2ClientReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error
if registerErr := r.registerOAuth2Client(ctx, &oauth2client, credentials); registerErr != nil { if registerErr := r.registerOAuth2Client(ctx, &oauth2client, credentials); registerErr != nil {
return ctrl.Result{}, registerErr return ctrl.Result{}, registerErr
} }
}
return ctrl.Result{}, nil return ctrl.Result{}, nil
} }

View File

@ -60,6 +60,7 @@ var _ = Describe("OAuth2Client Controller", func() {
c := mgr.GetClient() c := mgr.GetClient()
mch := &mocks.HydraClientInterface{} mch := &mocks.HydraClientInterface{}
mch.On("GetOAuth2Client", Anything).Return(nil, false, nil)
mch.On("DeleteOAuth2Client", Anything).Return(nil) mch.On("DeleteOAuth2Client", Anything).Return(nil)
mch.On("ListOAuth2Client", Anything).Return(nil, nil) mch.On("ListOAuth2Client", Anything).Return(nil, nil)
mch.On("PostOAuth2Client", AnythingOfType("*hydra.OAuth2ClientJSON")).Return(func(o *hydra.OAuth2ClientJSON) *hydra.OAuth2ClientJSON { mch.On("PostOAuth2Client", AnythingOfType("*hydra.OAuth2ClientJSON")).Return(func(o *hydra.OAuth2ClientJSON) *hydra.OAuth2ClientJSON {
@ -139,6 +140,7 @@ var _ = Describe("OAuth2Client Controller", func() {
c := mgr.GetClient() c := mgr.GetClient()
mch := &mocks.HydraClientInterface{} mch := &mocks.HydraClientInterface{}
mch.On("GetOAuth2Client", Anything).Return(nil, false, nil)
mch.On("PostOAuth2Client", Anything).Return(nil, errors.New("error")) mch.On("PostOAuth2Client", Anything).Return(nil, errors.New("error"))
mch.On("DeleteOAuth2Client", Anything).Return(nil) mch.On("DeleteOAuth2Client", Anything).Return(nil)
mch.On("ListOAuth2Client", Anything).Return(nil, nil) mch.On("ListOAuth2Client", Anything).Return(nil, nil)
@ -205,6 +207,7 @@ var _ = Describe("OAuth2Client Controller", func() {
c := mgr.GetClient() c := mgr.GetClient()
mch := mocks.HydraClientInterface{} mch := mocks.HydraClientInterface{}
mch.On("GetOAuth2Client", Anything).Return(nil, false, nil)
mch.On("DeleteOAuth2Client", Anything).Return(nil) mch.On("DeleteOAuth2Client", Anything).Return(nil)
mch.On("ListOAuth2Client", Anything).Return(nil, nil) mch.On("ListOAuth2Client", Anything).Return(nil, nil)
mch.On("GetOAuth2Client", Anything).Return(nil, false, nil) mch.On("GetOAuth2Client", Anything).Return(nil, false, nil)
@ -300,6 +303,7 @@ var _ = Describe("OAuth2Client Controller", func() {
c := mgr.GetClient() c := mgr.GetClient()
mch := mocks.HydraClientInterface{} mch := mocks.HydraClientInterface{}
mch.On("GetOAuth2Client", Anything).Return(nil, false, nil)
mch.On("DeleteOAuth2Client", Anything).Return(nil) mch.On("DeleteOAuth2Client", Anything).Return(nil)
mch.On("ListOAuth2Client", Anything).Return(nil, nil) mch.On("ListOAuth2Client", Anything).Return(nil, nil)

12
main.go
View File

@ -21,6 +21,7 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"os" "os"
"time"
"github.com/ory/hydra-maester/hydra" "github.com/ory/hydra-maester/hydra"
@ -48,7 +49,7 @@ func init() {
func main() { func main() {
var ( var (
metricsAddr, hydraURL, endpoint, forwardedProto string metricsAddr, hydraURL, endpoint, forwardedProto, syncPeriod string
hydraPort int hydraPort int
enableLeaderElection bool enableLeaderElection bool
) )
@ -58,16 +59,24 @@ func main() {
flag.IntVar(&hydraPort, "hydra-port", 4445, "Port ORY Hydra is listening on") flag.IntVar(&hydraPort, "hydra-port", 4445, "Port ORY Hydra is listening on")
flag.StringVar(&endpoint, "endpoint", "/clients", "ORY Hydra's client endpoint") 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(&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(&syncPeriod, "sync-period", "10h", "Determines the minimum frequency at which watched resources are reconciled")
flag.BoolVar(&enableLeaderElection, "enable-leader-election", false, flag.BoolVar(&enableLeaderElection, "enable-leader-election", false,
"Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager.") "Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager.")
flag.Parse() flag.Parse()
ctrl.SetLogger(zap.Logger(true)) ctrl.SetLogger(zap.Logger(true))
syncPeriodParsed, err := time.ParseDuration(syncPeriod)
if err != nil {
setupLog.Error(err, "unable to start manager")
os.Exit(1)
}
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
Scheme: scheme, Scheme: scheme,
MetricsBindAddress: metricsAddr, MetricsBindAddress: metricsAddr,
LeaderElection: enableLeaderElection, LeaderElection: enableLeaderElection,
SyncPeriod: &syncPeriodParsed,
}) })
if err != nil { if err != nil {
setupLog.Error(err, "unable to start manager") setupLog.Error(err, "unable to start manager")
@ -118,7 +127,6 @@ func getHydraClientMaker(defaultSpec hydrav1alpha1.OAuth2ClientSpec) controllers
return controllers.HydraClientMakerFunc(func(spec hydrav1alpha1.OAuth2ClientSpec) (controllers.HydraClientInterface, error) { return controllers.HydraClientMakerFunc(func(spec hydrav1alpha1.OAuth2ClientSpec) (controllers.HydraClientInterface, error) {
if spec.HydraAdmin.URL == "" { if spec.HydraAdmin.URL == "" {
spec.HydraAdmin.URL = defaultSpec.HydraAdmin.URL spec.HydraAdmin.URL = defaultSpec.HydraAdmin.URL
} }