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

Provide validation for identityId with Azure pod identity & Azure AD Workload Identity in TriggerAuthentication #4696

Merged
merged 41 commits into from
Aug 29, 2023
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
9c9af60
Update
SpiritZhou Jun 16, 2023
4857d65
Update CHANGELOG.md
SpiritZhou Jun 19, 2023
15f0d6e
Merge branch 'main' into spiritzhou/checkemptyidentityid
SpiritZhou Jun 30, 2023
bcea677
Merge branch 'main' into spiritzhou/checkemptyidentityid
SpiritZhou Jul 3, 2023
6edb425
Update
SpiritZhou Jul 3, 2023
70c5a14
Add webhooks
SpiritZhou Jul 5, 2023
c74f164
Update
SpiritZhou Jul 6, 2023
31178f2
Update
SpiritZhou Jul 6, 2023
ab3d9d0
Merge branch 'main' into spiritzhou/checkemptyidentityid
SpiritZhou Jul 6, 2023
966fb35
Update
SpiritZhou Jul 6, 2023
e43e3f0
fix
SpiritZhou Jul 6, 2023
1898b7b
Update
SpiritZhou Jul 6, 2023
294a0b8
Update
SpiritZhou Jul 6, 2023
8f13085
Update
SpiritZhou Jul 6, 2023
5de4f46
Add e2e test
SpiritZhou Jul 7, 2023
42f14a1
Fix
SpiritZhou Jul 7, 2023
9538860
Update
SpiritZhou Jul 10, 2023
9847f4b
Merge branch 'main' into spiritzhou/checkemptyidentityid
SpiritZhou Jul 10, 2023
0516b70
Update CHANGELOG.md
SpiritZhou Jul 10, 2023
113b115
Update
SpiritZhou Jul 10, 2023
5b95650
Update
SpiritZhou Jul 12, 2023
a183528
Update pkg/scaling/resolver/scale_resolvers.go
SpiritZhou Jul 13, 2023
8126a33
Update
SpiritZhou Jul 13, 2023
dbebad4
Merge branch 'main' into spiritzhou/checkemptyidentityid
SpiritZhou Jul 17, 2023
e00f693
Update
SpiritZhou Jul 19, 2023
ccc4bdc
Update
SpiritZhou Jul 19, 2023
b7ce1d9
Update
SpiritZhou Aug 18, 2023
2399cb5
Merge branch 'main' into spiritzhou/checkemptyidentityid
SpiritZhou Aug 18, 2023
58d32c8
Update
SpiritZhou Aug 18, 2023
82ee9aa
Update
SpiritZhou Aug 18, 2023
f0bd980
Update
SpiritZhou Aug 18, 2023
12f1fb4
Fix order
SpiritZhou Aug 18, 2023
00a359f
Update CHANGELOG.md
SpiritZhou Aug 21, 2023
1d2344c
Update CHANGELOG.md
SpiritZhou Aug 21, 2023
dfa0e7f
Update CHANGELOG.md
SpiritZhou Aug 21, 2023
c00289d
Update CHANGELOG.md
SpiritZhou Aug 21, 2023
0f93a62
Update CHANGELOG.md
SpiritZhou Aug 21, 2023
958d41a
Merge branch 'main' into spiritzhou/checkemptyidentityid
SpiritZhou Aug 25, 2023
78307d7
Update
SpiritZhou Aug 25, 2023
7f51c4b
Merge branch 'main' into spiritzhou/checkemptyidentityid
SpiritZhou Aug 28, 2023
485fe87
Merge branch 'main' into spiritzhou/checkemptyidentityid
tomkerkhove Aug 29, 2023
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ To learn more about active deprecations, we recommend checking [GitHub Discussio

### Improvements

- **Azure Pod Identity**: Add validation of identity ID to prevent usage of empty identity ID ([#4528](https://github.com/kedacore/keda/issues/4528))
- **General:**: Add ScaledObject/ScaledJob names to output of `kubectl get triggerauthentication/clustertriggerauthentication` ([#796](https://github.com/kedacore/keda/issues/796))
SpiritZhou marked this conversation as resolved.
Show resolved Hide resolved

### Fixes
Expand Down
209 changes: 98 additions & 111 deletions apis/keda/v1alpha1/scaledobject_webhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,132 +18,119 @@ package v1alpha1

import (
"context"
"crypto/tls"
"fmt"
"net"
"path/filepath"
"testing"
"time"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
admissionv1beta1 "k8s.io/api/admission/v1beta1"
appsv1 "k8s.io/api/apps/v1"
v2 "k8s.io/api/autoscaling/v2"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
"k8s.io/utils/pointer"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/envtest"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
//+kubebuilder:scaffold:imports
)

// These tests use Ginkgo (BDD-style Go testing framework). Refer to
// http://onsi.github.io/ginkgo/ to learn more about Ginkgo.

var cfg *rest.Config
var k8sClient client.Client
var testEnv *envtest.Environment
var ctx context.Context
var cancel context.CancelFunc

const (
workloadName = "deployment-name"
soName = "test-so"
)

func TestAPIs(t *testing.T) {
RegisterFailHandler(Fail)

RunSpecs(t, "Webhook Suite")
}

var _ = BeforeSuite(func() {
logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true)))

ctx, cancel = context.WithCancel(context.Background())

By("bootstrapping test environment")
testEnv = &envtest.Environment{
CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")},
ErrorIfCRDPathMissing: false,
WebhookInstallOptions: envtest.WebhookInstallOptions{
Paths: []string{filepath.Join("..", "..", "..", "config", "webhooks")},
},
}

var err error
// cfg is defined in this file globally.
done := make(chan interface{})
go func() {
defer GinkgoRecover()
cfg, err = testEnv.Start()
close(done)
}()
Eventually(done).WithTimeout(time.Minute).Should(BeClosed())
Expect(err).NotTo(HaveOccurred())
Expect(cfg).NotTo(BeNil())

scheme := runtime.NewScheme()
err = AddToScheme(scheme)
Expect(err).NotTo(HaveOccurred())

err = clientgoscheme.AddToScheme(scheme)
Expect(err).NotTo(HaveOccurred())

err = admissionv1beta1.AddToScheme(scheme)
Expect(err).NotTo(HaveOccurred())

//+kubebuilder:scaffold:scheme

k8sClient, err = client.New(cfg, client.Options{Scheme: scheme})
Expect(err).NotTo(HaveOccurred())
Expect(k8sClient).NotTo(BeNil())

// start webhook server using Manager
webhookInstallOptions := &testEnv.WebhookInstallOptions
mgr, err := ctrl.NewManager(cfg, ctrl.Options{
Scheme: scheme,
Host: webhookInstallOptions.LocalServingHost,
Port: webhookInstallOptions.LocalServingPort,
CertDir: webhookInstallOptions.LocalServingCertDir,
LeaderElection: false,
MetricsBindAddress: "0",
})
Expect(err).NotTo(HaveOccurred())

err = (&ScaledObject{}).SetupWebhookWithManager(mgr)
Expect(err).NotTo(HaveOccurred())

//+kubebuilder:scaffold:webhook

go func() {
defer GinkgoRecover()
err = mgr.Start(ctx)
Expect(err).NotTo(HaveOccurred())
}()

// wait for the webhook server to get ready
dialer := &net.Dialer{Timeout: time.Second}
addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort)
Eventually(func() error {
conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true})
if err != nil {
return err
}
conn.Close()
return nil
}).Should(Succeed())

})
// var cfg *rest.Config
SpiritZhou marked this conversation as resolved.
Show resolved Hide resolved
// var k8sClient client.Client
// var testEnv *envtest.Environment
// var ctx context.Context
// var cancel context.CancelFunc

// const (
// workloadName = "deployment-name"
// soName = "test-so"
// )

// func TestAPIs(t *testing.T) {
// RegisterFailHandler(Fail)

// RunSpecs(t, "Webhook Suite")
// }

// var _ = BeforeSuite(func() {
// logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true)))

// ctx, cancel = context.WithCancel(context.Background())

// By("bootstrapping test environment")
// testEnv = &envtest.Environment{
// CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")},
// ErrorIfCRDPathMissing: false,
// WebhookInstallOptions: envtest.WebhookInstallOptions{
// Paths: []string{filepath.Join("..", "..", "..", "config", "webhooks")},
// },
// }
// fmt.Println("xxxxxxxxxxf")
// var err error
// // cfg is defined in this file globally.
// done := make(chan interface{})
// go func() {
// defer GinkgoRecover()
// cfg, err = testEnv.Start()
// close(done)
// }()
// Eventually(done).WithTimeout(time.Minute).Should(BeClosed())
// Expect(err).NotTo(HaveOccurred())
// Expect(cfg).NotTo(BeNil())

// scheme := runtime.NewScheme()
// err = AddToScheme(scheme)
// Expect(err).NotTo(HaveOccurred())

// err = clientgoscheme.AddToScheme(scheme)
// Expect(err).NotTo(HaveOccurred())

// err = admissionv1beta1.AddToScheme(scheme)
// Expect(err).NotTo(HaveOccurred())

// //+kubebuilder:scaffold:scheme

// k8sClient, err = client.New(cfg, client.Options{Scheme: scheme})
// Expect(err).NotTo(HaveOccurred())
// Expect(k8sClient).NotTo(BeNil())

// // start webhook server using Manager
// webhookInstallOptions := &testEnv.WebhookInstallOptions
// mgr, err := ctrl.NewManager(cfg, ctrl.Options{
// Scheme: scheme,
// Host: webhookInstallOptions.LocalServingHost,
// Port: webhookInstallOptions.LocalServingPort,
// CertDir: webhookInstallOptions.LocalServingCertDir,
// LeaderElection: false,
// MetricsBindAddress: "0",
// })
// Expect(err).NotTo(HaveOccurred())

// err = (&ScaledObject{}).SetupWebhookWithManager(mgr)
// Expect(err).NotTo(HaveOccurred())

// err = (&TriggerAuthentication{}).SetupWebhookWithManager(mgr)
// Expect(err).NotTo(HaveOccurred())

// //+kubebuilder:scaffold:webhook

// go func() {
// defer GinkgoRecover()
// err = mgr.Start(ctx)
// Expect(err).NotTo(HaveOccurred())
// }()

// // wait for the webhook server to get ready
// dialer := &net.Dialer{Timeout: time.Second}
// addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort)
// Eventually(func() error {
// conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true})
// if err != nil {
// return err
// }
// conn.Close()
// return nil
// }).Should(Succeed())

// })

var _ = It("should validate the so creation when there isn't any hpa", func() {

Expand Down
141 changes: 141 additions & 0 deletions apis/keda/v1alpha1/suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/*
Copyright 2023 The KEDA Authors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha1

import (
"context"
"crypto/tls"
"fmt"
"net"
"path/filepath"
"testing"
"time"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
admissionv1beta1 "k8s.io/api/admission/v1beta1"
"k8s.io/apimachinery/pkg/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/envtest"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
)

// These tests use Ginkgo (BDD-style Go testing framework). Refer to
// http://onsi.github.io/ginkgo/ to learn more about Ginkgo.

var cfg *rest.Config
var k8sClient client.Client
var testEnv *envtest.Environment
var ctx context.Context
var cancel context.CancelFunc

const (
workloadName = "deployment-name"
soName = "test-so"
)

func TestAPIs(t *testing.T) {
RegisterFailHandler(Fail)

RunSpecs(t, "Webhook Suite")
}

var _ = BeforeSuite(func() {
logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true)))

ctx, cancel = context.WithCancel(context.Background())

By("bootstrapping test environment")
testEnv = &envtest.Environment{
CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")},
ErrorIfCRDPathMissing: false,
WebhookInstallOptions: envtest.WebhookInstallOptions{
Paths: []string{filepath.Join("..", "..", "..", "config", "webhooks")},
},
}
var err error
// cfg is defined in this file globally.
done := make(chan interface{})
go func() {
defer GinkgoRecover()
cfg, err = testEnv.Start()
close(done)
}()
Eventually(done).WithTimeout(time.Minute).Should(BeClosed())
Expect(err).NotTo(HaveOccurred())
Expect(cfg).NotTo(BeNil())

scheme := runtime.NewScheme()
err = AddToScheme(scheme)
Expect(err).NotTo(HaveOccurred())

err = clientgoscheme.AddToScheme(scheme)
Expect(err).NotTo(HaveOccurred())

err = admissionv1beta1.AddToScheme(scheme)
Expect(err).NotTo(HaveOccurred())

//+kubebuilder:scaffold:scheme

k8sClient, err = client.New(cfg, client.Options{Scheme: scheme})
Expect(err).NotTo(HaveOccurred())
Expect(k8sClient).NotTo(BeNil())

// start webhook server using Manager
webhookInstallOptions := &testEnv.WebhookInstallOptions
mgr, err := ctrl.NewManager(cfg, ctrl.Options{
Scheme: scheme,
Host: webhookInstallOptions.LocalServingHost,
Port: webhookInstallOptions.LocalServingPort,
CertDir: webhookInstallOptions.LocalServingCertDir,
LeaderElection: false,
MetricsBindAddress: "0",
})
Expect(err).NotTo(HaveOccurred())

err = (&ScaledObject{}).SetupWebhookWithManager(mgr)
Expect(err).NotTo(HaveOccurred())
err = (&TriggerAuthentication{}).SetupWebhookWithManager(mgr)
Expect(err).NotTo(HaveOccurred())
err = (&ClusterTriggerAuthentication{}).SetupWebhookWithManager(mgr)
Expect(err).NotTo(HaveOccurred())

//+kubebuilder:scaffold:webhook

go func() {
defer GinkgoRecover()
err = mgr.Start(ctx)
Expect(err).NotTo(HaveOccurred())
}()

// wait for the webhook server to get ready
dialer := &net.Dialer{Timeout: time.Second}
addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort)
Eventually(func() error {
conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true})
if err != nil {
return err
}
conn.Close()
return nil
}).Should(Succeed())

})
9 changes: 8 additions & 1 deletion apis/keda/v1alpha1/triggerauthentication_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,14 @@ const (
type AuthPodIdentity struct {
Provider PodIdentityProvider `json:"provider"`
// +optional
IdentityID string `json:"identityId"`
IdentityID *string `json:"identityId"`
}

func (a *AuthPodIdentity) GetIdentityID() string {
if a.IdentityID == nil {
return ""
}
return *a.IdentityID
}

// AuthSecretTargetRef is used to authenticate using a reference to a secret
Expand Down
Loading