diff --git a/go.mod b/go.mod index a01bcb5183fb..d257906b2f4c 100644 --- a/go.mod +++ b/go.mod @@ -24,7 +24,7 @@ require ( github.com/onsi/ginkgo/v2 v2.9.5 github.com/onsi/gomega v1.27.7 github.com/opencontainers/go-digest v1.0.0 - github.com/openshift/api v0.0.0-20231205121914-b5716b30456a + github.com/openshift/api v0.0.0-20240522145529-93d6bda14341 github.com/openshift/apiserver-library-go v0.0.0-20230927115548-521857444d9a github.com/openshift/build-machinery-go v0.0.0-20220913142420-e25cf57ea46d github.com/openshift/client-go v0.0.0-20230926161409-848405da69e1 diff --git a/go.sum b/go.sum index be8546591bb7..168bed3bbe18 100644 --- a/go.sum +++ b/go.sum @@ -660,8 +660,8 @@ github.com/opencontainers/runtime-spec v1.0.3-0.20220909204839-494a5a6aca78 h1:R github.com/opencontainers/runtime-spec v1.0.3-0.20220909204839-494a5a6aca78/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/selinux v1.10.0 h1:rAiKF8hTcgLI3w0DHm6i0ylVVcOrlgR1kK99DRLDhyU= github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= -github.com/openshift/api v0.0.0-20231205121914-b5716b30456a h1:HdOIa5C84YZaiJ70IdPf5W0JUGOLjxCwf1PTPLpJ0QY= -github.com/openshift/api v0.0.0-20231205121914-b5716b30456a/go.mod h1:qNtV0315F+f8ld52TLtPvrfivZpdimOzTi3kn9IVbtU= +github.com/openshift/api v0.0.0-20240522145529-93d6bda14341 h1:JQpzgk+p24rkgNbNsrNR0yLm63WTKapuT60INU5BqT8= +github.com/openshift/api v0.0.0-20240522145529-93d6bda14341/go.mod h1:qNtV0315F+f8ld52TLtPvrfivZpdimOzTi3kn9IVbtU= github.com/openshift/apiserver-library-go v0.0.0-20230927115548-521857444d9a h1:fctOjlrMbnzle+zkEj04NVO9oZn7PY4ePlSrQc8e+CY= github.com/openshift/apiserver-library-go v0.0.0-20230927115548-521857444d9a/go.mod h1:1EYKLn9Noff0qebQdZghEtZDYNySM575P5Xo8WnB+Lk= github.com/openshift/build-machinery-go v0.0.0-20220913142420-e25cf57ea46d h1:RR4ah7FfaPR1WePizm0jlrsbmPu91xQZnAsVVreQV1k= diff --git a/test/extended/router/stress.go b/test/extended/router/stress.go index ee9e375e5791..dad54a855a91 100644 --- a/test/extended/router/stress.go +++ b/test/extended/router/stress.go @@ -8,6 +8,7 @@ import ( "text/tabwriter" "time" + "github.com/google/go-cmp/cmp" g "github.com/onsi/ginkgo/v2" o "github.com/onsi/gomega" e2eoutput "k8s.io/kubernetes/test/e2e/framework/pod/output" @@ -17,15 +18,19 @@ import ( corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/apimachinery/pkg/watch" clientset "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/cache" e2e "k8s.io/kubernetes/test/e2e/framework" admissionapi "k8s.io/pod-security-admission/api" routev1 "github.com/openshift/api/route/v1" routeclientset "github.com/openshift/client-go/route/clientset/versioned" + v1 "github.com/openshift/client-go/route/clientset/versioned/typed/route/v1" exutil "github.com/openshift/origin/test/extended/util" ) @@ -79,15 +84,17 @@ var _ = g.Describe("[sig-network][Feature:Router][apigroup:route.openshift.io]", g.Describe("The HAProxy router", func() { g.It("converges when multiple routers are writing status", func() { g.By("deploying a scaled out namespace scoped router") + routerName := "namespaced" rs, err := oc.KubeClient().AppsV1().ReplicaSets(ns).Create( context.Background(), scaledRouter( + "router", routerImage, []string{ "-v=4", fmt.Sprintf("--namespace=%s", ns), "--resync-interval=2m", - "--name=namespaced", + fmt.Sprintf("--name=%s", routerName), }, ), metav1.CreateOptions{}, @@ -98,24 +105,16 @@ var _ = g.Describe("[sig-network][Feature:Router][apigroup:route.openshift.io]", g.By("creating multiple routes") client := routeclientset.NewForConfigOrDie(oc.AdminConfig()).RouteV1().Routes(ns) - var rv string - for i := 0; i < 10; i++ { - _, err := client.Create(context.Background(), &routev1.Route{ - ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf("%d", i), - }, - Spec: routev1.RouteSpec{ - To: routev1.RouteTargetReference{Name: "test"}, - Port: &routev1.RoutePort{ - TargetPort: intstr.FromInt(8080), - }, - }, - }, metav1.CreateOptions{}) - o.Expect(err).NotTo(o.HaveOccurred()) - } + + // Start recording updates BEFORE the routes get created, so we capture all the updates. + err, stopRecordingRouteUpdates, updateCountCh := startRecordingRouteStatusUpdates(client, routerName, "") + o.Expect(err).NotTo(o.HaveOccurred()) + + err = createTestRoutes(client, 10) + o.Expect(err).NotTo(o.HaveOccurred()) g.By("waiting for all routes to have a status") - err = wait.Poll(time.Second, 2*time.Minute, func() (bool, error) { + err = wait.Poll(5*time.Second, 2*time.Minute, func() (bool, error) { routes, err := client.List(context.Background(), metav1.ListOptions{}) if err != nil { return false, err @@ -133,46 +132,34 @@ var _ = g.Describe("[sig-network][Feature:Router][apigroup:route.openshift.io]", o.Expect(ingress.Conditions[0].Status).To(o.Equal(corev1.ConditionTrue)) } outputIngress(routes.Items...) - rv = routes.ResourceVersion return true, nil }) o.Expect(err).NotTo(o.HaveOccurred()) g.By("verifying that we don't continue to write") - writes := 0 - w, err := client.Watch(context.Background(), metav1.ListOptions{Watch: true, ResourceVersion: rv}) + err, writes := waitForRouteStatusUpdates(stopRecordingRouteUpdates, updateCountCh, 15*time.Second) o.Expect(err).NotTo(o.HaveOccurred()) - defer w.Stop() - timer := time.NewTimer(10 * time.Second) - ch := w.ResultChan() - Wait: - for i := 0; ; i++ { - select { - case _, ok := <-ch: - writes++ - o.Expect(ok).To(o.BeTrue()) - case <-timer.C: - break Wait - } - } - o.Expect(writes).To(o.BeNumerically("<=", 10)) + // Number of writes should be exactly equal to ten because there are only 10 routes to update. + o.Expect(writes).To(o.BeNumerically("==", 10)) verifyCommandEquivalent(oc.KubeClient(), rs, "md5sum /var/lib/haproxy/conf/*") }) g.It("converges when multiple routers are writing conflicting status", func() { g.By("deploying a scaled out namespace scoped router") - + routerName := "conflicting" + numOfRoutes := 20 rs, err := oc.KubeClient().AppsV1().ReplicaSets(ns).Create( context.Background(), scaledRouter( + "router", routerImage, []string{ "-v=4", fmt.Sprintf("--namespace=%s", ns), - // the contention tracker is resync / 10, so this will give us 2 minutes of contention tracking - "--resync-interval=20m", - "--name=conflicting", + // Make resync interval high to avoid contention flushes. + "--resync-interval=24h", + fmt.Sprintf("--name=%s", routerName), "--override-hostname", // causes each pod to have a different value "--hostname-template=${name}-${namespace}.$(NAME).local", @@ -184,44 +171,29 @@ var _ = g.Describe("[sig-network][Feature:Router][apigroup:route.openshift.io]", err = waitForReadyReplicaSet(oc.KubeClient(), ns, rs.Name) o.Expect(err).NotTo(o.HaveOccurred()) - g.By("creating multiple routes") client := routeclientset.NewForConfigOrDie(oc.AdminConfig()).RouteV1().Routes(ns) - var rv string - for i := 0; i < 20; i++ { - _, err := client.Create(context.Background(), &routev1.Route{ - ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf("%d", i), - }, - Spec: routev1.RouteSpec{ - To: routev1.RouteTargetReference{Name: "test"}, - Port: &routev1.RoutePort{ - TargetPort: intstr.FromInt(8080), - }, - }, - }, metav1.CreateOptions{}) - o.Expect(err).NotTo(o.HaveOccurred()) - } + + // Start recording updates BEFORE the routes get created, so we capture all the updates. + err, stopRecordingRouteUpdates, updateCountCh := startRecordingRouteStatusUpdates(client, routerName, "") + o.Expect(err).NotTo(o.HaveOccurred()) + + g.By("creating multiple routes") + err = createTestRoutes(client, numOfRoutes) + o.Expect(err).NotTo(o.HaveOccurred()) g.By("waiting for sufficient routes to have a status") - err = wait.Poll(time.Second, 2*time.Minute, func() (bool, error) { + err = wait.Poll(5*time.Second, 2*time.Minute, func() (bool, error) { routes, err := client.List(context.Background(), metav1.ListOptions{}) if err != nil { return false, err } - o.Expect(routes.Items).To(o.HaveLen(20)) - other := 0 + o.Expect(routes.Items).To(o.HaveLen(numOfRoutes)) conflicting := 0 for _, route := range routes.Items { - ingress := findIngress(&route, "conflicting") + ingress := findIngress(&route, routerName) if ingress == nil { - if len(route.Status.Ingress) > 0 { - other++ - } continue } - if len(route.Status.Ingress) > 1 { - other++ - } conflicting++ o.Expect(ingress.Host).NotTo(o.BeEmpty()) o.Expect(ingress.Conditions).NotTo(o.BeEmpty()) @@ -229,75 +201,307 @@ var _ = g.Describe("[sig-network][Feature:Router][apigroup:route.openshift.io]", o.Expect(ingress.Conditions[0].Type).To(o.Equal(routev1.RouteAdmitted)) o.Expect(ingress.Conditions[0].Status).To(o.Equal(corev1.ConditionTrue)) } - // if other routers are writing status, wait until we get a complete - // set since we don't have a way to tell other routers to ignore us - if conflicting < 3 && other%20 != 0 { + // We will wait until all routes get an ingress status for conflicting. + if conflicting != numOfRoutes { + e2e.Logf("waiting for %d ingresses for %q, got %d", numOfRoutes, routerName, conflicting) return false, nil } outputIngress(routes.Items...) - rv = routes.ResourceVersion return true, nil }) o.Expect(err).NotTo(o.HaveOccurred()) g.By("verifying that we stop writing conflicts rapidly") - writes := 0 - w, err := client.Watch(context.Background(), metav1.ListOptions{Watch: true, ResourceVersion: rv}) + + // Start recording updates BEFORE the routes get created, so we capture all the updates. + err, writes := waitForRouteStatusUpdates(stopRecordingRouteUpdates, updateCountCh, 30*time.Second) o.Expect(err).NotTo(o.HaveOccurred()) - func() { - defer w.Stop() - timer := time.NewTimer(15 * time.Second) - ch := w.ResultChan() - Wait: - for i := 0; ; i++ { - select { - case _, ok := <-ch: - writes++ - o.Expect(ok).To(o.BeTrue()) - case <-timer.C: - break Wait - } - } - // we expect to see no more than 10 writes per router (we should hit the hard limit) (3 replicas and 1 master) - o.Expect(writes).To(o.BeNumerically("<=", 50)) - }() + + // First, we expect at least 20 writes for 20 routes, as every route should get a conflicting status. + // Next, we expect 1-2 more writes per route until per-route contention activates. + // Next, we expect the maxContention logic to activate and stop all updates when the routers detect > 5 + // contentions. + // In total, we expect around 30-35 writes, but we generously allow for up to 50 writes to accommodate for + // minor discrepancies in contention tracker logic. + o.Expect(writes).To(o.BeNumerically(">=", numOfRoutes)) + o.Expect(writes).To(o.BeNumerically("<=", 50)) // the os_http_be.map file will vary, so only check the haproxy config verifyCommandEquivalent(oc.KubeClient(), rs, "md5sum /var/lib/haproxy/conf/haproxy.config") g.By("clearing a single route's status") - route, err := client.Patch(context.Background(), "9", types.MergePatchType, []byte(`{"status":{"ingress":[]}}`), metav1.PatchOptions{}, "status") + // Start recording updates BEFORE the route gets updated, so we capture all the updates. + err, stopRecordingRouteUpdates, updateCountCh = startRecordingRouteStatusUpdates(client, routerName, "9") + o.Expect(err).NotTo(o.HaveOccurred()) + + _, err = client.Patch(context.Background(), "9", types.MergePatchType, []byte(`{"status":{"ingress":[]}}`), metav1.PatchOptions{}, "status") o.Expect(err).NotTo(o.HaveOccurred()) g.By("verifying that only get a few updates") - writes = 0 - w, err = client.Watch(context.Background(), metav1.ListOptions{Watch: true, ResourceVersion: route.ResourceVersion}) + err, writes = waitForRouteStatusUpdates(stopRecordingRouteUpdates, updateCountCh, 15*time.Second) + o.Expect(err).NotTo(o.HaveOccurred()) + // Ideally, this should be at least 1 write (our patch). MaxContentions should have kicked in for most + // routers so the updates should be limited. + o.Expect(writes).To(o.BeNumerically(">=", 1)) + o.Expect(writes).To(o.BeNumerically("<=", 5)) + }) + + g.It("converges when multiple routers are writing conflicting upgrade validation status", func() { + g.By("deploying a scaled out namespace scoped router that adds the UnservableInFutureVersions condition") + + routerName := "conflicting" + numOfRoutes := 20 + rsAdd, err := oc.KubeClient().AppsV1().ReplicaSets(ns).Create( + context.Background(), + scaledRouter( + "router-add-condition", + routerImage, + []string{ + "-v=5", + fmt.Sprintf("--namespace=%s", ns), + // Make resync interval high to avoid contention flushes. + "--resync-interval=24h", + fmt.Sprintf("--name=%s", routerName), + "--debug-upgrade-validation-force-add-condition", + }, + ), + metav1.CreateOptions{}, + ) + o.Expect(err).NotTo(o.HaveOccurred()) + err = waitForReadyReplicaSet(oc.KubeClient(), ns, rsAdd.Name) + o.Expect(err).NotTo(o.HaveOccurred()) + + g.By("creating multiple routes") + client := routeclientset.NewForConfigOrDie(oc.AdminConfig()).RouteV1().Routes(ns) + err = createTestRoutes(client, numOfRoutes) o.Expect(err).NotTo(o.HaveOccurred()) - func() { - defer w.Stop() - timer := time.NewTimer(10 * time.Second) - ch := w.ResultChan() - Wait: - for i := 0; ; i++ { - select { - case obj, ok := <-ch: - o.Expect(ok).To(o.BeTrue()) - if r, ok := obj.Object.(*routev1.Route); ok { - if r == nil || r.Name != "9" { - continue - } - } - writes++ - case <-timer.C: - break Wait + + g.By("waiting for sufficient routes to have a UnservableInFutureVersions and Admitted status condition") + err = wait.PollUntilContextTimeout(context.Background(), 10*time.Second, 10*time.Minute, false, func(ctx context.Context) (bool, error) { + routes, err := client.List(ctx, metav1.ListOptions{}) + if err != nil { + e2e.Logf("failed to list routes: %v", err) + return false, nil + } + o.Expect(routes.Items).To(o.HaveLen(numOfRoutes)) + unservableCondition := 0 + admittedCondition := 0 + for _, route := range routes.Items { + ingress := findIngress(&route, routerName) + if ingress == nil { + continue } + // Find UnservableInFutureVersions condition. + if cond := findIngressCondition(ingress, routev1.RouteUnservableInFutureVersions); cond != nil { + unservableCondition++ + o.Expect(ingress.Host).NotTo(o.BeEmpty()) + o.Expect(ingress.Conditions).NotTo(o.BeEmpty()) + o.Expect(cond.LastTransitionTime).NotTo(o.BeNil()) + o.Expect(cond.Status).To(o.Equal(corev1.ConditionTrue)) + } + // Find Admitted condition. + if cond := findIngressCondition(ingress, routev1.RouteAdmitted); cond != nil { + admittedCondition++ + o.Expect(ingress.Host).NotTo(o.BeEmpty()) + o.Expect(ingress.Conditions).NotTo(o.BeEmpty()) + o.Expect(cond.LastTransitionTime).NotTo(o.BeNil()) + o.Expect(cond.Status).To(o.Equal(corev1.ConditionTrue)) + } + } + // Wait for both conditions to be on all routes. + if unservableCondition != numOfRoutes || admittedCondition != numOfRoutes { + e2e.Logf("waiting for %d conditions for %q, got UnservableInFutureVersions=%d and Admitted=%d", numOfRoutes, routerName, unservableCondition, admittedCondition) + return false, nil + } + outputIngress(routes.Items...) + return true, nil + }) + o.Expect(err).NotTo(o.HaveOccurred()) + + // Start recording updates BEFORE the second router that removes the conditions gets created, + // so we capture all the updates. + err, stopRecordingRouteUpdates, updateCountCh := startRecordingRouteStatusUpdates(client, routerName, "") + o.Expect(err).NotTo(o.HaveOccurred()) + + g.By("deploying a scaled out namespace scoped router that removes the UnservableInFutureVersions condition") + rsRemove, err := oc.KubeClient().AppsV1().ReplicaSets(ns).Create( + context.Background(), + scaledRouter( + "router-remove-condition", + routerImage, + []string{ + "-v=5", + fmt.Sprintf("--namespace=%s", ns), + // Make resync interval high to avoid contention flushes. + "--resync-interval=24h", + fmt.Sprintf("--name=%s", routerName), + "--debug-upgrade-validation-force-remove-condition", + }, + ), + metav1.CreateOptions{}, + ) + o.Expect(err).NotTo(o.HaveOccurred()) + err = waitForReadyReplicaSet(oc.KubeClient(), ns, rsRemove.Name) + o.Expect(err).NotTo(o.HaveOccurred()) + + g.By("verifying that we stop writing conflicts rapidly") + err, writes := waitForRouteStatusUpdates(stopRecordingRouteUpdates, updateCountCh, 30*time.Second) + o.Expect(err).NotTo(o.HaveOccurred()) + + // Ideally, we expect at least 20 writes for 20 routes, as the router-add-condition routers already consider + // all routes a candidate for contention. When router-remove-condition begins to remove these conditions, + // the router-add-condition routers should immediately consider each route as contended and won't attempt to + // add the condition back. However, a few additional conflicting writes might occur if the contention + // tracker is late in detecting route writes. Therefore, we generously allow for up to 50 writes to + // accommodate these discrepancies. + o.Expect(writes).To(o.BeNumerically(">=", numOfRoutes)) + o.Expect(writes).To(o.BeNumerically("<=", 50)) + + g.By("toggling a single route's status condition") + + // Start recording updates BEFORE the route gets modified, so we capture all the updates. + err, stopRecordingRouteUpdates, updateCountCh = startRecordingRouteStatusUpdates(client, routerName, "9") + o.Expect(err).NotTo(o.HaveOccurred()) + + // Though it is highly likely that the router-remove-conditions won the conflict and the condition is + // removed, we will be safe and not make that assumption. We will add or remove the condition based on its + // presence. + route9, err := client.Get(context.Background(), "9", metav1.GetOptions{}) + o.Expect(err).NotTo(o.HaveOccurred()) + route9Ingress := findIngress(route9, routerName) + if cond := findIngressCondition(route9Ingress, routev1.RouteUnservableInFutureVersions); cond != nil { + e2e.Logf("removing %q condition from route %q", routev1.RouteUnservableInFutureVersions, route9.Name) + removeIngressCondition(route9Ingress, routev1.RouteUnservableInFutureVersions) + } else { + e2e.Logf("adding %q condition to route %q", routev1.RouteUnservableInFutureVersions, route9.Name) + cond := routev1.RouteIngressCondition{ + Type: routev1.RouteUnservableInFutureVersions, + Status: corev1.ConditionFalse, + Message: "foo", + Reason: "foo", } - o.Expect(writes).To(o.BeNumerically("<", 5)) - }() + route9Ingress.Conditions = append(route9Ingress.Conditions, cond) + } + + route9, err = client.UpdateStatus(context.Background(), route9, metav1.UpdateOptions{}) + o.Expect(err).NotTo(o.HaveOccurred()) + + g.By("verifying that only get a few updates") + err, writes = waitForRouteStatusUpdates(stopRecordingRouteUpdates, updateCountCh, 15*time.Second) + o.Expect(err).NotTo(o.HaveOccurred()) + // Ideally, this should be 1 write. If we are adding the status condition, then the router-remove-condition + // routers should now consider the route contended. If we are removing the status condition, then the + // router-add-conditions should already consider the route contended and/or have reach max contentions. + // Though its very unlikely, we allow up to 5 writes for discrepancies in slow contention tracking. + o.Expect(writes).To(o.BeNumerically(">=", 1)) + o.Expect(writes).To(o.BeNumerically("<=", 5)) }) }) }) +// waitForRouteStatusUpdates waits for an observation time, then calls the context.CancelFunc, +// and receives the update count from the provided channel. +func waitForRouteStatusUpdates(stopRecordingRouteUpdates context.CancelFunc, updateCountCh <-chan int, observeTime time.Duration) (error, int) { + // Wait for the observation. + time.AfterFunc(observeTime, func() { stopRecordingRouteUpdates() }) + + // Set a timeout for receiving the updateCount. + timeout := time.After(1 * time.Minute) + + select { + case updates := <-updateCountCh: + e2e.Logf("recorded %d route updates", updates) + return nil, updates + case <-timeout: + return fmt.Errorf("timeout waiting for the update count to be received"), 0 + } +} + +// startRecordingRouteStatusUpdates starts an informer in a separate go routine that monitors route status updates +// for a specific routerName. The informer can be stopped with the returned context.CancelFunc. The returned channel +// receives counts of route status updates. Updates can be filtered by a routeNameMatch, if specified. +func startRecordingRouteStatusUpdates(client v1.RouteInterface, routerName string, routeNameMatch string) (error, context.CancelFunc, <-chan int) { + lw := &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + return client.List(context.Background(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + return client.Watch(context.Background(), options) + }, + } + + updateCount := 0 + informer := cache.NewSharedIndexInformer(lw, &routev1.Route{}, 0, nil) + _, err := informer.AddEventHandler(cache.ResourceEventHandlerFuncs{ + UpdateFunc: func(oldObj, obj interface{}) { + oldRoute, ok := oldObj.(*routev1.Route) + if !ok { + return + } + route, ok := obj.(*routev1.Route) + if !ok { + return + } + if routeNameMatch != "" { + if route.Name != routeNameMatch { + return + } + } + oldRouteIngress := findIngress(oldRoute, routerName) + routeIngress := findIngress(route, routerName) + + if diff := cmp.Diff(oldRouteIngress, routeIngress); diff != "" { + updateCount++ + e2e.Logf("route ingress status updated, router: %s, write count: %d, diff: %s", routerName, updateCount, diff) + } else { + diff := cmp.Diff(oldRoute, route) + e2e.Logf("not counting route update because route ingress status is the same, route diff: %s", diff) + } + }, + }) + if err != nil { + return err, nil, nil + } + + ctx, stopRecordingRouteUpdates := context.WithCancel(context.Background()) + updateCountCh := make(chan int) + + // Start the informer and handle context cancellation. + go func() { + informer.Run(ctx.Done()) + updateCountCh <- updateCount + close(updateCountCh) + }() + + return nil, stopRecordingRouteUpdates, updateCountCh +} + +// createTestRoutes creates test routes with the name as the index number +// and returns errors if not successful. +func createTestRoutes(client v1.RouteInterface, numOfRoutes int) error { + var errs []error + for i := 0; i < numOfRoutes; i++ { + _, err := client.Create(context.Background(), &routev1.Route{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("%d", i), + }, + Spec: routev1.RouteSpec{ + To: routev1.RouteTargetReference{Name: "test"}, + Port: &routev1.RoutePort{ + TargetPort: intstr.FromInt(8080), + }, + }, + }, metav1.CreateOptions{}) + if err != nil { + errs = append(errs, fmt.Errorf("failed to create route %d: %w", i, err)) + } + } + if len(errs) > 0 { + return fmt.Errorf("multiple errors occurred: %v", errs) + } + return nil +} + func findIngress(route *routev1.Route, name string) *routev1.RouteIngress { for i, ingress := range route.Status.Ingress { if ingress.RouterName == name { @@ -307,21 +511,41 @@ func findIngress(route *routev1.Route, name string) *routev1.RouteIngress { return nil } -func scaledRouter(image string, args []string) *appsv1.ReplicaSet { +// findIngressCondition locates the first condition that corresponds to the requested type. +func findIngressCondition(ingress *routev1.RouteIngress, t routev1.RouteIngressConditionType) (_ *routev1.RouteIngressCondition) { + for i := range ingress.Conditions { + if ingress.Conditions[i].Type == t { + return &ingress.Conditions[i] + } + } + return nil +} + +// removeIngressCondition removes a condition of type t from the ingress conditions +func removeIngressCondition(ingress *routev1.RouteIngress, t routev1.RouteIngressConditionType) { + for i, v := range ingress.Conditions { + if v.Type == t { + ingress.Conditions = append(ingress.Conditions[:i], ingress.Conditions[i+1:]...) + return + } + } +} + +func scaledRouter(name, image string, args []string) *appsv1.ReplicaSet { one := int64(1) scale := int32(3) return &appsv1.ReplicaSet{ ObjectMeta: metav1.ObjectMeta{ - Name: "router", + Name: name, }, Spec: appsv1.ReplicaSetSpec{ Replicas: &scale, Selector: &metav1.LabelSelector{ - MatchLabels: map[string]string{"app": "router"}, + MatchLabels: map[string]string{"app": name}, }, Template: corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ - Labels: map[string]string{"app": "router"}, + Labels: map[string]string{"app": name}, }, Spec: corev1.PodSpec{ TerminationGracePeriodSeconds: &one, @@ -344,16 +568,31 @@ func scaledRouter(image string, args []string) *appsv1.ReplicaSet { func outputIngress(routes ...routev1.Route) { b := &bytes.Buffer{} w := tabwriter.NewWriter(b, 0, 0, 2, ' ', 0) - fmt.Fprintf(w, "NAME\tROUTER\tHOST\tLAST TRANSITION\n") + fmt.Fprintf(w, "NAME\tROUTER\tHOST\tCONDITIONS\tLAST TRANSITION\n") for _, route := range routes { for _, ingress := range route.Status.Ingress { - fmt.Fprintf(w, "%s\t%s\t%s\t%s\n", route.Name, ingress.RouterName, ingress.Host, ingress.Conditions[0].LastTransitionTime) + conditions := "" + for _, condition := range ingress.Conditions { + conditions += fmt.Sprintf("%s=%s ", condition.Type, condition.Status) + } + fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n", route.Name, ingress.RouterName, ingress.Host, conditions, findMostRecentConditionTime(ingress.Conditions)) } } w.Flush() e2e.Logf("Routes:\n%s", b.String()) } +// findMostRecentConditionTime returns the time of the most recent condition. +func findMostRecentConditionTime(conditions []routev1.RouteIngressCondition) time.Time { + var recent time.Time + for j := range conditions { + if conditions[j].LastTransitionTime != nil && conditions[j].LastTransitionTime.Time.After(recent) { + recent = conditions[j].LastTransitionTime.Time + } + } + return recent +} + func verifyCommandEquivalent(c clientset.Interface, rs *appsv1.ReplicaSet, cmd string) { selector, err := metav1.LabelSelectorAsSelector(rs.Spec.Selector) o.Expect(err).NotTo(o.HaveOccurred()) diff --git a/test/extended/util/annotate/generated/zz_generated.annotations.go b/test/extended/util/annotate/generated/zz_generated.annotations.go index e80f4b4f5378..2dd8963fcffe 100644 --- a/test/extended/util/annotate/generated/zz_generated.annotations.go +++ b/test/extended/util/annotate/generated/zz_generated.annotations.go @@ -1367,6 +1367,8 @@ var Annotations = map[string]string{ "[sig-network][Feature:Router][apigroup:route.openshift.io] The HAProxy router converges when multiple routers are writing conflicting status": " [Suite:openshift/conformance/parallel]", + "[sig-network][Feature:Router][apigroup:route.openshift.io] The HAProxy router converges when multiple routers are writing conflicting upgrade validation status": " [Suite:openshift/conformance/parallel]", + "[sig-network][Feature:Router][apigroup:route.openshift.io] The HAProxy router converges when multiple routers are writing status": " [Suite:openshift/conformance/parallel]", "[sig-network][Feature:Router][apigroup:route.openshift.io] The HAProxy router reports the expected host names in admitted routes' statuses": " [Suite:openshift/conformance/parallel]", diff --git a/vendor/github.com/openshift/api/Dockerfile.rhel8 b/vendor/github.com/openshift/api/Dockerfile.rhel8 index 172c7a0c123c..5b5954528c17 100644 --- a/vendor/github.com/openshift/api/Dockerfile.rhel8 +++ b/vendor/github.com/openshift/api/Dockerfile.rhel8 @@ -12,22 +12,12 @@ COPY --from=builder /go/src/github.com/openshift/api/write-available-featuresets # this directory is used to produce rendered manifests that the installer applies (but does not maintain) in bootkube RUN mkdir -p /usr/share/bootkube/manifests/manifests -COPY config/v1/*_config-operator_*.yaml /usr/share/bootkube/manifests/manifests -COPY quota/v1/*.crd.yaml /usr/share/bootkube/manifests/manifests -COPY security/v1/*.crd.yaml /usr/share/bootkube/manifests/manifests -COPY securityinternal/v1/*.crd.yaml /usr/share/bootkube/manifests/manifests -COPY authorization/v1/*.crd.yaml /usr/share/bootkube/manifests/manifests -COPY operator/v1alpha1/0000_10_config-operator_01_imagecontentsourcepolicy.crd.yaml /usr/share/bootkube/manifests/manifests +COPY payload-manifests/crds/* /usr/share/bootkube/manifests/manifests # these are applied by the CVO COPY manifests /manifests -COPY config/v1/*_config-operator_*.yaml /manifests -COPY quota/v1/*.crd.yaml /manifests -COPY security/v1/*.crd.yaml /manifests -COPY securityinternal/v1/*.crd.yaml /manifests -COPY authorization/v1/*.crd.yaml /manifests -COPY operator/v1alpha1/0000_10_config-operator_01_imagecontentsourcepolicy.crd.yaml /manifests -COPY operator/v1/0000_10_config-operator_*.yaml /manifests +COPY payload-manifests/crds/* /manifests +COPY payload-manifests/featuregates/* /manifests COPY payload-command/empty-resources /manifests LABEL io.openshift.release.operator true diff --git a/vendor/github.com/openshift/api/Makefile b/vendor/github.com/openshift/api/Makefile index 69eee4376ab8..30ce998bd45e 100644 --- a/vendor/github.com/openshift/api/Makefile +++ b/vendor/github.com/openshift/api/Makefile @@ -49,6 +49,8 @@ verify-scripts: bash -x hack/verify-integration-tests.sh bash -x hack/verify-group-versions.sh bash -x hack/verify-prerelease-lifecycle-gen.sh + hack/verify-payload-crds.sh + hack/verify-payload-featuregates.sh .PHONY: verify verify: verify-scripts verify-crd-schema verify-codegen-crds @@ -76,7 +78,7 @@ verify-%: ################################################################################################ .PHONY: update-scripts -update-scripts: update-compatibility update-openapi update-deepcopy update-protobuf update-swagger-docs tests-vendor update-prerelease-lifecycle-gen +update-scripts: update-compatibility update-openapi update-deepcopy update-protobuf update-swagger-docs tests-vendor update-prerelease-lifecycle-gen update-payload-crds update-payload-featuregates .PHONY: update-compatibility update-compatibility: @@ -102,6 +104,14 @@ update-swagger-docs: update-prerelease-lifecycle-gen: hack/update-prerelease-lifecycle-gen.sh +.PHONY: update-payload-crds +update-payload-crds: + hack/update-payload-crds.sh + +.PHONY: update-payload-featuregates +update-payload-featuregates: + hack/update-payload-featuregates.sh + ##################### # # END: Update scripts diff --git a/vendor/github.com/openshift/api/cloudnetwork/v1/001-cloudprivateipconfig.crd.yaml b/vendor/github.com/openshift/api/cloudnetwork/v1/001-cloudprivateipconfig.crd.yaml index d4e9e0b88ef1..41c0671c8506 100644 --- a/vendor/github.com/openshift/api/cloudnetwork/v1/001-cloudprivateipconfig.crd.yaml +++ b/vendor/github.com/openshift/api/cloudnetwork/v1/001-cloudprivateipconfig.crd.yaml @@ -29,7 +29,7 @@ spec: name: anyOf: - format: ipv4 - - format: ipv6 + - pattern: ^[0-9a-f]{4}(\.[0-9a-f]{4}){7}$ type: string type: object spec: diff --git a/vendor/github.com/openshift/api/cloudnetwork/v1/001-cloudprivateipconfig.crd.yaml-patch b/vendor/github.com/openshift/api/cloudnetwork/v1/001-cloudprivateipconfig.crd.yaml-patch index 1239c054398b..a11d1b82c9be 100644 --- a/vendor/github.com/openshift/api/cloudnetwork/v1/001-cloudprivateipconfig.crd.yaml-patch +++ b/vendor/github.com/openshift/api/cloudnetwork/v1/001-cloudprivateipconfig.crd.yaml-patch @@ -7,4 +7,4 @@ type: string anyOf: - format: ipv4 - - format: ipv6 + - pattern: '^[0-9a-f]{4}(\.[0-9a-f]{4}){7}$' diff --git a/vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusterversion-CustomNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusterversion-CustomNoUpgrade.crd.yaml new file mode 100644 index 000000000000..a3d35768681b --- /dev/null +++ b/vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusterversion-CustomNoUpgrade.crd.yaml @@ -0,0 +1,503 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.openshift.io: https://github.com/openshift/api/pull/495 + include.release.openshift.io/self-managed-high-availability: "true" + include.release.openshift.io/single-node-developer: "true" + release.openshift.io/feature-set: CustomNoUpgrade + name: clusterversions.config.openshift.io +spec: + group: config.openshift.io + names: + kind: ClusterVersion + plural: clusterversions + singular: clusterversion + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .status.history[?(@.state=="Completed")].version + name: Version + type: string + - jsonPath: .status.conditions[?(@.type=="Available")].status + name: Available + type: string + - jsonPath: .status.conditions[?(@.type=="Progressing")].status + name: Progressing + type: string + - jsonPath: .status.conditions[?(@.type=="Progressing")].lastTransitionTime + name: Since + type: date + - jsonPath: .status.conditions[?(@.type=="Progressing")].message + name: Status + type: string + name: v1 + schema: + openAPIV3Schema: + description: "ClusterVersion is the configuration for the ClusterVersionOperator. This is where parameters related to automatic updates can be set. \n Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer)." + type: object + required: + - spec + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: spec is the desired state of the cluster version - the operator will work to ensure that the desired version is applied to the cluster. + type: object + required: + - clusterID + properties: + capabilities: + description: capabilities configures the installation of optional, core cluster components. A null value here is identical to an empty object; see the child properties for default semantics. + type: object + properties: + additionalEnabledCapabilities: + description: additionalEnabledCapabilities extends the set of managed capabilities beyond the baseline defined in baselineCapabilitySet. The default is an empty set. + type: array + items: + description: ClusterVersionCapability enumerates optional, core cluster components. + type: string + enum: + - openshift-samples + - baremetal + - marketplace + - Console + - Insights + - Storage + - CSISnapshot + - NodeTuning + - MachineAPI + - Build + - DeploymentConfig + - ImageRegistry + - OperatorLifecycleManager + - CloudCredential + x-kubernetes-list-type: atomic + baselineCapabilitySet: + description: baselineCapabilitySet selects an initial set of optional capabilities to enable, which can be extended via additionalEnabledCapabilities. If unset, the cluster will choose a default, and the default may change over time. The current default is vCurrent. + type: string + enum: + - None + - v4.11 + - v4.12 + - v4.13 + - v4.14 + - v4.15 + - vCurrent + channel: + description: channel is an identifier for explicitly requesting that a non-default set of updates be applied to this cluster. The default channel will be contain stable updates that are appropriate for production clusters. + type: string + clusterID: + description: clusterID uniquely identifies this cluster. This is expected to be an RFC4122 UUID value (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx in hexadecimal values). This is a required field. + type: string + desiredUpdate: + description: "desiredUpdate is an optional field that indicates the desired value of the cluster version. Setting this value will trigger an upgrade (if the current version does not match the desired version). The set of recommended update values is listed as part of available updates in status, and setting values outside that range may cause the upgrade to fail. \n Some of the fields are inter-related with restrictions and meanings described here. 1. image is specified, version is specified, architecture is specified. API validation error. 2. image is specified, version is specified, architecture is not specified. You should not do this. version is silently ignored and image is used. 3. image is specified, version is not specified, architecture is specified. API validation error. 4. image is specified, version is not specified, architecture is not specified. image is used. 5. image is not specified, version is specified, architecture is specified. version and desired architecture are used to select an image. 6. image is not specified, version is specified, architecture is not specified. version and current architecture are used to select an image. 7. image is not specified, version is not specified, architecture is specified. API validation error. 8. image is not specified, version is not specified, architecture is not specified. API validation error. \n If an upgrade fails the operator will halt and report status about the failing component. Setting the desired update value back to the previous version will cause a rollback to be attempted. Not all rollbacks will succeed." + type: object + properties: + architecture: + description: architecture is an optional field that indicates the desired value of the cluster architecture. In this context cluster architecture means either a single architecture or a multi architecture. architecture can only be set to Multi thereby only allowing updates from single to multi architecture. If architecture is set, image cannot be set and version must be set. Valid values are 'Multi' and empty. + type: string + enum: + - Multi + - "" + force: + description: force allows an administrator to update to an image that has failed verification or upgradeable checks. This option should only be used when the authenticity of the provided image has been verified out of band because the provided image will run with full administrative access to the cluster. Do not use this flag with images that comes from unknown or potentially malicious sources. + type: boolean + image: + description: image is a container image location that contains the update. image should be used when the desired version does not exist in availableUpdates or history. When image is set, version is ignored. When image is set, version should be empty. When image is set, architecture cannot be specified. + type: string + version: + description: version is a semantic version identifying the update version. version is ignored if image is specified and required if architecture is specified. + type: string + x-kubernetes-validations: + - rule: 'has(self.architecture) && has(self.image) ? (self.architecture == '''' || self.image == '''') : true' + message: cannot set both Architecture and Image + - rule: 'has(self.architecture) && self.architecture != '''' ? self.version != '''' : true' + message: Version must be set if Architecture is set + overrides: + description: overrides is list of overides for components that are managed by cluster version operator. Marking a component unmanaged will prevent the operator from creating or updating the object. + type: array + items: + description: ComponentOverride allows overriding cluster version operator's behavior for a component. + type: object + required: + - group + - kind + - name + - namespace + - unmanaged + properties: + group: + description: group identifies the API group that the kind is in. + type: string + kind: + description: kind indentifies which object to override. + type: string + name: + description: name is the component's name. + type: string + namespace: + description: namespace is the component's namespace. If the resource is cluster scoped, the namespace should be empty. + type: string + unmanaged: + description: 'unmanaged controls if cluster version operator should stop managing the resources in this cluster. Default: false' + type: boolean + x-kubernetes-list-map-keys: + - kind + - group + - namespace + - name + x-kubernetes-list-type: map + signatureStores: + description: "signatureStores contains the upstream URIs to verify release signatures and optional reference to a config map by name containing the PEM-encoded CA bundle. \n By default, CVO will use existing signature stores if this property is empty. The CVO will check the release signatures in the local ConfigMaps first. It will search for a valid signature in these stores in parallel only when local ConfigMaps did not include a valid signature. Validation will fail if none of the signature stores reply with valid signature before timeout. Setting signatureStores will replace the default signature stores with custom signature stores. Default stores can be used with custom signature stores by adding them manually. \n A maximum of 32 signature stores may be configured." + type: array + maxItems: 32 + items: + description: SignatureStore represents the URL of custom Signature Store + type: object + required: + - url + properties: + ca: + description: ca is an optional reference to a config map by name containing the PEM-encoded CA bundle. It is used as a trust anchor to validate the TLS certificate presented by the remote server. The key "ca.crt" is used to locate the data. If specified and the config map or expected key is not found, the signature store is not honored. If the specified ca data is not valid, the signature store is not honored. If empty, we fall back to the CA configured via Proxy, which is appended to the default system roots. The namespace for this config map is openshift-config. + type: object + required: + - name + properties: + name: + description: name is the metadata.name of the referenced config map + type: string + url: + description: url contains the upstream custom signature store URL. url should be a valid absolute http/https URI of an upstream signature store as per rfc1738. This must be provided and cannot be empty. + type: string + x-kubernetes-validations: + - rule: isURL(self) + message: url must be a valid absolute URL + x-kubernetes-list-map-keys: + - url + x-kubernetes-list-type: map + upstream: + description: upstream may be used to specify the preferred update server. By default it will use the appropriate update server for the cluster and region. + type: string + status: + description: status contains information about the available updates and any in-progress updates. + type: object + required: + - availableUpdates + - desired + - observedGeneration + - versionHash + properties: + availableUpdates: + description: availableUpdates contains updates recommended for this cluster. Updates which appear in conditionalUpdates but not in availableUpdates may expose this cluster to known issues. This list may be empty if no updates are recommended, if the update service is unavailable, or if an invalid channel has been specified. + type: array + items: + description: Release represents an OpenShift release image and associated metadata. + type: object + properties: + channels: + description: channels is the set of Cincinnati channels to which the release currently belongs. + type: array + items: + type: string + x-kubernetes-list-type: set + image: + description: image is a container image location that contains the update. When this field is part of spec, image is optional if version is specified and the availableUpdates field contains a matching version. + type: string + url: + description: url contains information about this release. This URL is set by the 'url' metadata property on a release or the metadata returned by the update API and should be displayed as a link in user interfaces. The URL field may not be set for test or nightly releases. + type: string + version: + description: version is a semantic version identifying the update version. When this field is part of spec, version is optional if image is specified. + type: string + nullable: true + x-kubernetes-list-type: atomic + capabilities: + description: capabilities describes the state of optional, core cluster components. + type: object + properties: + enabledCapabilities: + description: enabledCapabilities lists all the capabilities that are currently managed. + type: array + items: + description: ClusterVersionCapability enumerates optional, core cluster components. + type: string + enum: + - openshift-samples + - baremetal + - marketplace + - Console + - Insights + - Storage + - CSISnapshot + - NodeTuning + - MachineAPI + - Build + - DeploymentConfig + - ImageRegistry + - OperatorLifecycleManager + - CloudCredential + x-kubernetes-list-type: atomic + knownCapabilities: + description: knownCapabilities lists all the capabilities known to the current cluster. + type: array + items: + description: ClusterVersionCapability enumerates optional, core cluster components. + type: string + enum: + - openshift-samples + - baremetal + - marketplace + - Console + - Insights + - Storage + - CSISnapshot + - NodeTuning + - MachineAPI + - Build + - DeploymentConfig + - ImageRegistry + - OperatorLifecycleManager + - CloudCredential + x-kubernetes-list-type: atomic + conditionalUpdates: + description: conditionalUpdates contains the list of updates that may be recommended for this cluster if it meets specific required conditions. Consumers interested in the set of updates that are actually recommended for this cluster should use availableUpdates. This list may be empty if no updates are recommended, if the update service is unavailable, or if an empty or invalid channel has been specified. + type: array + items: + description: ConditionalUpdate represents an update which is recommended to some clusters on the version the current cluster is reconciling, but which may not be recommended for the current cluster. + type: object + required: + - release + - risks + properties: + conditions: + description: 'conditions represents the observations of the conditional update''s current status. Known types are: * Evaluating, for whether the cluster-version operator will attempt to evaluate any risks[].matchingRules. * Recommended, for whether the update is recommended for the current cluster.' + type: array + items: + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + type: object + required: + - lastTransitionTime + - message + - reason + - status + - type + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + type: string + format: date-time + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + type: string + maxLength: 32768 + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + type: integer + format: int64 + minimum: 0 + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + type: string + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + status: + description: status of the condition, one of True, False, Unknown. + type: string + enum: + - "True" + - "False" + - Unknown + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + type: string + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + release: + description: release is the target of the update. + type: object + properties: + channels: + description: channels is the set of Cincinnati channels to which the release currently belongs. + type: array + items: + type: string + x-kubernetes-list-type: set + image: + description: image is a container image location that contains the update. When this field is part of spec, image is optional if version is specified and the availableUpdates field contains a matching version. + type: string + url: + description: url contains information about this release. This URL is set by the 'url' metadata property on a release or the metadata returned by the update API and should be displayed as a link in user interfaces. The URL field may not be set for test or nightly releases. + type: string + version: + description: version is a semantic version identifying the update version. When this field is part of spec, version is optional if image is specified. + type: string + risks: + description: risks represents the range of issues associated with updating to the target release. The cluster-version operator will evaluate all entries, and only recommend the update if there is at least one entry and all entries recommend the update. + type: array + minItems: 1 + items: + description: ConditionalUpdateRisk represents a reason and cluster-state for not recommending a conditional update. + type: object + required: + - matchingRules + - message + - name + - url + properties: + matchingRules: + description: matchingRules is a slice of conditions for deciding which clusters match the risk and which do not. The slice is ordered by decreasing precedence. The cluster-version operator will walk the slice in order, and stop after the first it can successfully evaluate. If no condition can be successfully evaluated, the update will not be recommended. + type: array + minItems: 1 + items: + description: ClusterCondition is a union of typed cluster conditions. The 'type' property determines which of the type-specific properties are relevant. When evaluated on a cluster, the condition may match, not match, or fail to evaluate. + type: object + required: + - type + properties: + promql: + description: promQL represents a cluster condition based on PromQL. + type: object + required: + - promql + properties: + promql: + description: PromQL is a PromQL query classifying clusters. This query query should return a 1 in the match case and a 0 in the does-not-match case. Queries which return no time series, or which return values besides 0 or 1, are evaluation failures. + type: string + type: + description: type represents the cluster-condition type. This defines the members and semantics of any additional properties. + type: string + enum: + - Always + - PromQL + x-kubernetes-list-type: atomic + message: + description: message provides additional information about the risk of updating, in the event that matchingRules match the cluster state. This is only to be consumed by humans. It may contain Line Feed characters (U+000A), which should be rendered as new lines. + type: string + minLength: 1 + name: + description: name is the CamelCase reason for not recommending a conditional update, in the event that matchingRules match the cluster state. + type: string + minLength: 1 + url: + description: url contains information about this risk. + type: string + format: uri + minLength: 1 + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + x-kubernetes-list-type: atomic + conditions: + description: conditions provides information about the cluster version. The condition "Available" is set to true if the desiredUpdate has been reached. The condition "Progressing" is set to true if an update is being applied. The condition "Degraded" is set to true if an update is currently blocked by a temporary or permanent error. Conditions are only valid for the current desiredUpdate when metadata.generation is equal to status.generation. + type: array + items: + description: ClusterOperatorStatusCondition represents the state of the operator's managed and monitored components. + type: object + required: + - lastTransitionTime + - status + - type + properties: + lastTransitionTime: + description: lastTransitionTime is the time of the last update to the current status property. + type: string + format: date-time + message: + description: message provides additional information about the current condition. This is only to be consumed by humans. It may contain Line Feed characters (U+000A), which should be rendered as new lines. + type: string + reason: + description: reason is the CamelCase reason for the condition's current status. + type: string + status: + description: status of the condition, one of True, False, Unknown. + type: string + type: + description: type specifies the aspect reported by this condition. + type: string + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + desired: + description: desired is the version that the cluster is reconciling towards. If the cluster is not yet fully initialized desired will be set with the information available, which may be an image or a tag. + type: object + properties: + channels: + description: channels is the set of Cincinnati channels to which the release currently belongs. + type: array + items: + type: string + x-kubernetes-list-type: set + image: + description: image is a container image location that contains the update. When this field is part of spec, image is optional if version is specified and the availableUpdates field contains a matching version. + type: string + url: + description: url contains information about this release. This URL is set by the 'url' metadata property on a release or the metadata returned by the update API and should be displayed as a link in user interfaces. The URL field may not be set for test or nightly releases. + type: string + version: + description: version is a semantic version identifying the update version. When this field is part of spec, version is optional if image is specified. + type: string + history: + description: history contains a list of the most recent versions applied to the cluster. This value may be empty during cluster startup, and then will be updated when a new update is being applied. The newest update is first in the list and it is ordered by recency. Updates in the history have state Completed if the rollout completed - if an update was failing or halfway applied the state will be Partial. Only a limited amount of update history is preserved. + type: array + items: + description: UpdateHistory is a single attempted update to the cluster. + type: object + required: + - completionTime + - image + - startedTime + - state + - verified + properties: + acceptedRisks: + description: acceptedRisks records risks which were accepted to initiate the update. For example, it may menition an Upgradeable=False or missing signature that was overriden via desiredUpdate.force, or an update that was initiated despite not being in the availableUpdates set of recommended update targets. + type: string + completionTime: + description: completionTime, if set, is when the update was fully applied. The update that is currently being applied will have a null completion time. Completion time will always be set for entries that are not the current update (usually to the started time of the next update). + type: string + format: date-time + nullable: true + image: + description: image is a container image location that contains the update. This value is always populated. + type: string + startedTime: + description: startedTime is the time at which the update was started. + type: string + format: date-time + state: + description: state reflects whether the update was fully applied. The Partial state indicates the update is not fully applied, while the Completed state indicates the update was successfully rolled out at least once (all parts of the update successfully applied). + type: string + verified: + description: verified indicates whether the provided update was properly verified before it was installed. If this is false the cluster may not be trusted. Verified does not cover upgradeable checks that depend on the cluster state at the time when the update target was accepted. + type: boolean + version: + description: version is a semantic version identifying the update version. If the requested image does not define a version, or if a failure occurs retrieving the image, this value may be empty. + type: string + x-kubernetes-list-type: atomic + observedGeneration: + description: observedGeneration reports which version of the spec is being synced. If this value is not equal to metadata.generation, then the desired and conditions fields may represent a previous version. + type: integer + format: int64 + versionHash: + description: versionHash is a fingerprint of the content that the cluster will be updated with. It is used by the operator to avoid unnecessary work and is for internal use only. + type: string + x-kubernetes-validations: + - rule: 'has(self.spec.capabilities) && has(self.spec.capabilities.additionalEnabledCapabilities) && self.spec.capabilities.baselineCapabilitySet == ''None'' && ''baremetal'' in self.spec.capabilities.additionalEnabledCapabilities ? ''MachineAPI'' in self.spec.capabilities.additionalEnabledCapabilities || (has(self.status) && has(self.status.capabilities) && has(self.status.capabilities.enabledCapabilities) && ''MachineAPI'' in self.status.capabilities.enabledCapabilities) : true' + message: the `baremetal` capability requires the `MachineAPI` capability, which is neither explicitly or implicitly enabled in this cluster, please enable the `MachineAPI` capability + - rule: 'has(self.spec.capabilities) && has(self.spec.capabilities.additionalEnabledCapabilities) && self.spec.capabilities.baselineCapabilitySet == ''None'' && ''marketplace'' in self.spec.capabilities.additionalEnabledCapabilities ? ''OperatorLifecycleManager'' in self.spec.capabilities.additionalEnabledCapabilities || (has(self.status) && has(self.status.capabilities) && has(self.status.capabilities.enabledCapabilities) && ''OperatorLifecycleManager'' in self.status.capabilities.enabledCapabilities) : true' + message: the `marketplace` capability requires the `OperatorLifecycleManager` capability, which is neither explicitly or implicitly enabled in this cluster, please enable the `OperatorLifecycleManager` capability + served: true + storage: true + subresources: + status: {} diff --git a/vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusterversion.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusterversion-Default.crd.yaml similarity index 98% rename from vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusterversion.crd.yaml rename to vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusterversion-Default.crd.yaml index 9b169f964c23..6d802f0ca64a 100644 --- a/vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusterversion.crd.yaml +++ b/vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusterversion-Default.crd.yaml @@ -5,6 +5,7 @@ metadata: api-approved.openshift.io: https://github.com/openshift/api/pull/495 include.release.openshift.io/self-managed-high-availability: "true" include.release.openshift.io/single-node-developer: "true" + release.openshift.io/feature-set: Default name: clusterversions.config.openshift.io spec: group: config.openshift.io @@ -147,6 +148,12 @@ spec: unmanaged: description: 'unmanaged controls if cluster version operator should stop managing the resources in this cluster. Default: false' type: boolean + x-kubernetes-list-map-keys: + - kind + - group + - namespace + - name + x-kubernetes-list-type: map upstream: description: upstream may be used to specify the preferred update server. By default it will use the appropriate update server for the cluster and region. type: string @@ -171,6 +178,7 @@ spec: type: array items: type: string + x-kubernetes-list-type: set image: description: image is a container image location that contains the update. When this field is part of spec, image is optional if version is specified and the availableUpdates field contains a matching version. type: string @@ -181,6 +189,7 @@ spec: description: version is a semantic version identifying the update version. When this field is part of spec, version is optional if image is specified. type: string nullable: true + x-kubernetes-list-type: atomic capabilities: description: capabilities describes the state of optional, core cluster components. type: object @@ -295,6 +304,7 @@ spec: type: array items: type: string + x-kubernetes-list-type: set image: description: image is a container image location that contains the update. When this field is part of spec, image is optional if version is specified and the availableUpdates field contains a matching version. type: string @@ -387,6 +397,9 @@ spec: type: description: type specifies the aspect reported by this condition. type: string + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map desired: description: desired is the version that the cluster is reconciling towards. If the cluster is not yet fully initialized desired will be set with the information available, which may be an image or a tag. type: object @@ -396,6 +409,7 @@ spec: type: array items: type: string + x-kubernetes-list-type: set image: description: image is a container image location that contains the update. When this field is part of spec, image is optional if version is specified and the availableUpdates field contains a matching version. type: string @@ -442,6 +456,7 @@ spec: version: description: version is a semantic version identifying the update version. If the requested image does not define a version, or if a failure occurs retrieving the image, this value may be empty. type: string + x-kubernetes-list-type: atomic observedGeneration: description: observedGeneration reports which version of the spec is being synced. If this value is not equal to metadata.generation, then the desired and conditions fields may represent a previous version. type: integer diff --git a/vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusterversion-TechPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusterversion-TechPreviewNoUpgrade.crd.yaml new file mode 100644 index 000000000000..878a71fa6d83 --- /dev/null +++ b/vendor/github.com/openshift/api/config/v1/0000_00_cluster-version-operator_01_clusterversion-TechPreviewNoUpgrade.crd.yaml @@ -0,0 +1,503 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.openshift.io: https://github.com/openshift/api/pull/495 + include.release.openshift.io/self-managed-high-availability: "true" + include.release.openshift.io/single-node-developer: "true" + release.openshift.io/feature-set: TechPreviewNoUpgrade + name: clusterversions.config.openshift.io +spec: + group: config.openshift.io + names: + kind: ClusterVersion + plural: clusterversions + singular: clusterversion + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .status.history[?(@.state=="Completed")].version + name: Version + type: string + - jsonPath: .status.conditions[?(@.type=="Available")].status + name: Available + type: string + - jsonPath: .status.conditions[?(@.type=="Progressing")].status + name: Progressing + type: string + - jsonPath: .status.conditions[?(@.type=="Progressing")].lastTransitionTime + name: Since + type: date + - jsonPath: .status.conditions[?(@.type=="Progressing")].message + name: Status + type: string + name: v1 + schema: + openAPIV3Schema: + description: "ClusterVersion is the configuration for the ClusterVersionOperator. This is where parameters related to automatic updates can be set. \n Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer)." + type: object + required: + - spec + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: spec is the desired state of the cluster version - the operator will work to ensure that the desired version is applied to the cluster. + type: object + required: + - clusterID + properties: + capabilities: + description: capabilities configures the installation of optional, core cluster components. A null value here is identical to an empty object; see the child properties for default semantics. + type: object + properties: + additionalEnabledCapabilities: + description: additionalEnabledCapabilities extends the set of managed capabilities beyond the baseline defined in baselineCapabilitySet. The default is an empty set. + type: array + items: + description: ClusterVersionCapability enumerates optional, core cluster components. + type: string + enum: + - openshift-samples + - baremetal + - marketplace + - Console + - Insights + - Storage + - CSISnapshot + - NodeTuning + - MachineAPI + - Build + - DeploymentConfig + - ImageRegistry + - OperatorLifecycleManager + - CloudCredential + x-kubernetes-list-type: atomic + baselineCapabilitySet: + description: baselineCapabilitySet selects an initial set of optional capabilities to enable, which can be extended via additionalEnabledCapabilities. If unset, the cluster will choose a default, and the default may change over time. The current default is vCurrent. + type: string + enum: + - None + - v4.11 + - v4.12 + - v4.13 + - v4.14 + - v4.15 + - vCurrent + channel: + description: channel is an identifier for explicitly requesting that a non-default set of updates be applied to this cluster. The default channel will be contain stable updates that are appropriate for production clusters. + type: string + clusterID: + description: clusterID uniquely identifies this cluster. This is expected to be an RFC4122 UUID value (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx in hexadecimal values). This is a required field. + type: string + desiredUpdate: + description: "desiredUpdate is an optional field that indicates the desired value of the cluster version. Setting this value will trigger an upgrade (if the current version does not match the desired version). The set of recommended update values is listed as part of available updates in status, and setting values outside that range may cause the upgrade to fail. \n Some of the fields are inter-related with restrictions and meanings described here. 1. image is specified, version is specified, architecture is specified. API validation error. 2. image is specified, version is specified, architecture is not specified. You should not do this. version is silently ignored and image is used. 3. image is specified, version is not specified, architecture is specified. API validation error. 4. image is specified, version is not specified, architecture is not specified. image is used. 5. image is not specified, version is specified, architecture is specified. version and desired architecture are used to select an image. 6. image is not specified, version is specified, architecture is not specified. version and current architecture are used to select an image. 7. image is not specified, version is not specified, architecture is specified. API validation error. 8. image is not specified, version is not specified, architecture is not specified. API validation error. \n If an upgrade fails the operator will halt and report status about the failing component. Setting the desired update value back to the previous version will cause a rollback to be attempted. Not all rollbacks will succeed." + type: object + properties: + architecture: + description: architecture is an optional field that indicates the desired value of the cluster architecture. In this context cluster architecture means either a single architecture or a multi architecture. architecture can only be set to Multi thereby only allowing updates from single to multi architecture. If architecture is set, image cannot be set and version must be set. Valid values are 'Multi' and empty. + type: string + enum: + - Multi + - "" + force: + description: force allows an administrator to update to an image that has failed verification or upgradeable checks. This option should only be used when the authenticity of the provided image has been verified out of band because the provided image will run with full administrative access to the cluster. Do not use this flag with images that comes from unknown or potentially malicious sources. + type: boolean + image: + description: image is a container image location that contains the update. image should be used when the desired version does not exist in availableUpdates or history. When image is set, version is ignored. When image is set, version should be empty. When image is set, architecture cannot be specified. + type: string + version: + description: version is a semantic version identifying the update version. version is ignored if image is specified and required if architecture is specified. + type: string + x-kubernetes-validations: + - rule: 'has(self.architecture) && has(self.image) ? (self.architecture == '''' || self.image == '''') : true' + message: cannot set both Architecture and Image + - rule: 'has(self.architecture) && self.architecture != '''' ? self.version != '''' : true' + message: Version must be set if Architecture is set + overrides: + description: overrides is list of overides for components that are managed by cluster version operator. Marking a component unmanaged will prevent the operator from creating or updating the object. + type: array + items: + description: ComponentOverride allows overriding cluster version operator's behavior for a component. + type: object + required: + - group + - kind + - name + - namespace + - unmanaged + properties: + group: + description: group identifies the API group that the kind is in. + type: string + kind: + description: kind indentifies which object to override. + type: string + name: + description: name is the component's name. + type: string + namespace: + description: namespace is the component's namespace. If the resource is cluster scoped, the namespace should be empty. + type: string + unmanaged: + description: 'unmanaged controls if cluster version operator should stop managing the resources in this cluster. Default: false' + type: boolean + x-kubernetes-list-map-keys: + - kind + - group + - namespace + - name + x-kubernetes-list-type: map + signatureStores: + description: "signatureStores contains the upstream URIs to verify release signatures and optional reference to a config map by name containing the PEM-encoded CA bundle. \n By default, CVO will use existing signature stores if this property is empty. The CVO will check the release signatures in the local ConfigMaps first. It will search for a valid signature in these stores in parallel only when local ConfigMaps did not include a valid signature. Validation will fail if none of the signature stores reply with valid signature before timeout. Setting signatureStores will replace the default signature stores with custom signature stores. Default stores can be used with custom signature stores by adding them manually. \n A maximum of 32 signature stores may be configured." + type: array + maxItems: 32 + items: + description: SignatureStore represents the URL of custom Signature Store + type: object + required: + - url + properties: + ca: + description: ca is an optional reference to a config map by name containing the PEM-encoded CA bundle. It is used as a trust anchor to validate the TLS certificate presented by the remote server. The key "ca.crt" is used to locate the data. If specified and the config map or expected key is not found, the signature store is not honored. If the specified ca data is not valid, the signature store is not honored. If empty, we fall back to the CA configured via Proxy, which is appended to the default system roots. The namespace for this config map is openshift-config. + type: object + required: + - name + properties: + name: + description: name is the metadata.name of the referenced config map + type: string + url: + description: url contains the upstream custom signature store URL. url should be a valid absolute http/https URI of an upstream signature store as per rfc1738. This must be provided and cannot be empty. + type: string + x-kubernetes-validations: + - rule: isURL(self) + message: url must be a valid absolute URL + x-kubernetes-list-map-keys: + - url + x-kubernetes-list-type: map + upstream: + description: upstream may be used to specify the preferred update server. By default it will use the appropriate update server for the cluster and region. + type: string + status: + description: status contains information about the available updates and any in-progress updates. + type: object + required: + - availableUpdates + - desired + - observedGeneration + - versionHash + properties: + availableUpdates: + description: availableUpdates contains updates recommended for this cluster. Updates which appear in conditionalUpdates but not in availableUpdates may expose this cluster to known issues. This list may be empty if no updates are recommended, if the update service is unavailable, or if an invalid channel has been specified. + type: array + items: + description: Release represents an OpenShift release image and associated metadata. + type: object + properties: + channels: + description: channels is the set of Cincinnati channels to which the release currently belongs. + type: array + items: + type: string + x-kubernetes-list-type: set + image: + description: image is a container image location that contains the update. When this field is part of spec, image is optional if version is specified and the availableUpdates field contains a matching version. + type: string + url: + description: url contains information about this release. This URL is set by the 'url' metadata property on a release or the metadata returned by the update API and should be displayed as a link in user interfaces. The URL field may not be set for test or nightly releases. + type: string + version: + description: version is a semantic version identifying the update version. When this field is part of spec, version is optional if image is specified. + type: string + nullable: true + x-kubernetes-list-type: atomic + capabilities: + description: capabilities describes the state of optional, core cluster components. + type: object + properties: + enabledCapabilities: + description: enabledCapabilities lists all the capabilities that are currently managed. + type: array + items: + description: ClusterVersionCapability enumerates optional, core cluster components. + type: string + enum: + - openshift-samples + - baremetal + - marketplace + - Console + - Insights + - Storage + - CSISnapshot + - NodeTuning + - MachineAPI + - Build + - DeploymentConfig + - ImageRegistry + - OperatorLifecycleManager + - CloudCredential + x-kubernetes-list-type: atomic + knownCapabilities: + description: knownCapabilities lists all the capabilities known to the current cluster. + type: array + items: + description: ClusterVersionCapability enumerates optional, core cluster components. + type: string + enum: + - openshift-samples + - baremetal + - marketplace + - Console + - Insights + - Storage + - CSISnapshot + - NodeTuning + - MachineAPI + - Build + - DeploymentConfig + - ImageRegistry + - OperatorLifecycleManager + - CloudCredential + x-kubernetes-list-type: atomic + conditionalUpdates: + description: conditionalUpdates contains the list of updates that may be recommended for this cluster if it meets specific required conditions. Consumers interested in the set of updates that are actually recommended for this cluster should use availableUpdates. This list may be empty if no updates are recommended, if the update service is unavailable, or if an empty or invalid channel has been specified. + type: array + items: + description: ConditionalUpdate represents an update which is recommended to some clusters on the version the current cluster is reconciling, but which may not be recommended for the current cluster. + type: object + required: + - release + - risks + properties: + conditions: + description: 'conditions represents the observations of the conditional update''s current status. Known types are: * Evaluating, for whether the cluster-version operator will attempt to evaluate any risks[].matchingRules. * Recommended, for whether the update is recommended for the current cluster.' + type: array + items: + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + type: object + required: + - lastTransitionTime + - message + - reason + - status + - type + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + type: string + format: date-time + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + type: string + maxLength: 32768 + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + type: integer + format: int64 + minimum: 0 + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + type: string + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + status: + description: status of the condition, one of True, False, Unknown. + type: string + enum: + - "True" + - "False" + - Unknown + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + type: string + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + release: + description: release is the target of the update. + type: object + properties: + channels: + description: channels is the set of Cincinnati channels to which the release currently belongs. + type: array + items: + type: string + x-kubernetes-list-type: set + image: + description: image is a container image location that contains the update. When this field is part of spec, image is optional if version is specified and the availableUpdates field contains a matching version. + type: string + url: + description: url contains information about this release. This URL is set by the 'url' metadata property on a release or the metadata returned by the update API and should be displayed as a link in user interfaces. The URL field may not be set for test or nightly releases. + type: string + version: + description: version is a semantic version identifying the update version. When this field is part of spec, version is optional if image is specified. + type: string + risks: + description: risks represents the range of issues associated with updating to the target release. The cluster-version operator will evaluate all entries, and only recommend the update if there is at least one entry and all entries recommend the update. + type: array + minItems: 1 + items: + description: ConditionalUpdateRisk represents a reason and cluster-state for not recommending a conditional update. + type: object + required: + - matchingRules + - message + - name + - url + properties: + matchingRules: + description: matchingRules is a slice of conditions for deciding which clusters match the risk and which do not. The slice is ordered by decreasing precedence. The cluster-version operator will walk the slice in order, and stop after the first it can successfully evaluate. If no condition can be successfully evaluated, the update will not be recommended. + type: array + minItems: 1 + items: + description: ClusterCondition is a union of typed cluster conditions. The 'type' property determines which of the type-specific properties are relevant. When evaluated on a cluster, the condition may match, not match, or fail to evaluate. + type: object + required: + - type + properties: + promql: + description: promQL represents a cluster condition based on PromQL. + type: object + required: + - promql + properties: + promql: + description: PromQL is a PromQL query classifying clusters. This query query should return a 1 in the match case and a 0 in the does-not-match case. Queries which return no time series, or which return values besides 0 or 1, are evaluation failures. + type: string + type: + description: type represents the cluster-condition type. This defines the members and semantics of any additional properties. + type: string + enum: + - Always + - PromQL + x-kubernetes-list-type: atomic + message: + description: message provides additional information about the risk of updating, in the event that matchingRules match the cluster state. This is only to be consumed by humans. It may contain Line Feed characters (U+000A), which should be rendered as new lines. + type: string + minLength: 1 + name: + description: name is the CamelCase reason for not recommending a conditional update, in the event that matchingRules match the cluster state. + type: string + minLength: 1 + url: + description: url contains information about this risk. + type: string + format: uri + minLength: 1 + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + x-kubernetes-list-type: atomic + conditions: + description: conditions provides information about the cluster version. The condition "Available" is set to true if the desiredUpdate has been reached. The condition "Progressing" is set to true if an update is being applied. The condition "Degraded" is set to true if an update is currently blocked by a temporary or permanent error. Conditions are only valid for the current desiredUpdate when metadata.generation is equal to status.generation. + type: array + items: + description: ClusterOperatorStatusCondition represents the state of the operator's managed and monitored components. + type: object + required: + - lastTransitionTime + - status + - type + properties: + lastTransitionTime: + description: lastTransitionTime is the time of the last update to the current status property. + type: string + format: date-time + message: + description: message provides additional information about the current condition. This is only to be consumed by humans. It may contain Line Feed characters (U+000A), which should be rendered as new lines. + type: string + reason: + description: reason is the CamelCase reason for the condition's current status. + type: string + status: + description: status of the condition, one of True, False, Unknown. + type: string + type: + description: type specifies the aspect reported by this condition. + type: string + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + desired: + description: desired is the version that the cluster is reconciling towards. If the cluster is not yet fully initialized desired will be set with the information available, which may be an image or a tag. + type: object + properties: + channels: + description: channels is the set of Cincinnati channels to which the release currently belongs. + type: array + items: + type: string + x-kubernetes-list-type: set + image: + description: image is a container image location that contains the update. When this field is part of spec, image is optional if version is specified and the availableUpdates field contains a matching version. + type: string + url: + description: url contains information about this release. This URL is set by the 'url' metadata property on a release or the metadata returned by the update API and should be displayed as a link in user interfaces. The URL field may not be set for test or nightly releases. + type: string + version: + description: version is a semantic version identifying the update version. When this field is part of spec, version is optional if image is specified. + type: string + history: + description: history contains a list of the most recent versions applied to the cluster. This value may be empty during cluster startup, and then will be updated when a new update is being applied. The newest update is first in the list and it is ordered by recency. Updates in the history have state Completed if the rollout completed - if an update was failing or halfway applied the state will be Partial. Only a limited amount of update history is preserved. + type: array + items: + description: UpdateHistory is a single attempted update to the cluster. + type: object + required: + - completionTime + - image + - startedTime + - state + - verified + properties: + acceptedRisks: + description: acceptedRisks records risks which were accepted to initiate the update. For example, it may menition an Upgradeable=False or missing signature that was overriden via desiredUpdate.force, or an update that was initiated despite not being in the availableUpdates set of recommended update targets. + type: string + completionTime: + description: completionTime, if set, is when the update was fully applied. The update that is currently being applied will have a null completion time. Completion time will always be set for entries that are not the current update (usually to the started time of the next update). + type: string + format: date-time + nullable: true + image: + description: image is a container image location that contains the update. This value is always populated. + type: string + startedTime: + description: startedTime is the time at which the update was started. + type: string + format: date-time + state: + description: state reflects whether the update was fully applied. The Partial state indicates the update is not fully applied, while the Completed state indicates the update was successfully rolled out at least once (all parts of the update successfully applied). + type: string + verified: + description: verified indicates whether the provided update was properly verified before it was installed. If this is false the cluster may not be trusted. Verified does not cover upgradeable checks that depend on the cluster state at the time when the update target was accepted. + type: boolean + version: + description: version is a semantic version identifying the update version. If the requested image does not define a version, or if a failure occurs retrieving the image, this value may be empty. + type: string + x-kubernetes-list-type: atomic + observedGeneration: + description: observedGeneration reports which version of the spec is being synced. If this value is not equal to metadata.generation, then the desired and conditions fields may represent a previous version. + type: integer + format: int64 + versionHash: + description: versionHash is a fingerprint of the content that the cluster will be updated with. It is used by the operator to avoid unnecessary work and is for internal use only. + type: string + x-kubernetes-validations: + - rule: 'has(self.spec.capabilities) && has(self.spec.capabilities.additionalEnabledCapabilities) && self.spec.capabilities.baselineCapabilitySet == ''None'' && ''baremetal'' in self.spec.capabilities.additionalEnabledCapabilities ? ''MachineAPI'' in self.spec.capabilities.additionalEnabledCapabilities || (has(self.status) && has(self.status.capabilities) && has(self.status.capabilities.enabledCapabilities) && ''MachineAPI'' in self.status.capabilities.enabledCapabilities) : true' + message: the `baremetal` capability requires the `MachineAPI` capability, which is neither explicitly or implicitly enabled in this cluster, please enable the `MachineAPI` capability + - rule: 'has(self.spec.capabilities) && has(self.spec.capabilities.additionalEnabledCapabilities) && self.spec.capabilities.baselineCapabilitySet == ''None'' && ''marketplace'' in self.spec.capabilities.additionalEnabledCapabilities ? ''OperatorLifecycleManager'' in self.spec.capabilities.additionalEnabledCapabilities || (has(self.status) && has(self.status.capabilities) && has(self.status.capabilities.enabledCapabilities) && ''OperatorLifecycleManager'' in self.status.capabilities.enabledCapabilities) : true' + message: the `marketplace` capability requires the `OperatorLifecycleManager` capability, which is neither explicitly or implicitly enabled in this cluster, please enable the `OperatorLifecycleManager` capability + served: true + storage: true + subresources: + status: {} diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd-CustomNoUpgrade.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd-CustomNoUpgrade.yaml index 597344ff0c21..69d171917c05 100644 --- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd-CustomNoUpgrade.yaml +++ b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd-CustomNoUpgrade.yaml @@ -141,7 +141,8 @@ spec: audiences: description: Audiences is an array of audiences that the token was issued for. Valid tokens must include at least one of these values in their "aud" claim. Must be set to exactly one value. type: array - maxItems: 1 + maxItems: 10 + minItems: 1 items: type: string minLength: 1 @@ -216,6 +217,11 @@ spec: type: description: type identifies the cluster managed, user facing authentication mode in use. Specifically, it manages the component that responds to login attempts. The default is IntegratedOAuth. type: string + enum: + - "" + - None + - IntegratedOAuth + - OIDC webhookTokenAuthenticator: description: "webhookTokenAuthenticator configures a remote token reviewer. These remote authentication webhooks can be used to verify bearer tokens via the tokenreviews.authentication.k8s.io REST API. This is required to honor bearer tokens that are provisioned by an external authentication service. \n Can only be set if \"Type\" is set to \"None\"." type: object diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd-Default-Hypershift.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd-Default-Hypershift.yaml new file mode 100644 index 000000000000..cc698b46c62b --- /dev/null +++ b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd-Default-Hypershift.yaml @@ -0,0 +1,378 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.openshift.io: https://github.com/openshift/api/pull/470 + include.release.openshift.io/ibm-cloud-managed: "true" + release.openshift.io/feature-set: Default + name: authentications.config.openshift.io +spec: + group: config.openshift.io + names: + kind: Authentication + listKind: AuthenticationList + plural: authentications + singular: authentication + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + description: "Authentication specifies cluster-wide settings for authentication (like OAuth and webhook token authenticators). The canonical name of an instance is `cluster`. \n Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer)." + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: spec holds user settable values for configuration + properties: + oauthMetadata: + description: 'oauthMetadata contains the discovery endpoint data for OAuth 2.0 Authorization Server Metadata for an external OAuth server. This discovery document can be viewed from its served location: oc get --raw ''/.well-known/oauth-authorization-server'' For further details, see the IETF Draft: https://tools.ietf.org/html/draft-ietf-oauth-discovery-04#section-2 If oauthMetadata.name is non-empty, this value has precedence over any metadata reference stored in status. The key "oauthMetadata" is used to locate the data. If specified and the config map or expected key is not found, no metadata is served. If the specified metadata is not valid, no metadata is served. The namespace for this config map is openshift-config.' + properties: + name: + description: name is the metadata.name of the referenced config map + type: string + required: + - name + type: object + oidcProviders: + description: "OIDCProviders are OIDC identity providers that can issue tokens for this cluster Can only be set if \"Type\" is set to \"OIDC\". \n At most one provider can be configured." + items: + properties: + claimMappings: + description: ClaimMappings describes rules on how to transform information from an ID token into a cluster identity + properties: + groups: + description: Groups is a name of the claim that should be used to construct groups for the cluster identity. The referenced claim must use array of strings values. + properties: + claim: + description: Claim is a JWT token claim to be used in the mapping + type: string + prefix: + description: "Prefix is a string to prefix the value from the token in the result of the claim mapping. \n By default, no prefixing occurs. \n Example: if `prefix` is set to \"myoidc:\"\" and the `claim` in JWT contains an array of strings \"a\", \"b\" and \"c\", the mapping will result in an array of string \"myoidc:a\", \"myoidc:b\" and \"myoidc:c\"." + type: string + required: + - claim + type: object + username: + description: "Username is a name of the claim that should be used to construct usernames for the cluster identity. \n Default value: \"sub\"" + properties: + claim: + description: Claim is a JWT token claim to be used in the mapping + type: string + prefix: + properties: + prefixString: + minLength: 1 + type: string + required: + - prefixString + type: object + prefixPolicy: + description: "PrefixPolicy specifies how a prefix should apply. \n By default, claims other than `email` will be prefixed with the issuer URL to prevent naming clashes with other plugins. \n Set to \"NoPrefix\" to disable prefixing. \n Example: (1) `prefix` is set to \"myoidc:\" and `claim` is set to \"username\". If the JWT claim `username` contains value `userA`, the resulting mapped value will be \"myoidc:userA\". (2) `prefix` is set to \"myoidc:\" and `claim` is set to \"email\". If the JWT `email` claim contains value \"userA@myoidc.tld\", the resulting mapped value will be \"myoidc:userA@myoidc.tld\". (3) `prefix` is unset, `issuerURL` is set to `https://myoidc.tld`, the JWT claims include \"username\":\"userA\" and \"email\":\"userA@myoidc.tld\", and `claim` is set to: (a) \"username\": the mapped value will be \"https://myoidc.tld#userA\" (b) \"email\": the mapped value will be \"userA@myoidc.tld\"" + enum: + - "" + - NoPrefix + - Prefix + type: string + required: + - claim + type: object + x-kubernetes-validations: + - message: prefix must be set if prefixPolicy is 'Prefix', but must remain unset otherwise + rule: 'has(self.prefixPolicy) && self.prefixPolicy == ''Prefix'' ? (has(self.prefix) && size(self.prefix.prefixString) > 0) : !has(self.prefix)' + type: object + claimValidationRules: + description: ClaimValidationRules are rules that are applied to validate token claims to authenticate users. + items: + properties: + requiredClaim: + description: RequiredClaim allows configuring a required claim name and its expected value + properties: + claim: + description: Claim is a name of a required claim. Only claims with string values are supported. + minLength: 1 + type: string + requiredValue: + description: RequiredValue is the required value for the claim. + minLength: 1 + type: string + required: + - claim + - requiredValue + type: object + type: + default: RequiredClaim + description: Type sets the type of the validation rule + enum: + - RequiredClaim + type: string + type: object + type: array + x-kubernetes-list-type: atomic + issuer: + description: Issuer describes atributes of the OIDC token issuer + properties: + audiences: + description: Audiences is an array of audiences that the token was issued for. Valid tokens must include at least one of these values in their "aud" claim. Must be set to exactly one value. + items: + minLength: 1 + type: string + maxItems: 10 + minItems: 1 + type: array + x-kubernetes-list-type: set + issuerCertificateAuthority: + description: CertificateAuthority is a reference to a config map in the configuration namespace. The .data of the configMap must contain the "ca-bundle.crt" key. If unset, system trust is used instead. + properties: + name: + description: name is the metadata.name of the referenced config map + type: string + required: + - name + type: object + issuerURL: + description: URL is the serving URL of the token issuer. Must use the https:// scheme. + pattern: ^https:\/\/[^\s] + type: string + required: + - audiences + - issuerURL + type: object + name: + description: Name of the OIDC provider + minLength: 1 + type: string + oidcClients: + description: OIDCClients contains configuration for the platform's clients that need to request tokens from the issuer + items: + properties: + clientID: + description: ClientID is the identifier of the OIDC client from the OIDC provider + minLength: 1 + type: string + clientSecret: + description: ClientSecret refers to a secret in the `openshift-config` namespace that contains the client secret in the `clientSecret` key of the `.data` field + properties: + name: + description: name is the metadata.name of the referenced secret + type: string + required: + - name + type: object + componentName: + description: ComponentName is the name of the component that is supposed to consume this client configuration + maxLength: 256 + minLength: 1 + type: string + componentNamespace: + description: ComponentNamespace is the namespace of the component that is supposed to consume this client configuration + maxLength: 63 + minLength: 1 + type: string + extraScopes: + description: ExtraScopes is an optional set of scopes to request tokens with. + items: + type: string + type: array + x-kubernetes-list-type: set + required: + - clientID + - componentName + - componentNamespace + type: object + maxItems: 20 + type: array + x-kubernetes-list-map-keys: + - componentNamespace + - componentName + x-kubernetes-list-type: map + required: + - issuer + - name + type: object + maxItems: 1 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + serviceAccountIssuer: + description: 'serviceAccountIssuer is the identifier of the bound service account token issuer. The default is https://kubernetes.default.svc WARNING: Updating this field will not result in immediate invalidation of all bound tokens with the previous issuer value. Instead, the tokens issued by previous service account issuer will continue to be trusted for a time period chosen by the platform (currently set to 24h). This time period is subject to change over time. This allows internal components to transition to use new service account issuer without service distruption.' + type: string + type: + description: type identifies the cluster managed, user facing authentication mode in use. Specifically, it manages the component that responds to login attempts. The default is IntegratedOAuth. + enum: + - "" + - None + - IntegratedOAuth + - OIDC + type: string + webhookTokenAuthenticator: + description: "webhookTokenAuthenticator configures a remote token reviewer. These remote authentication webhooks can be used to verify bearer tokens via the tokenreviews.authentication.k8s.io REST API. This is required to honor bearer tokens that are provisioned by an external authentication service. \n Can only be set if \"Type\" is set to \"None\"." + properties: + kubeConfig: + description: "kubeConfig references a secret that contains kube config file data which describes how to access the remote webhook service. The namespace for the referenced secret is openshift-config. \n For further details, see: \n https://kubernetes.io/docs/reference/access-authn-authz/authentication/#webhook-token-authentication \n The key \"kubeConfig\" is used to locate the data. If the secret or expected key is not found, the webhook is not honored. If the specified kube config data is not valid, the webhook is not honored." + properties: + name: + description: name is the metadata.name of the referenced secret + type: string + required: + - name + type: object + required: + - kubeConfig + type: object + webhookTokenAuthenticators: + description: webhookTokenAuthenticators is DEPRECATED, setting it has no effect. + items: + description: deprecatedWebhookTokenAuthenticator holds the necessary configuration options for a remote token authenticator. It's the same as WebhookTokenAuthenticator but it's missing the 'required' validation on KubeConfig field. + properties: + kubeConfig: + description: 'kubeConfig contains kube config file data which describes how to access the remote webhook service. For further details, see: https://kubernetes.io/docs/reference/access-authn-authz/authentication/#webhook-token-authentication The key "kubeConfig" is used to locate the data. If the secret or expected key is not found, the webhook is not honored. If the specified kube config data is not valid, the webhook is not honored. The namespace for this secret is determined by the point of use.' + properties: + name: + description: name is the metadata.name of the referenced secret + type: string + required: + - name + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + status: + description: status holds observed values from the cluster. They may not be overridden. + properties: + integratedOAuthMetadata: + description: 'integratedOAuthMetadata contains the discovery endpoint data for OAuth 2.0 Authorization Server Metadata for the in-cluster integrated OAuth server. This discovery document can be viewed from its served location: oc get --raw ''/.well-known/oauth-authorization-server'' For further details, see the IETF Draft: https://tools.ietf.org/html/draft-ietf-oauth-discovery-04#section-2 This contains the observed value based on cluster state. An explicitly set value in spec.oauthMetadata has precedence over this field. This field has no meaning if authentication spec.type is not set to IntegratedOAuth. The key "oauthMetadata" is used to locate the data. If the config map or expected key is not found, no metadata is served. If the specified metadata is not valid, no metadata is served. The namespace for this config map is openshift-config-managed.' + properties: + name: + description: name is the metadata.name of the referenced config map + type: string + required: + - name + type: object + oidcClients: + description: OIDCClients is where participating operators place the current OIDC client status for OIDC clients that can be customized by the cluster-admin. + items: + properties: + componentName: + description: ComponentName is the name of the component that will consume a client configuration. + maxLength: 256 + minLength: 1 + type: string + componentNamespace: + description: ComponentNamespace is the namespace of the component that will consume a client configuration. + maxLength: 63 + minLength: 1 + type: string + conditions: + description: "Conditions are used to communicate the state of the `oidcClients` entry. \n Supported conditions include Available, Degraded and Progressing. \n If Available is true, the component is successfully using the configured client. If Degraded is true, that means something has gone wrong trying to handle the client configuration. If Progressing is true, that means the component is taking some action related to the `oidcClients` entry." + items: + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + consumingUsers: + description: ConsumingUsers is a slice of ServiceAccounts that need to have read permission on the `clientSecret` secret. + items: + description: ConsumingUser is an alias for string which we add validation to. Currently only service accounts are supported. + maxLength: 512 + minLength: 1 + pattern: ^system:serviceaccount:[a-z0-9]([-a-z0-9]*[a-z0-9])?:[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + maxItems: 5 + type: array + x-kubernetes-list-type: set + currentOIDCClients: + description: CurrentOIDCClients is a list of clients that the component is currently using. + items: + properties: + clientID: + description: ClientID is the identifier of the OIDC client from the OIDC provider + minLength: 1 + type: string + issuerURL: + description: URL is the serving URL of the token issuer. Must use the https:// scheme. + pattern: ^https:\/\/[^\s] + type: string + oidcProviderName: + description: OIDCName refers to the `name` of the provider from `oidcProviders` + minLength: 1 + type: string + required: + - clientID + - issuerURL + - oidcProviderName + type: object + type: array + x-kubernetes-list-map-keys: + - issuerURL + - clientID + x-kubernetes-list-type: map + required: + - componentName + - componentNamespace + type: object + maxItems: 20 + type: array + x-kubernetes-list-map-keys: + - componentNamespace + - componentName + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + x-kubernetes-validations: + - message: all oidcClients in the oidcProviders must match their componentName and componentNamespace to either a previously configured oidcClient or they must exist in the status.oidcClients + rule: '!has(self.spec.oidcProviders) || self.spec.oidcProviders.all(p, !has(p.oidcClients) || p.oidcClients.all(specC, self.status.oidcClients.exists(statusC, statusC.componentNamespace == specC.componentNamespace && statusC.componentName == specC.componentName) || (has(oldSelf.spec.oidcProviders) && oldSelf.spec.oidcProviders.exists(oldP, oldP.name == p.name && has(oldP.oidcClients) && oldP.oidcClients.exists(oldC, oldC.componentNamespace == specC.componentNamespace && oldC.componentName == specC.componentName)))))' + served: true + storage: true + subresources: + status: {} diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd-Default-Hypershift.yaml-patch b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd-Default-Hypershift.yaml-patch new file mode 100644 index 000000000000..dcc254fbd50c --- /dev/null +++ b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd-Default-Hypershift.yaml-patch @@ -0,0 +1,285 @@ +- op: add + path: /spec/versions/name=v1/schema/openAPIV3Schema/properties/spec/properties/oidcProviders + value: + description: "OIDCProviders are OIDC identity providers that can issue tokens for this cluster Can only be set if \"Type\" is set to \"OIDC\". \n At most one provider can be configured." + type: array + maxItems: 1 + items: + type: object + required: + - issuer + - name + properties: + claimMappings: + description: ClaimMappings describes rules on how to transform information from an ID token into a cluster identity + type: object + properties: + groups: + description: Groups is a name of the claim that should be used to construct groups for the cluster identity. The referenced claim must use array of strings values. + type: object + required: + - claim + properties: + claim: + description: Claim is a JWT token claim to be used in the mapping + type: string + prefix: + description: "Prefix is a string to prefix the value from the token in the result of the claim mapping. \n By default, no prefixing occurs. \n Example: if `prefix` is set to \"myoidc:\"\" and the `claim` in JWT contains an array of strings \"a\", \"b\" and \"c\", the mapping will result in an array of string \"myoidc:a\", \"myoidc:b\" and \"myoidc:c\"." + type: string + username: + description: "Username is a name of the claim that should be used to construct usernames for the cluster identity. \n Default value: \"sub\"" + type: object + required: + - claim + properties: + claim: + description: Claim is a JWT token claim to be used in the mapping + type: string + prefix: + type: object + required: + - prefixString + properties: + prefixString: + type: string + minLength: 1 + prefixPolicy: + description: "PrefixPolicy specifies how a prefix should apply. \n By default, claims other than `email` will be prefixed with the issuer URL to prevent naming clashes with other plugins. \n Set to \"NoPrefix\" to disable prefixing. \n Example: (1) `prefix` is set to \"myoidc:\" and `claim` is set to \"username\". If the JWT claim `username` contains value `userA`, the resulting mapped value will be \"myoidc:userA\". (2) `prefix` is set to \"myoidc:\" and `claim` is set to \"email\". If the JWT `email` claim contains value \"userA@myoidc.tld\", the resulting mapped value will be \"myoidc:userA@myoidc.tld\". (3) `prefix` is unset, `issuerURL` is set to `https://myoidc.tld`, the JWT claims include \"username\":\"userA\" and \"email\":\"userA@myoidc.tld\", and `claim` is set to: (a) \"username\": the mapped value will be \"https://myoidc.tld#userA\" (b) \"email\": the mapped value will be \"userA@myoidc.tld\"" + type: string + enum: + - "" + - NoPrefix + - Prefix + x-kubernetes-validations: + - rule: 'has(self.prefixPolicy) && self.prefixPolicy == ''Prefix'' ? (has(self.prefix) && size(self.prefix.prefixString) > 0) : !has(self.prefix)' + message: prefix must be set if prefixPolicy is 'Prefix', but must remain unset otherwise + claimValidationRules: + description: ClaimValidationRules are rules that are applied to validate token claims to authenticate users. + type: array + items: + type: object + properties: + requiredClaim: + description: RequiredClaim allows configuring a required claim name and its expected value + type: object + required: + - claim + - requiredValue + properties: + claim: + description: Claim is a name of a required claim. Only claims with string values are supported. + type: string + minLength: 1 + requiredValue: + description: RequiredValue is the required value for the claim. + type: string + minLength: 1 + type: + description: Type sets the type of the validation rule + type: string + default: RequiredClaim + enum: + - RequiredClaim + x-kubernetes-list-type: atomic + issuer: + description: Issuer describes atributes of the OIDC token issuer + type: object + required: + - audiences + - issuerURL + properties: + audiences: + description: Audiences is an array of audiences that the token was issued for. Valid tokens must include at least one of these values in their "aud" claim. Must be set to exactly one value. + type: array + maxItems: 10 + minItems: 1 + items: + type: string + minLength: 1 + x-kubernetes-list-type: set + issuerCertificateAuthority: + description: CertificateAuthority is a reference to a config map in the configuration namespace. The .data of the configMap must contain the "ca-bundle.crt" key. If unset, system trust is used instead. + type: object + required: + - name + properties: + name: + description: name is the metadata.name of the referenced config map + type: string + issuerURL: + description: URL is the serving URL of the token issuer. Must use the https:// scheme. + type: string + pattern: ^https:\/\/[^\s] + name: + description: Name of the OIDC provider + type: string + minLength: 1 + oidcClients: + description: OIDCClients contains configuration for the platform's clients that need to request tokens from the issuer + type: array + maxItems: 20 + items: + type: object + required: + - clientID + - componentName + - componentNamespace + properties: + clientID: + description: ClientID is the identifier of the OIDC client from the OIDC provider + type: string + minLength: 1 + clientSecret: + description: ClientSecret refers to a secret in the `openshift-config` namespace that contains the client secret in the `clientSecret` key of the `.data` field + type: object + required: + - name + properties: + name: + description: name is the metadata.name of the referenced secret + type: string + componentName: + description: ComponentName is the name of the component that is supposed to consume this client configuration + type: string + maxLength: 256 + minLength: 1 + componentNamespace: + description: ComponentNamespace is the namespace of the component that is supposed to consume this client configuration + type: string + maxLength: 63 + minLength: 1 + extraScopes: + description: ExtraScopes is an optional set of scopes to request tokens with. + type: array + items: + type: string + x-kubernetes-list-type: set + x-kubernetes-list-map-keys: + - componentNamespace + - componentName + x-kubernetes-list-type: map + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map +- op: add + path: /spec/versions/name=v1/schema/openAPIV3Schema/properties/status/properties/oidcClients + value: + description: OIDCClients is where participating operators place the current OIDC client status for OIDC clients that can be customized by the cluster-admin. + items: + properties: + componentName: + description: ComponentName is the name of the component that will consume a client configuration. + maxLength: 256 + minLength: 1 + type: string + componentNamespace: + description: ComponentNamespace is the namespace of the component that will consume a client configuration. + maxLength: 63 + minLength: 1 + type: string + conditions: + description: "Conditions are used to communicate the state of the `oidcClients` entry. \n Supported conditions include Available, Degraded and Progressing. \n If Available is true, the component is successfully using the configured client. If Degraded is true, that means something has gone wrong trying to handle the client configuration. If Progressing is true, that means the component is taking some action related to the `oidcClients` entry." + items: + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + consumingUsers: + description: ConsumingUsers is a slice of ServiceAccounts that need to have read permission on the `clientSecret` secret. + items: + description: ConsumingUser is an alias for string which we add validation to. Currently only service accounts are supported. + maxLength: 512 + minLength: 1 + pattern: ^system:serviceaccount:[a-z0-9]([-a-z0-9]*[a-z0-9])?:[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + maxItems: 5 + type: array + x-kubernetes-list-type: set + currentOIDCClients: + description: CurrentOIDCClients is a list of clients that the component is currently using. + items: + properties: + clientID: + description: ClientID is the identifier of the OIDC client from the OIDC provider + minLength: 1 + type: string + issuerURL: + description: URL is the serving URL of the token issuer. Must use the https:// scheme. + pattern: ^https:\/\/[^\s] + type: string + oidcProviderName: + description: OIDCName refers to the `name` of the provider from `oidcProviders` + minLength: 1 + type: string + required: + - clientID + - issuerURL + - oidcProviderName + type: object + type: array + x-kubernetes-list-map-keys: + - issuerURL + - clientID + x-kubernetes-list-type: map + required: + - componentName + - componentNamespace + type: object + maxItems: 20 + type: array + x-kubernetes-list-map-keys: + - componentNamespace + - componentName + x-kubernetes-list-type: map +- op: add + path: /spec/versions/name=v1/schema/openAPIV3Schema/x-kubernetes-validations + value: + - message: all oidcClients in the oidcProviders must match their componentName and componentNamespace to either a previously configured oidcClient or they must exist in the status.oidcClients + rule: '!has(self.spec.oidcProviders) || self.spec.oidcProviders.all(p, !has(p.oidcClients) || p.oidcClients.all(specC, self.status.oidcClients.exists(statusC, statusC.componentNamespace == specC.componentNamespace && statusC.componentName == specC.componentName) || (has(oldSelf.spec.oidcProviders) && oldSelf.spec.oidcProviders.exists(oldP, oldP.name == p.name && has(oldP.oidcClients) && oldP.oidcClients.exists(oldC, oldC.componentNamespace == specC.componentNamespace && oldC.componentName == specC.componentName)))))' +- op: add + path: /spec/versions/name=v1/schema/openAPIV3Schema/properties/spec/properties/type/enum + value: + - "" + - None + - IntegratedOAuth + - OIDC diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd-Default.yaml similarity index 98% rename from vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd.yaml rename to vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd-Default.yaml index b0cd9e67fcd9..44b890ab5db1 100644 --- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd.yaml +++ b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd-Default.yaml @@ -3,7 +3,6 @@ kind: CustomResourceDefinition metadata: annotations: api-approved.openshift.io: https://github.com/openshift/api/pull/470 - include.release.openshift.io/ibm-cloud-managed: "true" include.release.openshift.io/self-managed-high-availability: "true" include.release.openshift.io/single-node-developer: "true" release.openshift.io/feature-set: Default @@ -52,6 +51,10 @@ spec: type: description: type identifies the cluster managed, user facing authentication mode in use. Specifically, it manages the component that responds to login attempts. The default is IntegratedOAuth. type: string + enum: + - "" + - None + - IntegratedOAuth webhookTokenAuthenticator: description: "webhookTokenAuthenticator configures a remote token reviewer. These remote authentication webhooks can be used to verify bearer tokens via the tokenreviews.authentication.k8s.io REST API. This is required to honor bearer tokens that are provisioned by an external authentication service. \n Can only be set if \"Type\" is set to \"None\"." type: object diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd-TechPreviewNoUpgrade.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd-TechPreviewNoUpgrade.yaml index d475dec957c9..83a8d87d1864 100644 --- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd-TechPreviewNoUpgrade.yaml +++ b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd-TechPreviewNoUpgrade.yaml @@ -3,6 +3,7 @@ kind: CustomResourceDefinition metadata: annotations: api-approved.openshift.io: https://github.com/openshift/api/pull/470 + formatted: "true" include.release.openshift.io/ibm-cloud-managed: "true" include.release.openshift.io/self-managed-high-availability: "true" include.release.openshift.io/single-node-developer: "true" @@ -18,16 +19,9 @@ spec: scope: Cluster versions: - name: v1 - served: true - storage: true - subresources: - status: {} - "schema": - "openAPIV3Schema": + schema: + openAPIV3Schema: description: "Authentication specifies cluster-wide settings for authentication (like OAuth and webhook token authenticators). The canonical name of an instance is `cluster`. \n Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer)." - type: object - required: - - spec properties: apiVersion: description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' @@ -39,36 +33,25 @@ spec: type: object spec: description: spec holds user settable values for configuration - type: object properties: oauthMetadata: description: 'oauthMetadata contains the discovery endpoint data for OAuth 2.0 Authorization Server Metadata for an external OAuth server. This discovery document can be viewed from its served location: oc get --raw ''/.well-known/oauth-authorization-server'' For further details, see the IETF Draft: https://tools.ietf.org/html/draft-ietf-oauth-discovery-04#section-2 If oauthMetadata.name is non-empty, this value has precedence over any metadata reference stored in status. The key "oauthMetadata" is used to locate the data. If specified and the config map or expected key is not found, no metadata is served. If the specified metadata is not valid, no metadata is served. The namespace for this config map is openshift-config.' - type: object - required: - - name properties: name: description: name is the metadata.name of the referenced config map type: string + required: + - name + type: object oidcProviders: description: "OIDCProviders are OIDC identity providers that can issue tokens for this cluster Can only be set if \"Type\" is set to \"OIDC\". \n At most one provider can be configured." - type: array - maxItems: 1 items: - type: object - required: - - issuer - - name properties: claimMappings: description: ClaimMappings describes rules on how to transform information from an ID token into a cluster identity - type: object properties: groups: description: Groups is a name of the claim that should be used to construct groups for the cluster identity. The referenced claim must use array of strings values. - type: object - required: - - claim properties: claim: description: Claim is a JWT token claim to be used in the mapping @@ -76,137 +59,148 @@ spec: prefix: description: "Prefix is a string to prefix the value from the token in the result of the claim mapping. \n By default, no prefixing occurs. \n Example: if `prefix` is set to \"myoidc:\"\" and the `claim` in JWT contains an array of strings \"a\", \"b\" and \"c\", the mapping will result in an array of string \"myoidc:a\", \"myoidc:b\" and \"myoidc:c\"." type: string - username: - description: "Username is a name of the claim that should be used to construct usernames for the cluster identity. \n Default value: \"sub\"" - type: object required: - claim + type: object + username: + description: "Username is a name of the claim that should be used to construct usernames for the cluster identity. \n Default value: \"sub\"" properties: claim: description: Claim is a JWT token claim to be used in the mapping type: string prefix: - type: object - required: - - prefixString properties: prefixString: - type: string minLength: 1 + type: string + required: + - prefixString + type: object prefixPolicy: description: "PrefixPolicy specifies how a prefix should apply. \n By default, claims other than `email` will be prefixed with the issuer URL to prevent naming clashes with other plugins. \n Set to \"NoPrefix\" to disable prefixing. \n Example: (1) `prefix` is set to \"myoidc:\" and `claim` is set to \"username\". If the JWT claim `username` contains value `userA`, the resulting mapped value will be \"myoidc:userA\". (2) `prefix` is set to \"myoidc:\" and `claim` is set to \"email\". If the JWT `email` claim contains value \"userA@myoidc.tld\", the resulting mapped value will be \"myoidc:userA@myoidc.tld\". (3) `prefix` is unset, `issuerURL` is set to `https://myoidc.tld`, the JWT claims include \"username\":\"userA\" and \"email\":\"userA@myoidc.tld\", and `claim` is set to: (a) \"username\": the mapped value will be \"https://myoidc.tld#userA\" (b) \"email\": the mapped value will be \"userA@myoidc.tld\"" - type: string enum: - "" - NoPrefix - Prefix + type: string + required: + - claim + type: object x-kubernetes-validations: - - rule: 'has(self.prefixPolicy) && self.prefixPolicy == ''Prefix'' ? (has(self.prefix) && size(self.prefix.prefixString) > 0) : !has(self.prefix)' - message: prefix must be set if prefixPolicy is 'Prefix', but must remain unset otherwise + - message: prefix must be set if prefixPolicy is 'Prefix', but must remain unset otherwise + rule: 'has(self.prefixPolicy) && self.prefixPolicy == ''Prefix'' ? (has(self.prefix) && size(self.prefix.prefixString) > 0) : !has(self.prefix)' + type: object claimValidationRules: description: ClaimValidationRules are rules that are applied to validate token claims to authenticate users. - type: array items: - type: object properties: requiredClaim: description: RequiredClaim allows configuring a required claim name and its expected value - type: object - required: - - claim - - requiredValue properties: claim: description: Claim is a name of a required claim. Only claims with string values are supported. - type: string minLength: 1 + type: string requiredValue: description: RequiredValue is the required value for the claim. - type: string minLength: 1 + type: string + required: + - claim + - requiredValue + type: object type: - description: Type sets the type of the validation rule - type: string default: RequiredClaim + description: Type sets the type of the validation rule enum: - RequiredClaim + type: string + type: object + type: array x-kubernetes-list-type: atomic issuer: description: Issuer describes atributes of the OIDC token issuer - type: object - required: - - audiences - - issuerURL properties: audiences: description: Audiences is an array of audiences that the token was issued for. Valid tokens must include at least one of these values in their "aud" claim. Must be set to exactly one value. - type: array - maxItems: 1 items: - type: string minLength: 1 + type: string + maxItems: 10 + minItems: 1 + type: array x-kubernetes-list-type: set issuerCertificateAuthority: description: CertificateAuthority is a reference to a config map in the configuration namespace. The .data of the configMap must contain the "ca-bundle.crt" key. If unset, system trust is used instead. - type: object - required: - - name properties: name: description: name is the metadata.name of the referenced config map type: string + required: + - name + type: object issuerURL: description: URL is the serving URL of the token issuer. Must use the https:// scheme. - type: string pattern: ^https:\/\/[^\s] + type: string + required: + - audiences + - issuerURL + type: object name: description: Name of the OIDC provider - type: string minLength: 1 + type: string oidcClients: description: OIDCClients contains configuration for the platform's clients that need to request tokens from the issuer - type: array - maxItems: 20 items: - type: object - required: - - clientID - - componentName - - componentNamespace properties: clientID: description: ClientID is the identifier of the OIDC client from the OIDC provider - type: string minLength: 1 + type: string clientSecret: description: ClientSecret refers to a secret in the `openshift-config` namespace that contains the client secret in the `clientSecret` key of the `.data` field - type: object - required: - - name properties: name: description: name is the metadata.name of the referenced secret type: string + required: + - name + type: object componentName: description: ComponentName is the name of the component that is supposed to consume this client configuration - type: string maxLength: 256 minLength: 1 + type: string componentNamespace: description: ComponentNamespace is the namespace of the component that is supposed to consume this client configuration - type: string maxLength: 63 minLength: 1 + type: string extraScopes: description: ExtraScopes is an optional set of scopes to request tokens with. - type: array items: type: string + type: array x-kubernetes-list-type: set + required: + - clientID + - componentName + - componentNamespace + type: object + maxItems: 20 + type: array x-kubernetes-list-map-keys: - componentNamespace - componentName x-kubernetes-list-type: map + required: + - issuer + - name + type: object + maxItems: 1 + type: array x-kubernetes-list-map-keys: - name x-kubernetes-list-type: map @@ -215,160 +209,173 @@ spec: type: string type: description: type identifies the cluster managed, user facing authentication mode in use. Specifically, it manages the component that responds to login attempts. The default is IntegratedOAuth. + enum: + - "" + - None + - IntegratedOAuth + - OIDC type: string webhookTokenAuthenticator: description: "webhookTokenAuthenticator configures a remote token reviewer. These remote authentication webhooks can be used to verify bearer tokens via the tokenreviews.authentication.k8s.io REST API. This is required to honor bearer tokens that are provisioned by an external authentication service. \n Can only be set if \"Type\" is set to \"None\"." - type: object - required: - - kubeConfig properties: kubeConfig: description: "kubeConfig references a secret that contains kube config file data which describes how to access the remote webhook service. The namespace for the referenced secret is openshift-config. \n For further details, see: \n https://kubernetes.io/docs/reference/access-authn-authz/authentication/#webhook-token-authentication \n The key \"kubeConfig\" is used to locate the data. If the secret or expected key is not found, the webhook is not honored. If the specified kube config data is not valid, the webhook is not honored." - type: object - required: - - name properties: name: description: name is the metadata.name of the referenced secret type: string + required: + - name + type: object + required: + - kubeConfig + type: object webhookTokenAuthenticators: description: webhookTokenAuthenticators is DEPRECATED, setting it has no effect. - type: array items: description: deprecatedWebhookTokenAuthenticator holds the necessary configuration options for a remote token authenticator. It's the same as WebhookTokenAuthenticator but it's missing the 'required' validation on KubeConfig field. - type: object properties: kubeConfig: description: 'kubeConfig contains kube config file data which describes how to access the remote webhook service. For further details, see: https://kubernetes.io/docs/reference/access-authn-authz/authentication/#webhook-token-authentication The key "kubeConfig" is used to locate the data. If the secret or expected key is not found, the webhook is not honored. If the specified kube config data is not valid, the webhook is not honored. The namespace for this secret is determined by the point of use.' - type: object - required: - - name properties: name: description: name is the metadata.name of the referenced secret type: string + required: + - name + type: object + type: object + type: array x-kubernetes-list-type: atomic + type: object status: description: status holds observed values from the cluster. They may not be overridden. - type: object properties: integratedOAuthMetadata: description: 'integratedOAuthMetadata contains the discovery endpoint data for OAuth 2.0 Authorization Server Metadata for the in-cluster integrated OAuth server. This discovery document can be viewed from its served location: oc get --raw ''/.well-known/oauth-authorization-server'' For further details, see the IETF Draft: https://tools.ietf.org/html/draft-ietf-oauth-discovery-04#section-2 This contains the observed value based on cluster state. An explicitly set value in spec.oauthMetadata has precedence over this field. This field has no meaning if authentication spec.type is not set to IntegratedOAuth. The key "oauthMetadata" is used to locate the data. If the config map or expected key is not found, no metadata is served. If the specified metadata is not valid, no metadata is served. The namespace for this config map is openshift-config-managed.' - type: object - required: - - name properties: name: description: name is the metadata.name of the referenced config map type: string + required: + - name + type: object oidcClients: description: OIDCClients is where participating operators place the current OIDC client status for OIDC clients that can be customized by the cluster-admin. - type: array - maxItems: 20 items: - type: object - required: - - componentName - - componentNamespace properties: componentName: description: ComponentName is the name of the component that will consume a client configuration. - type: string maxLength: 256 minLength: 1 + type: string componentNamespace: description: ComponentNamespace is the namespace of the component that will consume a client configuration. - type: string maxLength: 63 minLength: 1 + type: string conditions: description: "Conditions are used to communicate the state of the `oidcClients` entry. \n Supported conditions include Available, Degraded and Progressing. \n If Available is true, the component is successfully using the configured client. If Degraded is true, that means something has gone wrong trying to handle the client configuration. If Progressing is true, that means the component is taking some action related to the `oidcClients` entry." - type: array items: description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" - type: object - required: - - lastTransitionTime - - message - - reason - - status - - type properties: lastTransitionTime: description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - type: string format: date-time + type: string message: description: message is a human readable message indicating details about the transition. This may be an empty string. - type: string maxLength: 32768 + type: string observedGeneration: description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. - type: integer format: int64 minimum: 0 + type: integer reason: description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. - type: string maxLength: 1024 minLength: 1 pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string status: description: status of the condition, one of True, False, Unknown. - type: string enum: - "True" - "False" - Unknown + type: string type: description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - type: string maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array x-kubernetes-list-map-keys: - type x-kubernetes-list-type: map consumingUsers: description: ConsumingUsers is a slice of ServiceAccounts that need to have read permission on the `clientSecret` secret. - type: array - maxItems: 5 items: description: ConsumingUser is an alias for string which we add validation to. Currently only service accounts are supported. - type: string maxLength: 512 minLength: 1 pattern: ^system:serviceaccount:[a-z0-9]([-a-z0-9]*[a-z0-9])?:[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + maxItems: 5 + type: array x-kubernetes-list-type: set currentOIDCClients: description: CurrentOIDCClients is a list of clients that the component is currently using. - type: array items: - type: object - required: - - clientID - - issuerURL - - oidcProviderName properties: clientID: description: ClientID is the identifier of the OIDC client from the OIDC provider - type: string minLength: 1 + type: string issuerURL: description: URL is the serving URL of the token issuer. Must use the https:// scheme. - type: string pattern: ^https:\/\/[^\s] + type: string oidcProviderName: description: OIDCName refers to the `name` of the provider from `oidcProviders` - type: string minLength: 1 + type: string + required: + - clientID + - issuerURL + - oidcProviderName + type: object + type: array x-kubernetes-list-map-keys: - issuerURL - clientID x-kubernetes-list-type: map + required: + - componentName + - componentNamespace + type: object + maxItems: 20 + type: array x-kubernetes-list-map-keys: - componentNamespace - componentName x-kubernetes-list-type: map + type: object + required: + - spec + type: object x-kubernetes-validations: - - rule: '!has(self.spec.oidcProviders) || self.spec.oidcProviders.all(p, !has(p.oidcClients) || p.oidcClients.all(specC, self.status.oidcClients.exists(statusC, statusC.componentNamespace == specC.componentNamespace && statusC.componentName == specC.componentName) || (has(oldSelf.spec.oidcProviders) && oldSelf.spec.oidcProviders.exists(oldP, oldP.name == p.name && has(oldP.oidcClients) && oldP.oidcClients.exists(oldC, oldC.componentNamespace == specC.componentNamespace && oldC.componentName == specC.componentName)))))' - message: all oidcClients in the oidcProviders must match their componentName and componentNamespace to either a previously configured oidcClient or they must exist in the status.oidcClients + - message: all oidcClients in the oidcProviders must match their componentName and componentNamespace to either a previously configured oidcClient or they must exist in the status.oidcClients + rule: '!has(self.spec.oidcProviders) || self.spec.oidcProviders.all(p, !has(p.oidcClients) || p.oidcClients.all(specC, self.status.oidcClients.exists(statusC, statusC.componentNamespace == specC.componentNamespace && statusC.componentName == specC.componentName) || (has(oldSelf.spec.oidcProviders) && oldSelf.spec.oidcProviders.exists(oldP, oldP.name == p.name && has(oldP.oidcClients) && oldP.oidcClients.exists(oldC, oldC.componentNamespace == specC.componentNamespace && oldC.componentName == specC.componentName)))))' + served: true + storage: true + subresources: + status: {} diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd-TechPreviewNoUpgrade.yaml-patch b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd-TechPreviewNoUpgrade.yaml-patch new file mode 100644 index 000000000000..2d7321e4951f --- /dev/null +++ b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_authentication.crd-TechPreviewNoUpgrade.yaml-patch @@ -0,0 +1,4 @@ +- op: add + path: /metadata/annotations/formatted + value: + "true" \ No newline at end of file diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-CustomNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-CustomNoUpgrade.crd.yaml index 5aece24ff9a3..fd1cba76446a 100644 --- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-CustomNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-CustomNoUpgrade.crd.yaml @@ -66,6 +66,7 @@ spec: type: string type: object type: array + x-kubernetes-list-type: atomic type: object azure: description: Azure contains settings specific to the Azure infrastructure provider. @@ -337,6 +338,7 @@ spec: maxItems: 1 minItems: 1 type: array + x-kubernetes-list-type: atomic resourcePool: description: resourcePool is the absolute path of the resource pool where virtual machines will be created. The absolute path is of the form //host//Resources/. The maximum length of the path is 2048 characters. maxLength: 2048 @@ -367,6 +369,9 @@ spec: - zone type: object type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map nodeNetworking: description: nodeNetworking contains the definition of internal and external network constraints for assigning the node's networking. If this field is omitted, networking defaults to the legacy address selection behavior which is to only support a single address and return the first one found. properties: @@ -379,6 +384,7 @@ spec: format: cidr type: string type: array + x-kubernetes-list-type: atomic network: description: network VirtualMachine's VM Network names that will be used to when searching for status.addresses fields. Note that if internal.networkSubnetCIDR and external.networkSubnetCIDR are not set, then the vNIC associated to this network must only have a single IP address assigned to it. The available networks (port groups) can be listed using `govc ls 'network/*'` type: string @@ -388,6 +394,7 @@ spec: format: cidr type: string type: array + x-kubernetes-list-type: set type: object internal: description: internal represents the network configuration of the node that is routable only within the cluster. @@ -398,6 +405,7 @@ spec: format: cidr type: string type: array + x-kubernetes-list-type: atomic network: description: network VirtualMachine's VM Network names that will be used to when searching for status.addresses fields. Note that if internal.networkSubnetCIDR and external.networkSubnetCIDR are not set, then the vNIC associated to this network must only have a single IP address assigned to it. The available networks (port groups) can be listed using `govc ls 'network/*'` type: string @@ -407,6 +415,7 @@ spec: format: cidr type: string type: array + x-kubernetes-list-type: set type: object type: object vcenters: @@ -420,6 +429,7 @@ spec: type: string minItems: 1 type: array + x-kubernetes-list-type: set port: description: port is the TCP port that will be used to communicate to the vCenter endpoint. When omitted, this means the user has no opinion and it is up to the platform to choose a sensible default, which is subject to change over time. format: int32 @@ -441,6 +451,7 @@ spec: maxItems: 1 minItems: 0 type: array + x-kubernetes-list-type: atomic type: object type: object type: object @@ -572,6 +583,7 @@ spec: type: object maxItems: 25 type: array + x-kubernetes-list-type: atomic serviceEndpoints: description: ServiceEndpoints list contains custom endpoints which will override default service endpoint of AWS Services. There must be only one ServiceEndpoint for a service. items: @@ -587,6 +599,7 @@ spec: type: string type: object type: array + x-kubernetes-list-type: atomic type: object azure: description: Azure contains settings specific to the Azure infrastructure provider. @@ -633,6 +646,7 @@ spec: type: object maxItems: 10 type: array + x-kubernetes-list-type: atomic x-kubernetes-validations: - message: resourceTags are immutable and may only be configured during installation rule: self.all(x, x in oldSelf) && oldSelf.all(x, x in self) @@ -653,6 +667,7 @@ spec: type: string maxItems: 2 type: array + x-kubernetes-list-type: set ingressIP: description: "ingressIP is an external IP which routes to the default ingress controller. The IP is a suitable target of a wildcard DNS record used to resolve default route host names. \n Deprecated: Use IngressIPs instead." type: string @@ -663,6 +678,7 @@ spec: type: string maxItems: 2 type: array + x-kubernetes-list-type: set loadBalancer: default: type: OpenShiftManagedDefault @@ -720,16 +736,60 @@ spec: gcp: description: GCP contains settings specific to the Google Cloud Platform infrastructure provider. properties: - clusterHostedDNS: - default: Disabled - description: clusterHostedDNS indicates the type of DNS solution in use within the cluster. Its default value of "Disabled" indicates that the cluster's DNS is the default provided by the cloud platform. It can be "Enabled" during install to bypass the configuration of the cloud default DNS. When "Enabled", the cluster needs to provide a self-hosted DNS solution for the cluster's installation to succeed. The cluster's use of the cloud's Load Balancers is unaffected by this setting. The value is immutable after it has been set at install time. Currently, there is no way for the customer to add additional DNS entries into the cluster hosted DNS. Enabling this functionality allows the user to start their own DNS solution outside the cluster after installation is complete. The customer would be responsible for configuring this custom DNS solution, and it can be run in addition to the in-cluster DNS solution. - enum: - - Enabled - - Disabled - type: string + cloudLoadBalancerConfig: + default: + dnsType: PlatformDefault + description: cloudLoadBalancerConfig is a union that contains the IP addresses of API, API-Int and Ingress Load Balancers created on the cloud platform. These values would not be populated on on-prem platforms. These Load Balancer IPs are used to configure the in-cluster DNS instances for API, API-Int and Ingress services. `dnsType` is expected to be set to `ClusterHosted` when these Load Balancer IP addresses are populated and used. + nullable: true + properties: + clusterHosted: + description: clusterHosted holds the IP addresses of API, API-Int and Ingress Load Balancers on Cloud Platforms. The DNS solution hosted within the cluster use these IP addresses to provide resolution for API, API-Int and Ingress services. + properties: + apiIntLoadBalancerIPs: + description: apiIntLoadBalancerIPs holds Load Balancer IPs for the internal API service. These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. Entries in the apiIntLoadBalancerIPs must be unique. A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, "10.0.0.0" or "fd00::"). + pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*) + type: string + maxItems: 16 + type: array + x-kubernetes-list-type: set + apiLoadBalancerIPs: + description: apiLoadBalancerIPs holds Load Balancer IPs for the API service. These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. Could be empty for private clusters. Entries in the apiLoadBalancerIPs must be unique. A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, "10.0.0.0" or "fd00::"). + pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*) + type: string + maxItems: 16 + type: array + x-kubernetes-list-type: set + ingressLoadBalancerIPs: + description: ingressLoadBalancerIPs holds IPs for Ingress Load Balancers. These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. Entries in the ingressLoadBalancerIPs must be unique. A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, "10.0.0.0" or "fd00::"). + pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*) + type: string + maxItems: 16 + type: array + x-kubernetes-list-type: set + type: object + dnsType: + default: PlatformDefault + description: dnsType indicates the type of DNS solution in use within the cluster. Its default value of `PlatformDefault` indicates that the cluster's DNS is the default provided by the cloud platform. It can be set to `ClusterHosted` to bypass the configuration of the cloud default DNS. In this mode, the cluster needs to provide a self-hosted DNS solution for the cluster's installation to succeed. The cluster's use of the cloud's Load Balancers is unaffected by this setting. The value is immutable after it has been set at install time. Currently, there is no way for the customer to add additional DNS entries into the cluster hosted DNS. Enabling this functionality allows the user to start their own DNS solution outside the cluster after installation is complete. The customer would be responsible for configuring this custom DNS solution, and it can be run in addition to the in-cluster DNS solution. + enum: + - ClusterHosted + - PlatformDefault + type: string + x-kubernetes-validations: + - message: dnsType is immutable + rule: oldSelf == '' || self == oldSelf + type: object x-kubernetes-validations: - - message: clusterHostedDNS is immutable and may only be configured during installation - rule: self == oldSelf + - message: clusterHosted is permitted only when dnsType is ClusterHosted + rule: 'has(self.dnsType) && self.dnsType != ''ClusterHosted'' ? !has(self.clusterHosted) : true' projectID: description: resourceGroupName is the Project ID for new GCP resources created for the cluster. type: string @@ -886,6 +946,7 @@ spec: type: string maxItems: 2 type: array + x-kubernetes-list-type: set ingressIP: description: "ingressIP is an external IP which routes to the default ingress controller. The IP is a suitable target of a wildcard DNS record used to resolve default route host names. \n Deprecated: Use IngressIPs instead." type: string @@ -896,6 +957,7 @@ spec: type: string maxItems: 2 type: array + x-kubernetes-list-type: set loadBalancer: default: type: OpenShiftManagedDefault @@ -926,6 +988,7 @@ spec: type: string maxItems: 2 type: array + x-kubernetes-list-type: set cloudName: description: cloudName is the name of the desired OpenStack cloud in the client configuration file (`clouds.yaml`). type: string @@ -939,6 +1002,7 @@ spec: type: string maxItems: 2 type: array + x-kubernetes-list-type: set loadBalancer: default: type: OpenShiftManagedDefault @@ -972,6 +1036,7 @@ spec: type: string maxItems: 2 type: array + x-kubernetes-list-type: set ingressIP: description: "ingressIP is an external IP which routes to the default ingress controller. The IP is a suitable target of a wildcard DNS record used to resolve default route host names. \n Deprecated: Use IngressIPs instead." type: string @@ -982,6 +1047,7 @@ spec: type: string maxItems: 2 type: array + x-kubernetes-list-type: set loadBalancer: default: type: OpenShiftManagedDefault @@ -1041,6 +1107,9 @@ spec: - url type: object type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map zone: description: 'zone holds the default zone for the new Power VS resources created by the cluster. Note: Currently only single-zone OCP clusters are supported' type: string @@ -1082,6 +1151,7 @@ spec: type: string maxItems: 2 type: array + x-kubernetes-list-type: set ingressIP: description: "ingressIP is an external IP which routes to the default ingress controller. The IP is a suitable target of a wildcard DNS record used to resolve default route host names. \n Deprecated: Use IngressIPs instead." type: string @@ -1092,6 +1162,7 @@ spec: type: string maxItems: 2 type: array + x-kubernetes-list-type: set loadBalancer: default: type: OpenShiftManagedDefault diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-Default.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-Default.crd.yaml index 8916d77b5bf2..8652241673e2 100644 --- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-Default.crd.yaml +++ b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-Default.crd.yaml @@ -66,6 +66,7 @@ spec: type: string type: object type: array + x-kubernetes-list-type: atomic type: object azure: description: Azure contains settings specific to the Azure infrastructure provider. @@ -337,6 +338,7 @@ spec: maxItems: 1 minItems: 1 type: array + x-kubernetes-list-type: atomic resourcePool: description: resourcePool is the absolute path of the resource pool where virtual machines will be created. The absolute path is of the form //host//Resources/. The maximum length of the path is 2048 characters. maxLength: 2048 @@ -361,6 +363,9 @@ spec: - zone type: object type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map nodeNetworking: description: nodeNetworking contains the definition of internal and external network constraints for assigning the node's networking. If this field is omitted, networking defaults to the legacy address selection behavior which is to only support a single address and return the first one found. properties: @@ -373,6 +378,7 @@ spec: format: cidr type: string type: array + x-kubernetes-list-type: atomic network: description: network VirtualMachine's VM Network names that will be used to when searching for status.addresses fields. Note that if internal.networkSubnetCIDR and external.networkSubnetCIDR are not set, then the vNIC associated to this network must only have a single IP address assigned to it. The available networks (port groups) can be listed using `govc ls 'network/*'` type: string @@ -382,6 +388,7 @@ spec: format: cidr type: string type: array + x-kubernetes-list-type: set type: object internal: description: internal represents the network configuration of the node that is routable only within the cluster. @@ -392,6 +399,7 @@ spec: format: cidr type: string type: array + x-kubernetes-list-type: atomic network: description: network VirtualMachine's VM Network names that will be used to when searching for status.addresses fields. Note that if internal.networkSubnetCIDR and external.networkSubnetCIDR are not set, then the vNIC associated to this network must only have a single IP address assigned to it. The available networks (port groups) can be listed using `govc ls 'network/*'` type: string @@ -401,6 +409,7 @@ spec: format: cidr type: string type: array + x-kubernetes-list-type: set type: object type: object vcenters: @@ -414,6 +423,7 @@ spec: type: string minItems: 1 type: array + x-kubernetes-list-type: set port: description: port is the TCP port that will be used to communicate to the vCenter endpoint. When omitted, this means the user has no opinion and it is up to the platform to choose a sensible default, which is subject to change over time. format: int32 @@ -435,6 +445,7 @@ spec: maxItems: 1 minItems: 0 type: array + x-kubernetes-list-type: atomic type: object type: object type: object @@ -566,6 +577,7 @@ spec: type: object maxItems: 25 type: array + x-kubernetes-list-type: atomic serviceEndpoints: description: ServiceEndpoints list contains custom endpoints which will override default service endpoint of AWS Services. There must be only one ServiceEndpoint for a service. items: @@ -581,6 +593,7 @@ spec: type: string type: object type: array + x-kubernetes-list-type: atomic type: object azure: description: Azure contains settings specific to the Azure infrastructure provider. @@ -627,6 +640,7 @@ spec: type: object maxItems: 10 type: array + x-kubernetes-list-type: atomic x-kubernetes-validations: - message: resourceTags are immutable and may only be configured during installation rule: self.all(x, x in oldSelf) && oldSelf.all(x, x in self) @@ -647,6 +661,7 @@ spec: type: string maxItems: 2 type: array + x-kubernetes-list-type: set ingressIP: description: "ingressIP is an external IP which routes to the default ingress controller. The IP is a suitable target of a wildcard DNS record used to resolve default route host names. \n Deprecated: Use IngressIPs instead." type: string @@ -657,6 +672,7 @@ spec: type: string maxItems: 2 type: array + x-kubernetes-list-type: set nodeDNSIP: description: nodeDNSIP is the IP address for the internal DNS used by the nodes. Unlike the one managed by the DNS operator, `NodeDNSIP` provides name resolution for the nodes themselves. There is no DNS-as-a-service for BareMetal deployments. In order to minimize necessary changes to the datacenter DNS, a DNS service is hosted as a static pod to serve those hostnames to the nodes in the cluster. type: string @@ -781,6 +797,7 @@ spec: type: string maxItems: 2 type: array + x-kubernetes-list-type: set ingressIP: description: "ingressIP is an external IP which routes to the default ingress controller. The IP is a suitable target of a wildcard DNS record used to resolve default route host names. \n Deprecated: Use IngressIPs instead." type: string @@ -791,6 +808,7 @@ spec: type: string maxItems: 2 type: array + x-kubernetes-list-type: set type: object openstack: description: OpenStack contains settings specific to the OpenStack infrastructure provider. @@ -805,6 +823,7 @@ spec: type: string maxItems: 2 type: array + x-kubernetes-list-type: set cloudName: description: cloudName is the name of the desired OpenStack cloud in the client configuration file (`clouds.yaml`). type: string @@ -818,6 +837,7 @@ spec: type: string maxItems: 2 type: array + x-kubernetes-list-type: set loadBalancer: default: type: OpenShiftManagedDefault @@ -851,6 +871,7 @@ spec: type: string maxItems: 2 type: array + x-kubernetes-list-type: set ingressIP: description: "ingressIP is an external IP which routes to the default ingress controller. The IP is a suitable target of a wildcard DNS record used to resolve default route host names. \n Deprecated: Use IngressIPs instead." type: string @@ -861,6 +882,7 @@ spec: type: string maxItems: 2 type: array + x-kubernetes-list-type: set nodeDNSIP: description: 'deprecated: as of 4.6, this field is no longer set or honored. It will be removed in a future release.' type: string @@ -904,6 +926,9 @@ spec: - url type: object type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map zone: description: 'zone holds the default zone for the new Power VS resources created by the cluster. Note: Currently only single-zone OCP clusters are supported' type: string @@ -945,6 +970,7 @@ spec: type: string maxItems: 2 type: array + x-kubernetes-list-type: set ingressIP: description: "ingressIP is an external IP which routes to the default ingress controller. The IP is a suitable target of a wildcard DNS record used to resolve default route host names. \n Deprecated: Use IngressIPs instead." type: string @@ -955,6 +981,7 @@ spec: type: string maxItems: 2 type: array + x-kubernetes-list-type: set nodeDNSIP: description: nodeDNSIP is the IP address for the internal DNS used by the nodes. Unlike the one managed by the DNS operator, `NodeDNSIP` provides name resolution for the nodes themselves. There is no DNS-as-a-service for vSphere deployments. In order to minimize necessary changes to the datacenter DNS, a DNS service is hosted as a static pod to serve those hostnames to the nodes in the cluster. type: string diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-TechPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-TechPreviewNoUpgrade.crd.yaml index f9e91cca4e11..2fbaf91b00bd 100644 --- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-TechPreviewNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_infrastructure-TechPreviewNoUpgrade.crd.yaml @@ -66,6 +66,7 @@ spec: type: string type: object type: array + x-kubernetes-list-type: atomic type: object azure: description: Azure contains settings specific to the Azure infrastructure provider. @@ -337,6 +338,7 @@ spec: maxItems: 1 minItems: 1 type: array + x-kubernetes-list-type: atomic resourcePool: description: resourcePool is the absolute path of the resource pool where virtual machines will be created. The absolute path is of the form //host//Resources/. The maximum length of the path is 2048 characters. maxLength: 2048 @@ -367,6 +369,9 @@ spec: - zone type: object type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map nodeNetworking: description: nodeNetworking contains the definition of internal and external network constraints for assigning the node's networking. If this field is omitted, networking defaults to the legacy address selection behavior which is to only support a single address and return the first one found. properties: @@ -379,6 +384,7 @@ spec: format: cidr type: string type: array + x-kubernetes-list-type: atomic network: description: network VirtualMachine's VM Network names that will be used to when searching for status.addresses fields. Note that if internal.networkSubnetCIDR and external.networkSubnetCIDR are not set, then the vNIC associated to this network must only have a single IP address assigned to it. The available networks (port groups) can be listed using `govc ls 'network/*'` type: string @@ -388,6 +394,7 @@ spec: format: cidr type: string type: array + x-kubernetes-list-type: set type: object internal: description: internal represents the network configuration of the node that is routable only within the cluster. @@ -398,6 +405,7 @@ spec: format: cidr type: string type: array + x-kubernetes-list-type: atomic network: description: network VirtualMachine's VM Network names that will be used to when searching for status.addresses fields. Note that if internal.networkSubnetCIDR and external.networkSubnetCIDR are not set, then the vNIC associated to this network must only have a single IP address assigned to it. The available networks (port groups) can be listed using `govc ls 'network/*'` type: string @@ -407,6 +415,7 @@ spec: format: cidr type: string type: array + x-kubernetes-list-type: set type: object type: object vcenters: @@ -420,6 +429,7 @@ spec: type: string minItems: 1 type: array + x-kubernetes-list-type: set port: description: port is the TCP port that will be used to communicate to the vCenter endpoint. When omitted, this means the user has no opinion and it is up to the platform to choose a sensible default, which is subject to change over time. format: int32 @@ -441,6 +451,7 @@ spec: maxItems: 1 minItems: 0 type: array + x-kubernetes-list-type: atomic type: object type: object type: object @@ -572,6 +583,7 @@ spec: type: object maxItems: 25 type: array + x-kubernetes-list-type: atomic serviceEndpoints: description: ServiceEndpoints list contains custom endpoints which will override default service endpoint of AWS Services. There must be only one ServiceEndpoint for a service. items: @@ -587,6 +599,7 @@ spec: type: string type: object type: array + x-kubernetes-list-type: atomic type: object azure: description: Azure contains settings specific to the Azure infrastructure provider. @@ -633,6 +646,7 @@ spec: type: object maxItems: 10 type: array + x-kubernetes-list-type: atomic x-kubernetes-validations: - message: resourceTags are immutable and may only be configured during installation rule: self.all(x, x in oldSelf) && oldSelf.all(x, x in self) @@ -653,6 +667,7 @@ spec: type: string maxItems: 2 type: array + x-kubernetes-list-type: set ingressIP: description: "ingressIP is an external IP which routes to the default ingress controller. The IP is a suitable target of a wildcard DNS record used to resolve default route host names. \n Deprecated: Use IngressIPs instead." type: string @@ -663,6 +678,7 @@ spec: type: string maxItems: 2 type: array + x-kubernetes-list-type: set loadBalancer: default: type: OpenShiftManagedDefault @@ -720,16 +736,60 @@ spec: gcp: description: GCP contains settings specific to the Google Cloud Platform infrastructure provider. properties: - clusterHostedDNS: - default: Disabled - description: clusterHostedDNS indicates the type of DNS solution in use within the cluster. Its default value of "Disabled" indicates that the cluster's DNS is the default provided by the cloud platform. It can be "Enabled" during install to bypass the configuration of the cloud default DNS. When "Enabled", the cluster needs to provide a self-hosted DNS solution for the cluster's installation to succeed. The cluster's use of the cloud's Load Balancers is unaffected by this setting. The value is immutable after it has been set at install time. Currently, there is no way for the customer to add additional DNS entries into the cluster hosted DNS. Enabling this functionality allows the user to start their own DNS solution outside the cluster after installation is complete. The customer would be responsible for configuring this custom DNS solution, and it can be run in addition to the in-cluster DNS solution. - enum: - - Enabled - - Disabled - type: string + cloudLoadBalancerConfig: + default: + dnsType: PlatformDefault + description: cloudLoadBalancerConfig is a union that contains the IP addresses of API, API-Int and Ingress Load Balancers created on the cloud platform. These values would not be populated on on-prem platforms. These Load Balancer IPs are used to configure the in-cluster DNS instances for API, API-Int and Ingress services. `dnsType` is expected to be set to `ClusterHosted` when these Load Balancer IP addresses are populated and used. + nullable: true + properties: + clusterHosted: + description: clusterHosted holds the IP addresses of API, API-Int and Ingress Load Balancers on Cloud Platforms. The DNS solution hosted within the cluster use these IP addresses to provide resolution for API, API-Int and Ingress services. + properties: + apiIntLoadBalancerIPs: + description: apiIntLoadBalancerIPs holds Load Balancer IPs for the internal API service. These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. Entries in the apiIntLoadBalancerIPs must be unique. A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, "10.0.0.0" or "fd00::"). + pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*) + type: string + maxItems: 16 + type: array + x-kubernetes-list-type: set + apiLoadBalancerIPs: + description: apiLoadBalancerIPs holds Load Balancer IPs for the API service. These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. Could be empty for private clusters. Entries in the apiLoadBalancerIPs must be unique. A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, "10.0.0.0" or "fd00::"). + pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*) + type: string + maxItems: 16 + type: array + x-kubernetes-list-type: set + ingressLoadBalancerIPs: + description: ingressLoadBalancerIPs holds IPs for Ingress Load Balancers. These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. Entries in the ingressLoadBalancerIPs must be unique. A maximum of 16 IP addresses are permitted. + format: ip + items: + description: IP is an IP address (for example, "10.0.0.0" or "fd00::"). + pattern: (^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*) + type: string + maxItems: 16 + type: array + x-kubernetes-list-type: set + type: object + dnsType: + default: PlatformDefault + description: dnsType indicates the type of DNS solution in use within the cluster. Its default value of `PlatformDefault` indicates that the cluster's DNS is the default provided by the cloud platform. It can be set to `ClusterHosted` to bypass the configuration of the cloud default DNS. In this mode, the cluster needs to provide a self-hosted DNS solution for the cluster's installation to succeed. The cluster's use of the cloud's Load Balancers is unaffected by this setting. The value is immutable after it has been set at install time. Currently, there is no way for the customer to add additional DNS entries into the cluster hosted DNS. Enabling this functionality allows the user to start their own DNS solution outside the cluster after installation is complete. The customer would be responsible for configuring this custom DNS solution, and it can be run in addition to the in-cluster DNS solution. + enum: + - ClusterHosted + - PlatformDefault + type: string + x-kubernetes-validations: + - message: dnsType is immutable + rule: oldSelf == '' || self == oldSelf + type: object x-kubernetes-validations: - - message: clusterHostedDNS is immutable and may only be configured during installation - rule: self == oldSelf + - message: clusterHosted is permitted only when dnsType is ClusterHosted + rule: 'has(self.dnsType) && self.dnsType != ''ClusterHosted'' ? !has(self.clusterHosted) : true' projectID: description: resourceGroupName is the Project ID for new GCP resources created for the cluster. type: string @@ -886,6 +946,7 @@ spec: type: string maxItems: 2 type: array + x-kubernetes-list-type: set ingressIP: description: "ingressIP is an external IP which routes to the default ingress controller. The IP is a suitable target of a wildcard DNS record used to resolve default route host names. \n Deprecated: Use IngressIPs instead." type: string @@ -896,6 +957,7 @@ spec: type: string maxItems: 2 type: array + x-kubernetes-list-type: set loadBalancer: default: type: OpenShiftManagedDefault @@ -926,6 +988,7 @@ spec: type: string maxItems: 2 type: array + x-kubernetes-list-type: set cloudName: description: cloudName is the name of the desired OpenStack cloud in the client configuration file (`clouds.yaml`). type: string @@ -939,6 +1002,7 @@ spec: type: string maxItems: 2 type: array + x-kubernetes-list-type: set loadBalancer: default: type: OpenShiftManagedDefault @@ -972,6 +1036,7 @@ spec: type: string maxItems: 2 type: array + x-kubernetes-list-type: set ingressIP: description: "ingressIP is an external IP which routes to the default ingress controller. The IP is a suitable target of a wildcard DNS record used to resolve default route host names. \n Deprecated: Use IngressIPs instead." type: string @@ -982,6 +1047,7 @@ spec: type: string maxItems: 2 type: array + x-kubernetes-list-type: set loadBalancer: default: type: OpenShiftManagedDefault @@ -1041,6 +1107,9 @@ spec: - url type: object type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map zone: description: 'zone holds the default zone for the new Power VS resources created by the cluster. Note: Currently only single-zone OCP clusters are supported' type: string @@ -1082,6 +1151,7 @@ spec: type: string maxItems: 2 type: array + x-kubernetes-list-type: set ingressIP: description: "ingressIP is an external IP which routes to the default ingress controller. The IP is a suitable target of a wildcard DNS record used to resolve default route host names. \n Deprecated: Use IngressIPs instead." type: string @@ -1092,6 +1162,7 @@ spec: type: string maxItems: 2 type: array + x-kubernetes-list-type: set loadBalancer: default: type: OpenShiftManagedDefault diff --git a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_network-Default.crd.yaml b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_network-Default.crd.yaml index 4582bf8fdfe0..8548be65716c 100644 --- a/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_network-Default.crd.yaml +++ b/vendor/github.com/openshift/api/config/v1/0000_10_config-operator_01_network-Default.crd.yaml @@ -110,6 +110,53 @@ spec: clusterNetworkMTU: description: ClusterNetworkMTU is the MTU for inter-pod networking. type: integer + conditions: + description: 'conditions represents the observations of a network.config current state. Known .status.conditions.type are: "NetworkTypeMigrationInProgress", "NetworkTypeMigrationMTUReady", "NetworkTypeMigrationTargetCNIAvailable", "NetworkTypeMigrationTargetCNIInUse" and "NetworkTypeMigrationOriginalCNIPurged"' + type: array + items: + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + type: object + required: + - lastTransitionTime + - message + - reason + - status + - type + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + type: string + format: date-time + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + type: string + maxLength: 32768 + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + type: integer + format: int64 + minimum: 0 + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + type: string + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + status: + description: status of the condition, one of True, False, Unknown. + type: string + enum: + - "True" + - "False" + - Unknown + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + type: string + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map migration: description: Migration contains the cluster network migration configuration. type: object diff --git a/vendor/github.com/openshift/api/config/v1/custom.authentication.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/custom.authentication.testsuite.yaml index 1dccb080ac22..92e7d72e624b 100644 --- a/vendor/github.com/openshift/api/config/v1/custom.authentication.testsuite.yaml +++ b/vendor/github.com/openshift/api/config/v1/custom.authentication.testsuite.yaml @@ -12,6 +12,17 @@ tests: apiVersion: config.openshift.io/v1 kind: Authentication spec: {} + - name: Should be able to use the OIDC type + initial: | + apiVersion: config.openshift.io/v1 + kind: Authentication + spec: + type: OIDC + expected: | + apiVersion: config.openshift.io/v1 + kind: Authentication + spec: + type: OIDC - name: Cannot set username claim prefix with policy NoPrefix initial: | apiVersion: config.openshift.io/v1 diff --git a/vendor/github.com/openshift/api/config/v1/custom.clusterversion.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/custom.clusterversion.testsuite.yaml new file mode 100644 index 000000000000..f3090558b900 --- /dev/null +++ b/vendor/github.com/openshift/api/config/v1/custom.clusterversion.testsuite.yaml @@ -0,0 +1,472 @@ +apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this +name: "[CustomNoUpgrade] ClusterVersion" +crd: 0000_00_cluster-version-operator_01_clusterversion-CustomNoUpgrade.crd.yaml +tests: + onCreate: + - name: Should be able to create a minimal ClusterVersion + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + expected: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + - name: Should allow image to be set + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + desiredUpdate: + image: bar + expected: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + desiredUpdate: + image: bar + - name: Should allow version to be set + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + desiredUpdate: + version: 4.11.1 + expected: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + desiredUpdate: + version: 4.11.1 + - name: Should allow architecture to be empty + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + desiredUpdate: + architecture: "" + version: 4.11.1 + expected: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + desiredUpdate: + architecture: "" + version: 4.11.1 + - name: Should allow architecture and version to be set + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + desiredUpdate: + architecture: Multi + version: 4.11.1 + expected: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + desiredUpdate: + architecture: Multi + version: 4.11.1 + - name: Version must be set if architecture is set + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + desiredUpdate: + architecture: Multi + expectedError: "Version must be set if Architecture is set" + - name: Should not allow image and architecture to be set + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + desiredUpdate: + architecture: Multi + version: 4.11.1 + image: bar + expectedError: "cannot set both Architecture and Image" + - name: Should be able to create a ClusterVersion with base capability None, and additional capabilities baremetal and MachineAPI + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + additionalEnabledCapabilities: + - baremetal + - MachineAPI + expected: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + additionalEnabledCapabilities: + - baremetal + - MachineAPI + - name: Should not be able to create a ClusterVersion with base capability None, and additional capabilities baremetal without MachineAPI + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + additionalEnabledCapabilities: + - baremetal + expectedError: the `baremetal` capability requires the `MachineAPI` capability, which is neither explicitly or implicitly enabled in this cluster, please enable the `MachineAPI` capability + - name: Should be able to create a ClusterVersion with base capability None, and additional capabilities marketplace and OperatorLifecycleManager + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + additionalEnabledCapabilities: + - marketplace + - OperatorLifecycleManager + expected: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + additionalEnabledCapabilities: + - marketplace + - OperatorLifecycleManager + - name: Should not be able to create a ClusterVersion with base capability None, and additional capabilities marketplace without OperatorLifecycleManager + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + additionalEnabledCapabilities: + - marketplace + expectedError: the `marketplace` capability requires the `OperatorLifecycleManager` capability, which is neither explicitly or implicitly enabled in this cluster, please enable the `OperatorLifecycleManager` capability + - name: Should be able to set a custom signature store + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + signatureStores: + - url: "https://osus.ocp.com" + expected: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + signatureStores: + - url: "https://osus.ocp.com" + - name: Should be able to set multiple custom signature store + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + signatureStores: + - url: "https://osus1.ocp.com" + - url: "https://osus2.ocp.com" + expected: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + signatureStores: + - url: "https://osus1.ocp.com" + - url: "https://osus2.ocp.com" + - name: Invalid custom signature store should throw error + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + signatureStores: + - url: "osus1.ocp.com" + expectedError: "url must be a valid absolute URL" + - name: Should be able to unset the signature stores + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + signatureStores: [] + expected: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + signatureStores: [] + onUpdate: + - name: Should not allow image to be set if architecture set + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + desiredUpdate: + architecture: Multi + version: 4.11.1 + updated: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + desiredUpdate: + architecture: Multi + version: 4.11.1 + image: bar + expectedError: "cannot set both Architecture and Image" + - name: Should not allow architecture to be set if image set + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + desiredUpdate: + image: bar + updated: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + desiredUpdate: + architecture: Multi + version: 4.11.1 + image: bar + expectedError: "cannot set both Architecture and Image" + - name: Should be able to add the baremetal capability with a ClusterVersion with base capability None, and implicitly enabled MachineAPI + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + status: + desired: + version: foo + image: foo + observedGeneration: 1 + versionHash: foo + availableUpdates: + - version: foo + image: foo + capabilities: + enabledCapabilities: + - MachineAPI + updated: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + additionalEnabledCapabilities: + - baremetal + status: + desired: + version: foo + image: foo + observedGeneration: 1 + versionHash: foo + availableUpdates: + - version: foo + image: foo + capabilities: + enabledCapabilities: + - MachineAPI + expected: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + additionalEnabledCapabilities: + - baremetal + status: + desired: + version: foo + image: foo + observedGeneration: 1 + versionHash: foo + availableUpdates: + - version: foo + image: foo + capabilities: + enabledCapabilities: + - MachineAPI + - name: Should be able to add the baremetal capability with a ClusterVersion with base capability None, with the Machine API capability + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + updated: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + additionalEnabledCapabilities: + - baremetal + - MachineAPI + expected: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + additionalEnabledCapabilities: + - baremetal + - MachineAPI + - name: Should not be able to add the baremetal capability with a ClusterVersion with base capability None, and without MachineAPI + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + updated: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + additionalEnabledCapabilities: + - baremetal + expectedError: the `baremetal` capability requires the `MachineAPI` capability, which is neither explicitly or implicitly enabled in this cluster, please enable the `MachineAPI` capability + - name: Should be able to add the marketplace capability with a ClusterVersion with base capability None, and implicitly enabled OperatorLifecycleManager + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + status: + desired: + version: foo + image: foo + observedGeneration: 1 + versionHash: foo + availableUpdates: + - version: foo + image: foo + capabilities: + enabledCapabilities: + - OperatorLifecycleManager + updated: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + additionalEnabledCapabilities: + - marketplace + status: + desired: + version: foo + image: foo + observedGeneration: 1 + versionHash: foo + availableUpdates: + - version: foo + image: foo + capabilities: + enabledCapabilities: + - OperatorLifecycleManager + expected: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + additionalEnabledCapabilities: + - marketplace + status: + desired: + version: foo + image: foo + observedGeneration: 1 + versionHash: foo + availableUpdates: + - version: foo + image: foo + capabilities: + enabledCapabilities: + - OperatorLifecycleManager + - name: Should be able to add the marketplace capability with a ClusterVersion with base capability None, with the OperatorLifecycleManager capability + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + updated: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + additionalEnabledCapabilities: + - marketplace + - OperatorLifecycleManager + expected: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + additionalEnabledCapabilities: + - marketplace + - OperatorLifecycleManager + - name: Should not be able to add the marketplace capability with a ClusterVersion with base capability None, and without OperatorLifecycleManager + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + updated: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + additionalEnabledCapabilities: + - marketplace + expectedError: the `marketplace` capability requires the `OperatorLifecycleManager` capability, which is neither explicitly or implicitly enabled in this cluster, please enable the `OperatorLifecycleManager` capability diff --git a/vendor/github.com/openshift/api/config/v1/feature_gates.go b/vendor/github.com/openshift/api/config/v1/feature_gates.go index 51e826f7e023..dc53db89d2a0 100644 --- a/vendor/github.com/openshift/api/config/v1/feature_gates.go +++ b/vendor/github.com/openshift/api/config/v1/feature_gates.go @@ -381,4 +381,35 @@ var ( ResponsiblePerson: "djoshy", OwningProduct: ocpSpecific, } + + FeatureGateDisableKubeletCloudCredentialProviders = FeatureGateName("DisableKubeletCloudCredentialProviders") + disableKubeletCloudCredentialProviders = FeatureGateDescription{ + FeatureGateAttributes: FeatureGateAttributes{ + Name: FeatureGateDisableKubeletCloudCredentialProviders, + }, + OwningJiraComponent: "cloud-provider", + ResponsiblePerson: "jspeed", + OwningProduct: kubernetes, + } + + + FeatureGateOnClusterBuild = FeatureGateName("OnClusterBuild") + onClusterBuild = FeatureGateDescription{ + FeatureGateAttributes: FeatureGateAttributes{ + Name: FeatureGateOnClusterBuild, + }, + OwningJiraComponent: "MachineConfigOperator", + ResponsiblePerson: "dkhater", + OwningProduct: ocpSpecific, + } + + FeatureGateSignatureStores = FeatureGateName("SignatureStores") + signatureStores = FeatureGateDescription{ + FeatureGateAttributes: FeatureGateAttributes{ + Name: FeatureGateSignatureStores, + }, + OwningJiraComponent: "over-the-air-updates", + ResponsiblePerson: "lmohanty", + OwningProduct: ocpSpecific, + } ) diff --git a/vendor/github.com/openshift/api/config/v1/stable.authentication.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/stable.authentication.testsuite.yaml index dec3667561c3..6e966c15b459 100644 --- a/vendor/github.com/openshift/api/config/v1/stable.authentication.testsuite.yaml +++ b/vendor/github.com/openshift/api/config/v1/stable.authentication.testsuite.yaml @@ -1,6 +1,6 @@ apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this name: "[Stable] Authentication" -crd: 0000_10_config-operator_01_authentication.crd.yaml +crd: 0000_10_config-operator_01_authentication.crd-Default.yaml tests: onCreate: - name: Should be able to create a minimal Authentication @@ -12,3 +12,10 @@ tests: apiVersion: config.openshift.io/v1 kind: Authentication spec: {} + - name: Shouldn't be able to use the OIDC type in a stable version of the resource + initial: | + apiVersion: config.openshift.io/v1 + kind: Authentication + spec: + type: OIDC + expectedError: "spec.type: Unsupported value: \"OIDC\": supported values: \"\", \"None\", \"IntegratedOAuth\"" \ No newline at end of file diff --git a/vendor/github.com/openshift/api/config/v1/stable.clusterversion.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/stable.clusterversion.testsuite.yaml index 50bb3e027483..4c3fed149d89 100644 --- a/vendor/github.com/openshift/api/config/v1/stable.clusterversion.testsuite.yaml +++ b/vendor/github.com/openshift/api/config/v1/stable.clusterversion.testsuite.yaml @@ -1,6 +1,6 @@ apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this name: "[Stable] ClusterVersion" -crd: 0000_00_cluster-version-operator_01_clusterversion.crd.yaml +crd: 0000_00_cluster-version-operator_01_clusterversion-Default.crd.yaml tests: onCreate: - name: Should be able to create a minimal ClusterVersion diff --git a/vendor/github.com/openshift/api/config/v1/stable.hypershift.authentication.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/stable.hypershift.authentication.testsuite.yaml new file mode 100644 index 000000000000..406bf38617ce --- /dev/null +++ b/vendor/github.com/openshift/api/config/v1/stable.hypershift.authentication.testsuite.yaml @@ -0,0 +1,298 @@ +apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this +name: "[Stable][Hypershift] Authentication" +crd: 0000_10_config-operator_01_authentication.crd-Default-Hypershift.yaml +tests: + onCreate: + - name: Should be able to create a minimal Authentication + initial: | + apiVersion: config.openshift.io/v1 + kind: Authentication + spec: {} # No spec is required for a Authentication + expected: | + apiVersion: config.openshift.io/v1 + kind: Authentication + spec: {} + - name: Should be able to use the OIDC type + initial: | + apiVersion: config.openshift.io/v1 + kind: Authentication + spec: + type: OIDC + expected: | + apiVersion: config.openshift.io/v1 + kind: Authentication + spec: + type: OIDC + - name: Cannot set username claim prefix with policy NoPrefix + initial: | + apiVersion: config.openshift.io/v1 + kind: Authentication + spec: + type: OIDC + oidcProviders: + - name: myoidc + issuer: + issuerURL: https://meh.tld + audiences: ['openshift-aud'] + claimMappings: + username: + claim: "preferred_username" + prefixPolicy: NoPrefix + prefix: + prefixString: "myoidc:" + expectedError: "prefix must be set if prefixPolicy is 'Prefix', but must remain unset otherwise" + - name: Can set username claim prefix with policy Prefix + initial: | + apiVersion: config.openshift.io/v1 + kind: Authentication + spec: + type: OIDC + oidcProviders: + - name: myoidc + issuer: + issuerURL: https://meh.tld + audiences: ['openshift-aud'] + claimMappings: + username: + claim: "preferred_username" + prefixPolicy: Prefix + prefix: + prefixString: "myoidc:" + expected: | + apiVersion: config.openshift.io/v1 + kind: Authentication + spec: + type: OIDC + oidcProviders: + - name: myoidc + issuer: + issuerURL: https://meh.tld + audiences: ['openshift-aud'] + claimMappings: + username: + claim: "preferred_username" + prefixPolicy: Prefix + prefix: + prefixString: "myoidc:" + - name: Cannot leave username claim prefix blank with policy Prefix + initial: | + apiVersion: config.openshift.io/v1 + kind: Authentication + spec: + type: OIDC + oidcProviders: + - name: myoidc + issuer: + issuerURL: https://meh.tld + audiences: ['openshift-aud'] + claimMappings: + username: + claim: "preferred_username" + prefixPolicy: Prefix + expectedError: "prefix must be set if prefixPolicy is 'Prefix', but must remain unset otherwise" + - name: Can set OIDC providers with no username prefixing + initial: | + apiVersion: config.openshift.io/v1 + kind: Authentication + spec: + type: OIDC + oidcProviders: + - name: myoidc + issuer: + issuerURL: https://meh.tld + audiences: ['openshift-aud'] + claimMappings: + username: + claim: "preferred_username" + prefixPolicy: NoPrefix + expected: | + apiVersion: config.openshift.io/v1 + kind: Authentication + spec: + type: OIDC + oidcProviders: + - name: myoidc + issuer: + issuerURL: https://meh.tld + audiences: ['openshift-aud'] + claimMappings: + username: + claim: "preferred_username" + prefixPolicy: NoPrefix + onUpdate: + - name: Updating OIDC provider with a client that's not in the status + initial: &initConfig | + apiVersion: config.openshift.io/v1 + kind: Authentication + spec: + type: OIDC + oidcProviders: + - name: myoidc + issuer: + issuerURL: https://meh.tld + audiences: ['openshift-aud'] + oidcClients: + - componentNamespace: namespace + componentName: preexisting + clientID: someclient + - componentNamespace: namespace + componentName: name + clientID: legitclient + status: + oidcClients: + - componentNamespace: namespace + componentName: name + - componentNamespace: namespace2 + componentName: name2 + - componentNamespace: namespace2 + componentName: name3 + updated: | + apiVersion: config.openshift.io/v1 + kind: Authentication + spec: + type: OIDC + oidcProviders: + - name: myoidc + issuer: + issuerURL: https://meh.tld + audiences: ['openshift-aud'] + oidcClients: + - componentNamespace: namespace + componentName: preexisting + clientID: someclient + - componentNamespace: namespace + componentName: name + clientID: legitclient + - componentNamespace: dif-namespace # new client here + componentName: tehName + clientID: cool-client + status: + oidcClients: + - componentNamespace: namespace + componentName: name + - componentNamespace: namespace2 + componentName: name2 + - componentNamespace: namespace2 + componentName: name3 + expectedError: "all oidcClients in the oidcProviders must match their componentName and componentNamespace to either a previously configured oidcClient or they must exist in the status.oidcClients" + - name: Updating OIDC provider with a client that's different from the previous one + initial: *initConfig + updated: | + apiVersion: config.openshift.io/v1 + kind: Authentication + spec: + type: OIDC + oidcProviders: + - name: myoidc + issuer: + issuerURL: https://meh.tld + audiences: ['openshift-aud'] + oidcClients: + - componentNamespace: dif-namespace + componentName: tehName + clientID: cool-client + status: + oidcClients: + - componentNamespace: namespace + componentName: name + - componentNamespace: namespace2 + componentName: name2 + - componentNamespace: namespace2 + componentName: name3 + expectedError: "all oidcClients in the oidcProviders must match their componentName and componentNamespace to either a previously configured oidcClient or they must exist in the status.oidcClients" + - name: Updating previously existing client + initial: *initConfig + updated: &prevExistingUpdated | + apiVersion: config.openshift.io/v1 + kind: Authentication + spec: + type: OIDC + oidcProviders: + - name: myoidc + issuer: + issuerURL: https://meh.tld + audiences: ['openshift-aud'] + oidcClients: + - componentNamespace: namespace + componentName: preexisting + clientID: different-client + status: + oidcClients: + - componentNamespace: namespace + componentName: name + - componentNamespace: namespace2 + componentName: name2 + - componentNamespace: namespace2 + componentName: name3 + expected: *prevExistingUpdated + - name: Removing a configured client from the status (== component unregister) + initial: *initConfig + updated: &removeFromStatus | + apiVersion: config.openshift.io/v1 + kind: Authentication + spec: + type: OIDC + oidcProviders: + - name: myoidc + issuer: + issuerURL: https://meh.tld + audiences: ['openshift-aud'] + oidcClients: + - componentNamespace: namespace + componentName: preexisting + clientID: different-client + - componentNamespace: namespace + componentName: name + clientID: legitclient + status: + oidcClients: + - componentNamespace: namespace2 + componentName: name2 + - componentNamespace: namespace2 + componentName: name3 + expected: *removeFromStatus + - name: Simply add a valid client + initial: *initConfig + updated: &addClient | + apiVersion: config.openshift.io/v1 + kind: Authentication + spec: + type: OIDC + oidcProviders: + - name: myoidc + issuer: + issuerURL: https://meh.tld + audiences: ['openshift-aud'] + oidcClients: + - componentNamespace: namespace + componentName: preexisting + clientID: different-client + - componentNamespace: namespace + componentName: name + clientID: legitclient + - componentNamespace: namespace2 + componentName: name3 + clientID: justavalidclient + status: + oidcClients: + - componentNamespace: namespace + componentName: name + - componentNamespace: namespace2 + componentName: name2 + - componentNamespace: namespace2 + componentName: name3 + expected: *addClient + - name: Remove all oidcProviders + initial: *initConfig + updated: &removeFromStatus | + apiVersion: config.openshift.io/v1 + kind: Authentication + spec: + type: OIDC + status: + oidcClients: + - componentNamespace: namespace2 + componentName: name2 + - componentNamespace: namespace2 + componentName: name3 + expected: *removeFromStatus diff --git a/vendor/github.com/openshift/api/config/v1/stable.network.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/stable.network.testsuite.yaml index 7922d44812ee..c85d122a65ce 100644 --- a/vendor/github.com/openshift/api/config/v1/stable.network.testsuite.yaml +++ b/vendor/github.com/openshift/api/config/v1/stable.network.testsuite.yaml @@ -12,7 +12,7 @@ tests: apiVersion: config.openshift.io/v1 kind: Network spec: {} - - name: Should not be able to set status conditions + - name: Should be able to set status conditions initial: | apiVersion: config.openshift.io/v1 kind: Network @@ -28,4 +28,10 @@ tests: apiVersion: config.openshift.io/v1 kind: Network spec: {} - status: {} + status: + conditions: + - type: NetworkTypeMigrationInProgress + status: "False" + reason: "Reason" + message: "Message" + lastTransitionTime: "2023-10-25T12:00:00Z" diff --git a/vendor/github.com/openshift/api/config/v1/techpreview.authentication.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/techpreview.authentication.testsuite.yaml index f904ceafabe3..9d978fcf5b2a 100644 --- a/vendor/github.com/openshift/api/config/v1/techpreview.authentication.testsuite.yaml +++ b/vendor/github.com/openshift/api/config/v1/techpreview.authentication.testsuite.yaml @@ -12,6 +12,17 @@ tests: apiVersion: config.openshift.io/v1 kind: Authentication spec: {} + - name: Should be able to use the OIDC type + initial: | + apiVersion: config.openshift.io/v1 + kind: Authentication + spec: + type: OIDC + expected: | + apiVersion: config.openshift.io/v1 + kind: Authentication + spec: + type: OIDC - name: Cannot set username claim prefix with policy NoPrefix initial: | apiVersion: config.openshift.io/v1 @@ -284,4 +295,4 @@ tests: componentName: name2 - componentNamespace: namespace2 componentName: name3 - expected: *removeFromStatus \ No newline at end of file + expected: *removeFromStatus diff --git a/vendor/github.com/openshift/api/config/v1/techpreview.clusterversion.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/techpreview.clusterversion.testsuite.yaml new file mode 100644 index 000000000000..71988108e5cd --- /dev/null +++ b/vendor/github.com/openshift/api/config/v1/techpreview.clusterversion.testsuite.yaml @@ -0,0 +1,472 @@ +apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this +name: "[TechPreviewNoUpgrade] ClusterVersion" +crd: 0000_00_cluster-version-operator_01_clusterversion-TechPreviewNoUpgrade.crd.yaml +tests: + onCreate: + - name: Should be able to create a minimal ClusterVersion + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + expected: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + - name: Should allow image to be set + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + desiredUpdate: + image: bar + expected: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + desiredUpdate: + image: bar + - name: Should allow version to be set + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + desiredUpdate: + version: 4.11.1 + expected: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + desiredUpdate: + version: 4.11.1 + - name: Should allow architecture to be empty + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + desiredUpdate: + architecture: "" + version: 4.11.1 + expected: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + desiredUpdate: + architecture: "" + version: 4.11.1 + - name: Should allow architecture and version to be set + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + desiredUpdate: + architecture: Multi + version: 4.11.1 + expected: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + desiredUpdate: + architecture: Multi + version: 4.11.1 + - name: Version must be set if architecture is set + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + desiredUpdate: + architecture: Multi + expectedError: "Version must be set if Architecture is set" + - name: Should not allow image and architecture to be set + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + desiredUpdate: + architecture: Multi + version: 4.11.1 + image: bar + expectedError: "cannot set both Architecture and Image" + - name: Should be able to create a ClusterVersion with base capability None, and additional capabilities baremetal and MachineAPI + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + additionalEnabledCapabilities: + - baremetal + - MachineAPI + expected: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + additionalEnabledCapabilities: + - baremetal + - MachineAPI + - name: Should not be able to create a ClusterVersion with base capability None, and additional capabilities baremetal without MachineAPI + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + additionalEnabledCapabilities: + - baremetal + expectedError: the `baremetal` capability requires the `MachineAPI` capability, which is neither explicitly or implicitly enabled in this cluster, please enable the `MachineAPI` capability + - name: Should be able to create a ClusterVersion with base capability None, and additional capabilities marketplace and OperatorLifecycleManager + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + additionalEnabledCapabilities: + - marketplace + - OperatorLifecycleManager + expected: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + additionalEnabledCapabilities: + - marketplace + - OperatorLifecycleManager + - name: Should not be able to create a ClusterVersion with base capability None, and additional capabilities marketplace without OperatorLifecycleManager + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + additionalEnabledCapabilities: + - marketplace + expectedError: the `marketplace` capability requires the `OperatorLifecycleManager` capability, which is neither explicitly or implicitly enabled in this cluster, please enable the `OperatorLifecycleManager` capability + - name: Should be able to set a custom signature store + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + signatureStores: + - url: "https://osus.ocp.com" + expected: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + signatureStores: + - url: "https://osus.ocp.com" + - name: Should be able to set multiple custom signature store + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + signatureStores: + - url: "https://osus1.ocp.com" + - url: "https://osus2.ocp.com" + expected: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + signatureStores: + - url: "https://osus1.ocp.com" + - url: "https://osus2.ocp.com" + - name: Invalid custom signature store should throw error + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + signatureStores: + - url: "osus1.ocp.com" + expectedError: "url must be a valid absolute URL" + - name: Should be able to unset the signature stores + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + signatureStores: [] + expected: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + signatureStores: [] + onUpdate: + - name: Should not allow image to be set if architecture set + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + desiredUpdate: + architecture: Multi + version: 4.11.1 + updated: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + desiredUpdate: + architecture: Multi + version: 4.11.1 + image: bar + expectedError: "cannot set both Architecture and Image" + - name: Should not allow architecture to be set if image set + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + desiredUpdate: + image: bar + updated: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + desiredUpdate: + architecture: Multi + version: 4.11.1 + image: bar + expectedError: "cannot set both Architecture and Image" + - name: Should be able to add the baremetal capability with a ClusterVersion with base capability None, and implicitly enabled MachineAPI + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + status: + desired: + version: foo + image: foo + observedGeneration: 1 + versionHash: foo + availableUpdates: + - version: foo + image: foo + capabilities: + enabledCapabilities: + - MachineAPI + updated: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + additionalEnabledCapabilities: + - baremetal + status: + desired: + version: foo + image: foo + observedGeneration: 1 + versionHash: foo + availableUpdates: + - version: foo + image: foo + capabilities: + enabledCapabilities: + - MachineAPI + expected: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + additionalEnabledCapabilities: + - baremetal + status: + desired: + version: foo + image: foo + observedGeneration: 1 + versionHash: foo + availableUpdates: + - version: foo + image: foo + capabilities: + enabledCapabilities: + - MachineAPI + - name: Should be able to add the baremetal capability with a ClusterVersion with base capability None, with the Machine API capability + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + updated: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + additionalEnabledCapabilities: + - baremetal + - MachineAPI + expected: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + additionalEnabledCapabilities: + - baremetal + - MachineAPI + - name: Should not be able to add the baremetal capability with a ClusterVersion with base capability None, and without MachineAPI + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + updated: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + additionalEnabledCapabilities: + - baremetal + expectedError: the `baremetal` capability requires the `MachineAPI` capability, which is neither explicitly or implicitly enabled in this cluster, please enable the `MachineAPI` capability + - name: Should be able to add the marketplace capability with a ClusterVersion with base capability None, and implicitly enabled OperatorLifecycleManager + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + status: + desired: + version: foo + image: foo + observedGeneration: 1 + versionHash: foo + availableUpdates: + - version: foo + image: foo + capabilities: + enabledCapabilities: + - OperatorLifecycleManager + updated: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + additionalEnabledCapabilities: + - marketplace + status: + desired: + version: foo + image: foo + observedGeneration: 1 + versionHash: foo + availableUpdates: + - version: foo + image: foo + capabilities: + enabledCapabilities: + - OperatorLifecycleManager + expected: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + additionalEnabledCapabilities: + - marketplace + status: + desired: + version: foo + image: foo + observedGeneration: 1 + versionHash: foo + availableUpdates: + - version: foo + image: foo + capabilities: + enabledCapabilities: + - OperatorLifecycleManager + - name: Should be able to add the marketplace capability with a ClusterVersion with base capability None, with the OperatorLifecycleManager capability + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + updated: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + additionalEnabledCapabilities: + - marketplace + - OperatorLifecycleManager + expected: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + additionalEnabledCapabilities: + - marketplace + - OperatorLifecycleManager + - name: Should not be able to add the marketplace capability with a ClusterVersion with base capability None, and without OperatorLifecycleManager + initial: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + updated: | + apiVersion: config.openshift.io/v1 + kind: ClusterVersion + spec: + clusterID: foo + capabilities: + baselineCapabilitySet: None + additionalEnabledCapabilities: + - marketplace + expectedError: the `marketplace` capability requires the `OperatorLifecycleManager` capability, which is neither explicitly or implicitly enabled in this cluster, please enable the `OperatorLifecycleManager` capability diff --git a/vendor/github.com/openshift/api/config/v1/techpreview.infrastructure.testsuite.yaml b/vendor/github.com/openshift/api/config/v1/techpreview.infrastructure.testsuite.yaml index 78501fb17496..d4a1113f01d7 100644 --- a/vendor/github.com/openshift/api/config/v1/techpreview.infrastructure.testsuite.yaml +++ b/vendor/github.com/openshift/api/config/v1/techpreview.infrastructure.testsuite.yaml @@ -517,48 +517,233 @@ tests: resourceTags: - {parentID: "test-project-123", key: "key", value: "value"} expectedStatusError: "status.platformStatus.gcp.resourceTags: Invalid value: \"array\": resourceTags are immutable and may only be configured during installation" - - name: Should not be able to modify the cluster hosted dns value for GCP Platform Status + - name: dnsType should default to `PlatformDefault` when not specified initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure - spec: {} + spec: + platformSpec: + gcp: {} + type: GCP status: - controlPlaneTopology: "HighlyAvailable" - infrastructureTopology: "HighlyAvailable" + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable + platform: GCP + platformStatus: + gcp: {} + type: GCP + updated: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: + platformSpec: + type: GCP + gcp: {} + status: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable platform: GCP platformStatus: + gcp: {} + type: GCP + expected: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: + platformSpec: type: GCP + gcp: {} + status: + controlPlaneTopology: HighlyAvailable + cpuPartitioning: None + infrastructureTopology: HighlyAvailable + platform: GCP + platformStatus: gcp: - clusterHostedDNS: "Enabled" + cloudLoadBalancerConfig: + dnsType: PlatformDefault + type: GCP + - name: should be able to set dnsType to non-default value of `ClusterHosted` + initial: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: + platformSpec: + gcp: {} + type: GCP updated: | apiVersion: config.openshift.io/v1 kind: Infrastructure - spec: {} + spec: + platformSpec: + type: GCP + gcp: {} status: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable platform: GCP platformStatus: + gcp: + cloudLoadBalancerConfig: + dnsType: ClusterHosted + type: GCP + expected: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: + platformSpec: type: GCP + gcp: {} + status: + controlPlaneTopology: HighlyAvailable + cpuPartitioning: None + infrastructureTopology: HighlyAvailable + platform: GCP + platformStatus: gcp: - clusterHostedDNS: "Disabled" - expectedStatusError: "status.platformStatus.gcp.clusterHostedDNS: Invalid value: \"string\": clusterHostedDNS is immutable and may only be configured during installation" - - name: Should not be able to remove GCP cluster hosted DNS from platformStatus.gcp + cloudLoadBalancerConfig: + dnsType: ClusterHosted + type: GCP + - name: Should not allow changing the immutable dnsType field initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure - spec: {} + spec: + platformSpec: + gcp: {} + type: GCP status: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable platform: GCP platformStatus: + gcp: + cloudLoadBalancerConfig: + dnsType: ClusterHosted + clusterHosted: + apiIntLoadBalancerIPs: + - 10.10.10.20 type: GCP + updated: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: + platformSpec: + type: GCP + gcp: {} + status: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable + platform: GCP + platformStatus: gcp: - clusterHostedDNS: "Enabled" + cloudLoadBalancerConfig: + dnsType: PlatformDefault + type: GCP + expectedStatusError: "status.platformStatus.gcp.cloudLoadBalancerConfig.dnsType: Invalid value: \"string\": dnsType is immutable" + - name: Should not accept non-IP address values for Load Balancer IPs + initial: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: + platformSpec: + gcp: {} + type: GCP + status: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable + platform: GCP + platformStatus: + gcp: + cloudLoadBalancerConfig: + dnsType: ClusterHosted + clusterHosted: + apiIntLoadBalancerIPs: + - 10.10.10.20 + type: GCP updated: | apiVersion: config.openshift.io/v1 kind: Infrastructure - spec: {} + spec: + platformSpec: + type: GCP + gcp: {} + status: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable + platform: GCP + platformStatus: + gcp: + cloudLoadBalancerConfig: + dnsType: ClusterHosted + clusterHosted: + apiIntLoadBalancerIPs: + - 10.10.10.20 + - not-an-ip-address + type: GCP + expectedStatusError: "status.platformStatus.gcp.cloudLoadBalancerConfig.clusterHosted.apiIntLoadBalancerIPs[1]: Invalid value: \"not-an-ip-address\": status.platformStatus.gcp.cloudLoadBalancerConfig.clusterHosted.apiIntLoadBalancerIPs[1] in body should match '(^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*)'" + - name: Should not accept update when `clusterHosted` is specified with DNSType `PlatformDefault` + initial: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: + platformSpec: + gcp: {} + type: GCP status: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable platform: GCP platformStatus: + gcp: {} + type: GCP + updated: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: + platformSpec: type: GCP gcp: {} - expectedStatusError: "status.platformStatus.gcp.clusterHostedDNS: Invalid value: \"string\": clusterHostedDNS is immutable and may only be configured during installation" + status: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable + platform: GCP + platformStatus: + gcp: + cloudLoadBalancerConfig: + dnsType: PlatformDefault + clusterHosted: + apiIntLoadBalancerIPs: + - 10.10.10.20 + type: GCP + expectedStatusError: "status.platformStatus.gcp.cloudLoadBalancerConfig: Invalid value: \"object\": clusterHosted is permitted only when dnsType is ClusterHosted" + - name: Should not accept duplicate IP addresses for any of the Load Balancer IPs + initial: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: + platformSpec: + gcp: {} + type: GCP + updated: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: + platformSpec: + type: GCP + gcp: {} + status: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable + platform: GCP + platformStatus: + gcp: + cloudLoadBalancerConfig: + dnsType: ClusterHosted + clusterHosted: + apiIntLoadBalancerIPs: + - 10.10.10.20 + - 10.10.20.20 + - 10.10.10.20 + type: GCP + expectedStatusError: "status.platformStatus.gcp.cloudLoadBalancerConfig.clusterHosted.apiIntLoadBalancerIPs[2]: Duplicate value: \"10.10.10.20\"" diff --git a/vendor/github.com/openshift/api/config/v1/types_authentication.go b/vendor/github.com/openshift/api/config/v1/types_authentication.go index b9d1e0c52a4f..62c9e7f5ae86 100644 --- a/vendor/github.com/openshift/api/config/v1/types_authentication.go +++ b/vendor/github.com/openshift/api/config/v1/types_authentication.go @@ -130,6 +130,8 @@ type AuthenticationList struct { Items []Authentication `json:"items"` } +// +openshift:validation:FeatureSetAwareEnum:featureSet=Default,enum="";None;IntegratedOAuth +// +openshift:validation:FeatureSetAwareEnum:featureSet=CustomNoUpgrade;TechPreviewNoUpgrade,enum="";None;IntegratedOAuth;OIDC type AuthenticationType string const ( @@ -238,7 +240,8 @@ type TokenIssuer struct { // // +listType=set // +kubebuilder:validation:Required - // +kubebuilder:validation:MaxItems=1 + // +kubebuilder:validation:MinItems=1 + // +kubebuilder:validation:MaxItems=10 // +required Audiences []TokenAudience `json:"audiences"` diff --git a/vendor/github.com/openshift/api/config/v1/types_cluster_version.go b/vendor/github.com/openshift/api/config/v1/types_cluster_version.go index 202972ebf84e..0ceedbab45de 100644 --- a/vendor/github.com/openshift/api/config/v1/types_cluster_version.go +++ b/vendor/github.com/openshift/api/config/v1/types_cluster_version.go @@ -88,9 +88,32 @@ type ClusterVersionSpec struct { // +optional Capabilities *ClusterVersionCapabilitiesSpec `json:"capabilities,omitempty"` + // signatureStores contains the upstream URIs to verify release signatures and optional + // reference to a config map by name containing the PEM-encoded CA bundle. + // + // By default, CVO will use existing signature stores if this property is empty. + // The CVO will check the release signatures in the local ConfigMaps first. It will search for a valid signature + // in these stores in parallel only when local ConfigMaps did not include a valid signature. + // Validation will fail if none of the signature stores reply with valid signature before timeout. + // Setting signatureStores will replace the default signature stores with custom signature stores. + // Default stores can be used with custom signature stores by adding them manually. + // + // A maximum of 32 signature stores may be configured. + // +kubebuilder:validation:MaxItems=32 + // +openshift:enable:FeatureSets=CustomNoUpgrade;TechPreviewNoUpgrade + // +listType=map + // +listMapKey=url + // +optional + SignatureStores []SignatureStore `json:"signatureStores"` + // overrides is list of overides for components that are managed by // cluster version operator. Marking a component unmanaged will prevent // the operator from creating or updating the object. + // +listType=map + // +listMapKey=kind + // +listMapKey=group + // +listMapKey=namespace + // +listMapKey=name // +optional Overrides []ComponentOverride `json:"overrides,omitempty"` } @@ -116,6 +139,7 @@ type ClusterVersionStatus struct { // Completed if the rollout completed - if an update was failing or halfway // applied the state will be Partial. Only a limited amount of update history // is preserved. + // +listType=atomic // +optional History []UpdateHistory `json:"history,omitempty"` @@ -143,8 +167,12 @@ type ClusterVersionStatus struct { // by a temporary or permanent error. Conditions are only valid for the // current desiredUpdate when metadata.generation is equal to // status.generation. + // +listType=map + // +listMapKey=type + // +patchMergeKey=type + // +patchStrategy=merge // +optional - Conditions []ClusterOperatorStatusCondition `json:"conditions,omitempty"` + Conditions []ClusterOperatorStatusCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"` // availableUpdates contains updates recommended for this // cluster. Updates which appear in conditionalUpdates but not in @@ -153,6 +181,7 @@ type ClusterVersionStatus struct { // is unavailable, or if an invalid channel has been specified. // +nullable // +kubebuilder:validation:Required + // +listType=atomic // +required AvailableUpdates []Release `json:"availableUpdates"` @@ -626,6 +655,7 @@ type Release struct { // channels is the set of Cincinnati channels to which the release // currently belongs. + // +listType=set // +optional Channels []string `json:"channels,omitempty"` } @@ -756,3 +786,26 @@ type ClusterVersionList struct { Items []ClusterVersion `json:"items"` } + +// SignatureStore represents the URL of custom Signature Store +type SignatureStore struct { + + // url contains the upstream custom signature store URL. + // url should be a valid absolute http/https URI of an upstream signature store as per rfc1738. + // This must be provided and cannot be empty. + // + // +kubebuilder:validation:Type=string + // +kubebuilder:validation:XValidation:rule="isURL(self)",message="url must be a valid absolute URL" + // +kubebuilder:validation:Required + URL string `json:"url"` + + // ca is an optional reference to a config map by name containing the PEM-encoded CA bundle. + // It is used as a trust anchor to validate the TLS certificate presented by the remote server. + // The key "ca.crt" is used to locate the data. + // If specified and the config map or expected key is not found, the signature store is not honored. + // If the specified ca data is not valid, the signature store is not honored. + // If empty, we fall back to the CA configured via Proxy, which is appended to the default system roots. + // The namespace for this config map is openshift-config. + // +optional + CA ConfigMapNameReference `json:"ca"` +} diff --git a/vendor/github.com/openshift/api/config/v1/types_feature.go b/vendor/github.com/openshift/api/config/v1/types_feature.go index a2f0623a0bd6..462a246960d8 100644 --- a/vendor/github.com/openshift/api/config/v1/types_feature.go +++ b/vendor/github.com/openshift/api/config/v1/types_feature.go @@ -159,8 +159,10 @@ type FeatureGateEnabledDisabled struct { var FeatureSets = map[FeatureSet]*FeatureGateEnabledDisabled{ Default: defaultFeatures, CustomNoUpgrade: { - Enabled: []FeatureGateDescription{}, - Disabled: []FeatureGateDescription{}, + Enabled: []FeatureGateDescription{}, + Disabled: []FeatureGateDescription{ + disableKubeletCloudCredentialProviders, // We do not currently ship the correct config to use the external credentials provider. + }, }, TechPreviewNoUpgrade: newDefaultFeatures(). with(validatingAdmissionPolicy). @@ -186,9 +188,12 @@ var FeatureSets = map[FeatureSet]*FeatureGateEnabledDisabled{ with(metricsServer). with(installAlternateInfrastructureAWS). without(clusterAPIInstall). - with(sdnLiveMigration). with(mixedCPUsAllocation). with(managedBootImages). + without(disableKubeletCloudCredentialProviders). + with(onClusterBuild). + with(signatureStores). + with(openShiftPodSecurityAdmission). toFeatures(defaultFeatures), LatencySensitive: newDefaultFeatures(). toFeatures(defaultFeatures), @@ -196,7 +201,6 @@ var FeatureSets = map[FeatureSet]*FeatureGateEnabledDisabled{ var defaultFeatures = &FeatureGateEnabledDisabled{ Enabled: []FeatureGateDescription{ - openShiftPodSecurityAdmission, alibabaPlatform, // This is a bug, it should be TechPreviewNoUpgrade. This must be downgraded before 4.14 is shipped. azureWorkloadIdentity, cloudDualStackNodeIPs, @@ -206,8 +210,11 @@ var defaultFeatures = &FeatureGateEnabledDisabled{ externalCloudProviderExternal, privateHostedZoneAWS, buildCSIVolumes, + sdnLiveMigration, + }, + Disabled: []FeatureGateDescription{ + disableKubeletCloudCredentialProviders, // We do not currently ship the correct config to use the external credentials provider. }, - Disabled: []FeatureGateDescription{}, } type featureSetBuilder struct { diff --git a/vendor/github.com/openshift/api/config/v1/types_infrastructure.go b/vendor/github.com/openshift/api/config/v1/types_infrastructure.go index e5a059c13cb4..4bb9327961c6 100644 --- a/vendor/github.com/openshift/api/config/v1/types_infrastructure.go +++ b/vendor/github.com/openshift/api/config/v1/types_infrastructure.go @@ -231,22 +231,22 @@ const ( IBMCloudProviderTypeUPI IBMCloudProviderType = "UPI" ) -// ClusterHostedDNS indicates whether the cluster DNS is hosted by the cluster or Core DNS . -type ClusterHostedDNS string +// DNSType indicates whether the cluster DNS is hosted by the cluster or Core DNS . +type DNSType string const ( - // EnabledClusterHostedDNS indicates that a DNS solution other than the default provided by the + // ClusterHosted indicates that a DNS solution other than the default provided by the // cloud platform is in use. In this mode, the cluster hosts a DNS solution during installation and the // user is expected to provide their own DNS solution post-install. - // When "Enabled", the cluster will continue to use the default Load Balancers provided by the cloud - // platform. - EnabledClusterHostedDNS ClusterHostedDNS = "Enabled" + // When the DNS solution is `ClusterHosted`, the cluster will continue to use the + // default Load Balancers provided by the cloud platform. + ClusterHostedDNSType DNSType = "ClusterHosted" - // DisabledClusterHostedDNS indicates that the cluster is using the default DNS solution for the + // PlatformDefault indicates that the cluster is using the default DNS solution for the // cloud platform. OpenShift is responsible for all the LB and DNS configuration needed for the // cluster to be functional with no intervention from the user. To accomplish this, OpenShift // configures the default LB and DNS solutions provided by the underlying cloud. - DisabledClusterHostedDNS ClusterHostedDNS = "Disabled" + PlatformDefaultDNSType DNSType = "PlatformDefault" ) // ExternalPlatformSpec holds the desired state for the generic External infrastructure provider. @@ -475,6 +475,7 @@ type AWSPlatformSpec struct { // serviceEndpoints list contains custom endpoints which will override default // service endpoint of AWS Services. // There must be only one ServiceEndpoint for a service. + // +listType=atomic // +optional ServiceEndpoints []AWSServiceEndpoint `json:"serviceEndpoints,omitempty"` } @@ -487,6 +488,7 @@ type AWSPlatformStatus struct { // ServiceEndpoints list contains custom endpoints which will override default // service endpoint of AWS Services. // There must be only one ServiceEndpoint for a service. + // +listType=atomic // +optional ServiceEndpoints []AWSServiceEndpoint `json:"serviceEndpoints,omitempty"` @@ -495,6 +497,7 @@ type AWSPlatformStatus struct { // AWS supports a maximum of 50 tags per resource. OpenShift reserves 25 tags for its use, leaving 25 tags // available for the user. // +kubebuilder:validation:MaxItems=25 + // +listType=atomic // +optional ResourceTags []AWSResourceTag `json:"resourceTags,omitempty"` } @@ -550,6 +553,7 @@ type AzurePlatformStatus struct { // may be applied. OpenShift reserves 5 tags for internal use, allowing 10 tags for user configuration. // +kubebuilder:validation:MaxItems=10 // +kubebuilder:validation:XValidation:rule="self.all(x, x in oldSelf) && oldSelf.all(x, x in self)",message="resourceTags are immutable and may only be configured during installation" + // +listType=atomic // +optional ResourceTags []AzureResourceTag `json:"resourceTags,omitempty"` } @@ -631,23 +635,24 @@ type GCPPlatformStatus struct { // +openshift:enable:FeatureSets=CustomNoUpgrade;TechPreviewNoUpgrade ResourceTags []GCPResourceTag `json:"resourceTags,omitempty"` - // clusterHostedDNS indicates the type of DNS solution in use within the cluster. Its default value of - // "Disabled" indicates that the cluster's DNS is the default provided by the cloud platform. It can be - // "Enabled" during install to bypass the configuration of the cloud default DNS. When "Enabled", the - // cluster needs to provide a self-hosted DNS solution for the cluster's installation to succeed. - // The cluster's use of the cloud's Load Balancers is unaffected by this setting. - // The value is immutable after it has been set at install time. - // Currently, there is no way for the customer to add additional DNS entries into the cluster hosted DNS. - // Enabling this functionality allows the user to start their own DNS solution outside the cluster after - // installation is complete. The customer would be responsible for configuring this custom DNS solution, - // and it can be run in addition to the in-cluster DNS solution. - // +kubebuilder:default:="Disabled" - // +default="Disabled" - // +kubebuilder:validation:Enum="Enabled";"Disabled" - // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="clusterHostedDNS is immutable and may only be configured during installation" - // +optional + // This field was introduced and removed under tech preview. + // To avoid conflicts with serialisation, this field name may never be used again. + // Tombstone the field as a reminder. + // ClusterHostedDNS ClusterHostedDNS `json:"clusterHostedDNS,omitempty"` + + // cloudLoadBalancerConfig is a union that contains the IP addresses of API, + // API-Int and Ingress Load Balancers created on the cloud platform. These + // values would not be populated on on-prem platforms. These Load Balancer + // IPs are used to configure the in-cluster DNS instances for API, API-Int + // and Ingress services. `dnsType` is expected to be set to `ClusterHosted` + // when these Load Balancer IP addresses are populated and used. + // + // +default={"dnsType": "PlatformDefault"} + // +kubebuilder:default={"dnsType": "PlatformDefault"} // +openshift:enable:FeatureSets=CustomNoUpgrade;TechPreviewNoUpgrade - ClusterHostedDNS ClusterHostedDNS `json:"clusterHostedDNS,omitempty"` + // +optional + // +nullable + CloudLoadBalancerConfig *CloudLoadBalancerConfig `json:"cloudLoadBalancerConfig,omitempty"` } // GCPResourceLabel is a label to apply to GCP resources created for the cluster. @@ -706,6 +711,77 @@ type GCPResourceTag struct { Value string `json:"value"` } +// CloudLoadBalancerConfig contains an union discriminator indicating the type of DNS +// solution in use within the cluster. When the DNSType is `ClusterHosted`, the cloud's +// Load Balancer configuration needs to be provided so that the DNS solution hosted +// within the cluster can be configured with those values. +// +kubebuilder:validation:XValidation:rule="has(self.dnsType) && self.dnsType != 'ClusterHosted' ? !has(self.clusterHosted) : true",message="clusterHosted is permitted only when dnsType is ClusterHosted" +// +union +type CloudLoadBalancerConfig struct { + // dnsType indicates the type of DNS solution in use within the cluster. Its default value of + // `PlatformDefault` indicates that the cluster's DNS is the default provided by the cloud platform. + // It can be set to `ClusterHosted` to bypass the configuration of the cloud default DNS. In this mode, + // the cluster needs to provide a self-hosted DNS solution for the cluster's installation to succeed. + // The cluster's use of the cloud's Load Balancers is unaffected by this setting. + // The value is immutable after it has been set at install time. + // Currently, there is no way for the customer to add additional DNS entries into the cluster hosted DNS. + // Enabling this functionality allows the user to start their own DNS solution outside the cluster after + // installation is complete. The customer would be responsible for configuring this custom DNS solution, + // and it can be run in addition to the in-cluster DNS solution. + // +default="PlatformDefault" + // +kubebuilder:default:="PlatformDefault" + // +kubebuilder:validation:Enum="ClusterHosted";"PlatformDefault" + // +kubebuilder:validation:XValidation:rule="oldSelf == '' || self == oldSelf",message="dnsType is immutable" + // +optional + // +unionDiscriminator + DNSType DNSType `json:"dnsType,omitempty"` + + // clusterHosted holds the IP addresses of API, API-Int and Ingress Load + // Balancers on Cloud Platforms. The DNS solution hosted within the cluster + // use these IP addresses to provide resolution for API, API-Int and Ingress + // services. + // +optional + // +unionMember,optional + ClusterHosted *CloudLoadBalancerIPs `json:"clusterHosted,omitempty"` +} + +// CloudLoadBalancerIPs contains the Load Balancer IPs for the cloud's API, +// API-Int and Ingress Load balancers. They will be populated as soon as the +// respective Load Balancers have been configured. These values are utilized +// to configure the DNS solution hosted within the cluster. +type CloudLoadBalancerIPs struct { + // apiIntLoadBalancerIPs holds Load Balancer IPs for the internal API service. + // These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. + // Entries in the apiIntLoadBalancerIPs must be unique. + // A maximum of 16 IP addresses are permitted. + // +kubebuilder:validation:Format=ip + // +listType=set + // +kubebuilder:validation:MaxItems=16 + // +optional + APIIntLoadBalancerIPs []IP `json:"apiIntLoadBalancerIPs,omitempty"` + + // apiLoadBalancerIPs holds Load Balancer IPs for the API service. + // These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. + // Could be empty for private clusters. + // Entries in the apiLoadBalancerIPs must be unique. + // A maximum of 16 IP addresses are permitted. + // +kubebuilder:validation:Format=ip + // +listType=set + // +kubebuilder:validation:MaxItems=16 + // +optional + APILoadBalancerIPs []IP `json:"apiLoadBalancerIPs,omitempty"` + + // ingressLoadBalancerIPs holds IPs for Ingress Load Balancers. + // These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. + // Entries in the ingressLoadBalancerIPs must be unique. + // A maximum of 16 IP addresses are permitted. + // +kubebuilder:validation:Format=ip + // +listType=set + // +kubebuilder:validation:MaxItems=16 + // +optional + IngressLoadBalancerIPs []IP `json:"ingressLoadBalancerIPs,omitempty"` +} + // BareMetalPlatformLoadBalancer defines the load balancer used by the cluster on BareMetal platform. // +union type BareMetalPlatformLoadBalancer struct { @@ -751,6 +827,7 @@ type BareMetalPlatformStatus struct { // // +kubebuilder:validation:Format=ip // +kubebuilder:validation:MaxItems=2 + // +listType=set APIServerInternalIPs []string `json:"apiServerInternalIPs"` // ingressIP is an external IP which routes to the default ingress controller. @@ -766,6 +843,7 @@ type BareMetalPlatformStatus struct { // // +kubebuilder:validation:Format=ip // +kubebuilder:validation:MaxItems=2 + // +listType=set IngressIPs []string `json:"ingressIPs"` // nodeDNSIP is the IP address for the internal DNS used by the @@ -827,6 +905,7 @@ type OpenStackPlatformStatus struct { // // +kubebuilder:validation:Format=ip // +kubebuilder:validation:MaxItems=2 + // +listType=set APIServerInternalIPs []string `json:"apiServerInternalIPs"` // cloudName is the name of the desired OpenStack cloud in the @@ -846,6 +925,7 @@ type OpenStackPlatformStatus struct { // // +kubebuilder:validation:Format=ip // +kubebuilder:validation:MaxItems=2 + // +listType=set IngressIPs []string `json:"ingressIPs"` // nodeDNSIP is the IP address for the internal DNS used by the @@ -906,6 +986,7 @@ type OvirtPlatformStatus struct { // // +kubebuilder:validation:Format=ip // +kubebuilder:validation:MaxItems=2 + // +listType=set APIServerInternalIPs []string `json:"apiServerInternalIPs"` // ingressIP is an external IP which routes to the default ingress controller. @@ -921,6 +1002,7 @@ type OvirtPlatformStatus struct { // // +kubebuilder:validation:Format=ip // +kubebuilder:validation:MaxItems=2 + // +listType=set IngressIPs []string `json:"ingressIPs"` // deprecated: as of 4.6, this field is no longer set or honored. It will be removed in a future release. @@ -1021,6 +1103,7 @@ type VSpherePlatformTopology struct { // +kubebuilder:validation:Required // +kubebuilder:validation:MaxItems=1 // +kubebuilder:validation:MinItems=1 + // +listType=atomic Networks []string `json:"networks"` // datastore is the absolute path of the datastore in which the @@ -1094,6 +1177,7 @@ type VSpherePlatformVCenterSpec struct { // a topology. // +kubebuilder:validation:Required // +kubebuilder:validation:MinItems=1 + // +listType=set Datacenters []string `json:"datacenters"` } @@ -1107,6 +1191,7 @@ type VSpherePlatformNodeNetworkingSpec struct { // that will be used in respective status.addresses fields. // --- // + Validation is applied via a patch, we validate the format as cidr + // +listType=set // +optional NetworkSubnetCIDR []string `json:"networkSubnetCidr,omitempty"` @@ -1123,6 +1208,7 @@ type VSpherePlatformNodeNetworkingSpec struct { // the IP address from the VirtualMachine's VM for use in the status.addresses fields. // --- // + Validation is applied via a patch, we validate the format as cidr + // +listType=atomic // +optional ExcludeNetworkSubnetCIDR []string `json:"excludeNetworkSubnetCidr,omitempty"` } @@ -1148,11 +1234,14 @@ type VSpherePlatformSpec struct { // + in openshift-config. // +kubebuilder:validation:MaxItems=1 // +kubebuilder:validation:MinItems=0 + // +listType=atomic // +optional VCenters []VSpherePlatformVCenterSpec `json:"vcenters,omitempty"` // failureDomains contains the definition of region, zone and the vCenter topology. // If this is omitted failure domains (regions and zones) will not be used. + // +listType=map + // +listMapKey=name // +optional FailureDomains []VSpherePlatformFailureDomainSpec `json:"failureDomains,omitempty"` @@ -1183,6 +1272,7 @@ type VSpherePlatformStatus struct { // // +kubebuilder:validation:Format=ip // +kubebuilder:validation:MaxItems=2 + // +listType=set APIServerInternalIPs []string `json:"apiServerInternalIPs"` // ingressIP is an external IP which routes to the default ingress controller. @@ -1198,6 +1288,7 @@ type VSpherePlatformStatus struct { // // +kubebuilder:validation:Format=ip // +kubebuilder:validation:MaxItems=2 + // +listType=set IngressIPs []string `json:"ingressIPs"` // nodeDNSIP is the IP address for the internal DNS used by the @@ -1364,6 +1455,8 @@ type PowerVSPlatformStatus struct { // serviceEndpoints is a list of custom endpoints which will override the default // service endpoints of a Power VS service. + // +listType=map + // +listMapKey=name // +optional ServiceEndpoints []PowerVSServiceEndpoint `json:"serviceEndpoints,omitempty"` @@ -1574,6 +1667,7 @@ type NutanixPlatformStatus struct { // // +kubebuilder:validation:Format=ip // +kubebuilder:validation:MaxItems=2 + // +listType=set APIServerInternalIPs []string `json:"apiServerInternalIPs"` // ingressIP is an external IP which routes to the default ingress controller. @@ -1589,6 +1683,7 @@ type NutanixPlatformStatus struct { // // +kubebuilder:validation:Format=ip // +kubebuilder:validation:MaxItems=2 + // +listType=set IngressIPs []string `json:"ingressIPs"` // loadBalancer defines how the load balancer used by the cluster is configured. @@ -1614,3 +1709,11 @@ type InfrastructureList struct { Items []Infrastructure `json:"items"` } + +// IP is an IP address (for example, "10.0.0.0" or "fd00::"). +// +kubebuilder:validation:Pattern=`(^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*)` +// + --- +// + The regex for the IPv4 and IPv6 address was taken from +// + https://blog.markhatton.co.uk/2011/03/15/regular-expressions-for-ip-addresses-cidr-ranges-and-hostnames/ +// + The resulting regex is an OR of both regexes. +type IP string diff --git a/vendor/github.com/openshift/api/config/v1/types_network.go b/vendor/github.com/openshift/api/config/v1/types_network.go index 3d345b2d600b..794f3db7b71c 100644 --- a/vendor/github.com/openshift/api/config/v1/types_network.go +++ b/vendor/github.com/openshift/api/config/v1/types_network.go @@ -95,7 +95,6 @@ type NetworkStatus struct { // +patchStrategy=merge // +listType=map // +listMapKey=type - // +openshift:enable:FeatureSets=CustomNoUpgrade;TechPreviewNoUpgrade Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"` } diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go b/vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go index 381a1642cc5f..5997ff74327a 100644 --- a/vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go @@ -905,6 +905,58 @@ func (in *CloudControllerManagerStatus) DeepCopy() *CloudControllerManagerStatus return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CloudLoadBalancerConfig) DeepCopyInto(out *CloudLoadBalancerConfig) { + *out = *in + if in.ClusterHosted != nil { + in, out := &in.ClusterHosted, &out.ClusterHosted + *out = new(CloudLoadBalancerIPs) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CloudLoadBalancerConfig. +func (in *CloudLoadBalancerConfig) DeepCopy() *CloudLoadBalancerConfig { + if in == nil { + return nil + } + out := new(CloudLoadBalancerConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CloudLoadBalancerIPs) DeepCopyInto(out *CloudLoadBalancerIPs) { + *out = *in + if in.APIIntLoadBalancerIPs != nil { + in, out := &in.APIIntLoadBalancerIPs, &out.APIIntLoadBalancerIPs + *out = make([]IP, len(*in)) + copy(*out, *in) + } + if in.APILoadBalancerIPs != nil { + in, out := &in.APILoadBalancerIPs, &out.APILoadBalancerIPs + *out = make([]IP, len(*in)) + copy(*out, *in) + } + if in.IngressLoadBalancerIPs != nil { + in, out := &in.IngressLoadBalancerIPs, &out.IngressLoadBalancerIPs + *out = make([]IP, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CloudLoadBalancerIPs. +func (in *CloudLoadBalancerIPs) DeepCopy() *CloudLoadBalancerIPs { + if in == nil { + return nil + } + out := new(CloudLoadBalancerIPs) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClusterCondition) DeepCopyInto(out *ClusterCondition) { *out = *in @@ -1191,6 +1243,11 @@ func (in *ClusterVersionSpec) DeepCopyInto(out *ClusterVersionSpec) { *out = new(ClusterVersionCapabilitiesSpec) (*in).DeepCopyInto(*out) } + if in.SignatureStores != nil { + in, out := &in.SignatureStores, &out.SignatureStores + *out = make([]SignatureStore, len(*in)) + copy(*out, *in) + } if in.Overrides != nil { in, out := &in.Overrides, &out.Overrides *out = make([]ComponentOverride, len(*in)) @@ -2161,6 +2218,11 @@ func (in *GCPPlatformStatus) DeepCopyInto(out *GCPPlatformStatus) { *out = make([]GCPResourceTag, len(*in)) copy(*out, *in) } + if in.CloudLoadBalancerConfig != nil { + in, out := &in.CloudLoadBalancerConfig, &out.CloudLoadBalancerConfig + *out = new(CloudLoadBalancerConfig) + (*in).DeepCopyInto(*out) + } return } @@ -5252,6 +5314,23 @@ func (in *ServingInfo) DeepCopy() *ServingInfo { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SignatureStore) DeepCopyInto(out *SignatureStore) { + *out = *in + out.CA = in.CA + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SignatureStore. +func (in *SignatureStore) DeepCopy() *SignatureStore { + if in == nil { + return nil + } + out := new(SignatureStore) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *StringSource) DeepCopyInto(out *StringSource) { *out = *in diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go b/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go index 215db197eb0f..98e8ac8db67b 100644 --- a/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go @@ -696,13 +696,14 @@ func (ClusterVersionList) SwaggerDoc() map[string]string { } var map_ClusterVersionSpec = map[string]string{ - "": "ClusterVersionSpec is the desired version state of the cluster. It includes the version the cluster should be at, how the cluster is identified, and where the cluster should look for version updates.", - "clusterID": "clusterID uniquely identifies this cluster. This is expected to be an RFC4122 UUID value (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx in hexadecimal values). This is a required field.", - "desiredUpdate": "desiredUpdate is an optional field that indicates the desired value of the cluster version. Setting this value will trigger an upgrade (if the current version does not match the desired version). The set of recommended update values is listed as part of available updates in status, and setting values outside that range may cause the upgrade to fail.\n\nSome of the fields are inter-related with restrictions and meanings described here. 1. image is specified, version is specified, architecture is specified. API validation error. 2. image is specified, version is specified, architecture is not specified. You should not do this. version is silently ignored and image is used. 3. image is specified, version is not specified, architecture is specified. API validation error. 4. image is specified, version is not specified, architecture is not specified. image is used. 5. image is not specified, version is specified, architecture is specified. version and desired architecture are used to select an image. 6. image is not specified, version is specified, architecture is not specified. version and current architecture are used to select an image. 7. image is not specified, version is not specified, architecture is specified. API validation error. 8. image is not specified, version is not specified, architecture is not specified. API validation error.\n\nIf an upgrade fails the operator will halt and report status about the failing component. Setting the desired update value back to the previous version will cause a rollback to be attempted. Not all rollbacks will succeed.", - "upstream": "upstream may be used to specify the preferred update server. By default it will use the appropriate update server for the cluster and region.", - "channel": "channel is an identifier for explicitly requesting that a non-default set of updates be applied to this cluster. The default channel will be contain stable updates that are appropriate for production clusters.", - "capabilities": "capabilities configures the installation of optional, core cluster components. A null value here is identical to an empty object; see the child properties for default semantics.", - "overrides": "overrides is list of overides for components that are managed by cluster version operator. Marking a component unmanaged will prevent the operator from creating or updating the object.", + "": "ClusterVersionSpec is the desired version state of the cluster. It includes the version the cluster should be at, how the cluster is identified, and where the cluster should look for version updates.", + "clusterID": "clusterID uniquely identifies this cluster. This is expected to be an RFC4122 UUID value (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx in hexadecimal values). This is a required field.", + "desiredUpdate": "desiredUpdate is an optional field that indicates the desired value of the cluster version. Setting this value will trigger an upgrade (if the current version does not match the desired version). The set of recommended update values is listed as part of available updates in status, and setting values outside that range may cause the upgrade to fail.\n\nSome of the fields are inter-related with restrictions and meanings described here. 1. image is specified, version is specified, architecture is specified. API validation error. 2. image is specified, version is specified, architecture is not specified. You should not do this. version is silently ignored and image is used. 3. image is specified, version is not specified, architecture is specified. API validation error. 4. image is specified, version is not specified, architecture is not specified. image is used. 5. image is not specified, version is specified, architecture is specified. version and desired architecture are used to select an image. 6. image is not specified, version is specified, architecture is not specified. version and current architecture are used to select an image. 7. image is not specified, version is not specified, architecture is specified. API validation error. 8. image is not specified, version is not specified, architecture is not specified. API validation error.\n\nIf an upgrade fails the operator will halt and report status about the failing component. Setting the desired update value back to the previous version will cause a rollback to be attempted. Not all rollbacks will succeed.", + "upstream": "upstream may be used to specify the preferred update server. By default it will use the appropriate update server for the cluster and region.", + "channel": "channel is an identifier for explicitly requesting that a non-default set of updates be applied to this cluster. The default channel will be contain stable updates that are appropriate for production clusters.", + "capabilities": "capabilities configures the installation of optional, core cluster components. A null value here is identical to an empty object; see the child properties for default semantics.", + "signatureStores": "signatureStores contains the upstream URIs to verify release signatures and optional reference to a config map by name containing the PEM-encoded CA bundle.\n\nBy default, CVO will use existing signature stores if this property is empty. The CVO will check the release signatures in the local ConfigMaps first. It will search for a valid signature in these stores in parallel only when local ConfigMaps did not include a valid signature. Validation will fail if none of the signature stores reply with valid signature before timeout. Setting signatureStores will replace the default signature stores with custom signature stores. Default stores can be used with custom signature stores by adding them manually.\n\nA maximum of 32 signature stores may be configured.", + "overrides": "overrides is list of overides for components that are managed by cluster version operator. Marking a component unmanaged will prevent the operator from creating or updating the object.", } func (ClusterVersionSpec) SwaggerDoc() map[string]string { @@ -782,6 +783,16 @@ func (Release) SwaggerDoc() map[string]string { return map_Release } +var map_SignatureStore = map[string]string{ + "": "SignatureStore represents the URL of custom Signature Store", + "url": "url contains the upstream custom signature store URL. url should be a valid absolute http/https URI of an upstream signature store as per rfc1738. This must be provided and cannot be empty.", + "ca": "ca is an optional reference to a config map by name containing the PEM-encoded CA bundle. It is used as a trust anchor to validate the TLS certificate presented by the remote server. The key \"ca.crt\" is used to locate the data. If specified and the config map or expected key is not found, the signature store is not honored. If the specified ca data is not valid, the signature store is not honored. If empty, we fall back to the CA configured via Proxy, which is appended to the default system roots. The namespace for this config map is openshift-config.", +} + +func (SignatureStore) SwaggerDoc() map[string]string { + return map_SignatureStore +} + var map_Update = map[string]string{ "": "Update represents an administrator update request.", "architecture": "architecture is an optional field that indicates the desired value of the cluster architecture. In this context cluster architecture means either a single architecture or a multi architecture. architecture can only be set to Multi thereby only allowing updates from single to multi architecture. If architecture is set, image cannot be set and version must be set. Valid values are 'Multi' and empty.", @@ -1301,6 +1312,27 @@ func (CloudControllerManagerStatus) SwaggerDoc() map[string]string { return map_CloudControllerManagerStatus } +var map_CloudLoadBalancerConfig = map[string]string{ + "": "CloudLoadBalancerConfig contains an union discriminator indicating the type of DNS solution in use within the cluster. When the DNSType is `ClusterHosted`, the cloud's Load Balancer configuration needs to be provided so that the DNS solution hosted within the cluster can be configured with those values.", + "dnsType": "dnsType indicates the type of DNS solution in use within the cluster. Its default value of `PlatformDefault` indicates that the cluster's DNS is the default provided by the cloud platform. It can be set to `ClusterHosted` to bypass the configuration of the cloud default DNS. In this mode, the cluster needs to provide a self-hosted DNS solution for the cluster's installation to succeed. The cluster's use of the cloud's Load Balancers is unaffected by this setting. The value is immutable after it has been set at install time. Currently, there is no way for the customer to add additional DNS entries into the cluster hosted DNS. Enabling this functionality allows the user to start their own DNS solution outside the cluster after installation is complete. The customer would be responsible for configuring this custom DNS solution, and it can be run in addition to the in-cluster DNS solution.", + "clusterHosted": "clusterHosted holds the IP addresses of API, API-Int and Ingress Load Balancers on Cloud Platforms. The DNS solution hosted within the cluster use these IP addresses to provide resolution for API, API-Int and Ingress services.", +} + +func (CloudLoadBalancerConfig) SwaggerDoc() map[string]string { + return map_CloudLoadBalancerConfig +} + +var map_CloudLoadBalancerIPs = map[string]string{ + "": "CloudLoadBalancerIPs contains the Load Balancer IPs for the cloud's API, API-Int and Ingress Load balancers. They will be populated as soon as the respective Load Balancers have been configured. These values are utilized to configure the DNS solution hosted within the cluster.", + "apiIntLoadBalancerIPs": "apiIntLoadBalancerIPs holds Load Balancer IPs for the internal API service. These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. Entries in the apiIntLoadBalancerIPs must be unique. A maximum of 16 IP addresses are permitted.", + "apiLoadBalancerIPs": "apiLoadBalancerIPs holds Load Balancer IPs for the API service. These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. Could be empty for private clusters. Entries in the apiLoadBalancerIPs must be unique. A maximum of 16 IP addresses are permitted.", + "ingressLoadBalancerIPs": "ingressLoadBalancerIPs holds IPs for Ingress Load Balancers. These Load Balancer IP addresses can be IPv4 and/or IPv6 addresses. Entries in the ingressLoadBalancerIPs must be unique. A maximum of 16 IP addresses are permitted.", +} + +func (CloudLoadBalancerIPs) SwaggerDoc() map[string]string { + return map_CloudLoadBalancerIPs +} + var map_EquinixMetalPlatformSpec = map[string]string{ "": "EquinixMetalPlatformSpec holds the desired state of the Equinix Metal infrastructure provider. This only includes fields that can be modified in the cluster.", } @@ -1346,12 +1378,12 @@ func (GCPPlatformSpec) SwaggerDoc() map[string]string { } var map_GCPPlatformStatus = map[string]string{ - "": "GCPPlatformStatus holds the current status of the Google Cloud Platform infrastructure provider.", - "projectID": "resourceGroupName is the Project ID for new GCP resources created for the cluster.", - "region": "region holds the region for new GCP resources created for the cluster.", - "resourceLabels": "resourceLabels is a list of additional labels to apply to GCP resources created for the cluster. See https://cloud.google.com/compute/docs/labeling-resources for information on labeling GCP resources. GCP supports a maximum of 64 labels per resource. OpenShift reserves 32 labels for internal use, allowing 32 labels for user configuration.", - "resourceTags": "resourceTags is a list of additional tags to apply to GCP resources created for the cluster. See https://cloud.google.com/resource-manager/docs/tags/tags-overview for information on tagging GCP resources. GCP supports a maximum of 50 tags per resource.", - "clusterHostedDNS": "clusterHostedDNS indicates the type of DNS solution in use within the cluster. Its default value of \"Disabled\" indicates that the cluster's DNS is the default provided by the cloud platform. It can be \"Enabled\" during install to bypass the configuration of the cloud default DNS. When \"Enabled\", the cluster needs to provide a self-hosted DNS solution for the cluster's installation to succeed. The cluster's use of the cloud's Load Balancers is unaffected by this setting. The value is immutable after it has been set at install time. Currently, there is no way for the customer to add additional DNS entries into the cluster hosted DNS. Enabling this functionality allows the user to start their own DNS solution outside the cluster after installation is complete. The customer would be responsible for configuring this custom DNS solution, and it can be run in addition to the in-cluster DNS solution.", + "": "GCPPlatformStatus holds the current status of the Google Cloud Platform infrastructure provider.", + "projectID": "resourceGroupName is the Project ID for new GCP resources created for the cluster.", + "region": "region holds the region for new GCP resources created for the cluster.", + "resourceLabels": "resourceLabels is a list of additional labels to apply to GCP resources created for the cluster. See https://cloud.google.com/compute/docs/labeling-resources for information on labeling GCP resources. GCP supports a maximum of 64 labels per resource. OpenShift reserves 32 labels for internal use, allowing 32 labels for user configuration.", + "resourceTags": "resourceTags is a list of additional tags to apply to GCP resources created for the cluster. See https://cloud.google.com/resource-manager/docs/tags/tags-overview for information on tagging GCP resources. GCP supports a maximum of 50 tags per resource.", + "cloudLoadBalancerConfig": "cloudLoadBalancerConfig is a union that contains the IP addresses of API, API-Int and Ingress Load Balancers created on the cloud platform. These values would not be populated on on-prem platforms. These Load Balancer IPs are used to configure the in-cluster DNS instances for API, API-Int and Ingress services. `dnsType` is expected to be set to `ClusterHosted` when these Load Balancer IP addresses are populated and used.", } func (GCPPlatformStatus) SwaggerDoc() map[string]string { diff --git a/vendor/github.com/openshift/api/operator/v1/0000_70_cluster-network-operator_01-CustomNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/operator/v1/0000_70_cluster-network-operator_01-CustomNoUpgrade.crd.yaml index 4938ac279734..ed528564201f 100644 --- a/vendor/github.com/openshift/api/operator/v1/0000_70_cluster-network-operator_01-CustomNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/0000_70_cluster-network-operator_01-CustomNoUpgrade.crd.yaml @@ -269,6 +269,19 @@ spec: ipsecConfig: description: ipsecConfig enables and configures IPsec for pods on the pod network within the cluster. type: object + default: + mode: Disabled + properties: + mode: + description: mode defines the behaviour of the ipsec configuration within the platform. Valid values are `Disabled`, `External` and `Full`. When 'Disabled', ipsec will not be enabled at the node level. When 'External', ipsec is enabled on the node level but requires the user to configure the secure communication parameters. This mode is for external secure communications and the configuration can be done using the k8s-nmstate operator. When 'Full', ipsec is configured on the node level and inter-pod secure communication within the cluster is configured. Note with `Full`, if ipsec is desired for communication with external (to the cluster) entities (such as storage arrays), this is left to the user to configure. + type: string + enum: + - Disabled + - External + - Full + x-kubernetes-validations: + - rule: self == oldSelf || has(self.mode) + message: ipsecConfig.mode is required mtu: description: mtu is the MTU to use for the tunnel interface. This must be 100 bytes smaller than the uplink mtu. Default is 1400 type: integer diff --git a/vendor/github.com/openshift/api/operator/v1/0000_70_cluster-network-operator_01-Default.crd.yaml b/vendor/github.com/openshift/api/operator/v1/0000_70_cluster-network-operator_01-Default.crd.yaml index 83849f24b7a3..a32c771b8249 100644 --- a/vendor/github.com/openshift/api/operator/v1/0000_70_cluster-network-operator_01-Default.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/0000_70_cluster-network-operator_01-Default.crd.yaml @@ -269,6 +269,19 @@ spec: ipsecConfig: description: ipsecConfig enables and configures IPsec for pods on the pod network within the cluster. type: object + default: + mode: Disabled + properties: + mode: + description: mode defines the behaviour of the ipsec configuration within the platform. Valid values are `Disabled`, `External` and `Full`. When 'Disabled', ipsec will not be enabled at the node level. When 'External', ipsec is enabled on the node level but requires the user to configure the secure communication parameters. This mode is for external secure communications and the configuration can be done using the k8s-nmstate operator. When 'Full', ipsec is configured on the node level and inter-pod secure communication within the cluster is configured. Note with `Full`, if ipsec is desired for communication with external (to the cluster) entities (such as storage arrays), this is left to the user to configure. + type: string + enum: + - Disabled + - External + - Full + x-kubernetes-validations: + - rule: self == oldSelf || has(self.mode) + message: ipsecConfig.mode is required mtu: description: mtu is the MTU to use for the tunnel interface. This must be 100 bytes smaller than the uplink mtu. Default is 1400 type: integer @@ -415,6 +428,13 @@ spec: description: multicast specifies whether or not the multicast configuration is migrated automatically when changing the cluster default network provider. If unset, this property defaults to 'true' and multicast configure is migrated. type: boolean default: true + mode: + description: mode indicates the mode of network migration. The supported values are "Live", "Offline" and omitted. A "Live" migration operation will not cause service interruption by migrating the CNI of each node one by one. The cluster network will work as normal during the network migration. An "Offline" migration operation will cause service interruption. During an "Offline" migration, two rounds of node reboots are required. The cluster network will be malfunctioning during the network migration. When omitted, this means no opinion and the platform is left to choose a reasonable default which is subject to change over time. The current default value is "Offline". + type: string + enum: + - Live + - Offline + - "" mtu: description: mtu contains the MTU migration configuration. Set this to allow changing the MTU values for the default network. If unset, the operation of changing the MTU for the default network will be rejected. type: object diff --git a/vendor/github.com/openshift/api/operator/v1/0000_70_cluster-network-operator_01-TechPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/operator/v1/0000_70_cluster-network-operator_01-TechPreviewNoUpgrade.crd.yaml index 294b5c945f48..43c7758cd4d3 100644 --- a/vendor/github.com/openshift/api/operator/v1/0000_70_cluster-network-operator_01-TechPreviewNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/0000_70_cluster-network-operator_01-TechPreviewNoUpgrade.crd.yaml @@ -269,6 +269,19 @@ spec: ipsecConfig: description: ipsecConfig enables and configures IPsec for pods on the pod network within the cluster. type: object + default: + mode: Disabled + properties: + mode: + description: mode defines the behaviour of the ipsec configuration within the platform. Valid values are `Disabled`, `External` and `Full`. When 'Disabled', ipsec will not be enabled at the node level. When 'External', ipsec is enabled on the node level but requires the user to configure the secure communication parameters. This mode is for external secure communications and the configuration can be done using the k8s-nmstate operator. When 'Full', ipsec is configured on the node level and inter-pod secure communication within the cluster is configured. Note with `Full`, if ipsec is desired for communication with external (to the cluster) entities (such as storage arrays), this is left to the user to configure. + type: string + enum: + - Disabled + - External + - Full + x-kubernetes-validations: + - rule: self == oldSelf || has(self.mode) + message: ipsecConfig.mode is required mtu: description: mtu is the MTU to use for the tunnel interface. This must be 100 bytes smaller than the uplink mtu. Default is 1400 type: integer diff --git a/vendor/github.com/openshift/api/operator/v1/0000_90_cluster_csi_driver_01_config.crd.yaml b/vendor/github.com/openshift/api/operator/v1/0000_90_cluster_csi_driver_01_config.crd.yaml index 93e34a5dfcec..cbd642a5687c 100644 --- a/vendor/github.com/openshift/api/operator/v1/0000_90_cluster_csi_driver_01_config.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/0000_90_cluster_csi_driver_01_config.crd.yaml @@ -59,7 +59,7 @@ spec: properties: kmsKeyARN: description: kmsKeyARN sets the cluster default storage class to encrypt volumes with a user-defined KMS key, rather than the default KMS key used by AWS. The value may be either the ARN or Alias ARN of a KMS key. - pattern: ^arn:(aws|aws-cn|aws-us-gov):kms:[a-z0-9-]+:[0-9]{12}:(key|alias)\/.*$ + pattern: ^arn:(aws|aws-cn|aws-us-gov|aws-iso|aws-iso-b|aws-iso-e|aws-iso-f):kms:[a-z0-9-]+:[0-9]{12}:(key|alias)\/.*$ type: string type: object azure: diff --git a/vendor/github.com/openshift/api/operator/v1/stable.network.testsuite.yaml b/vendor/github.com/openshift/api/operator/v1/stable.network.testsuite.yaml index 3d65b5dcaf77..7590f57142b1 100644 --- a/vendor/github.com/openshift/api/operator/v1/stable.network.testsuite.yaml +++ b/vendor/github.com/openshift/api/operator/v1/stable.network.testsuite.yaml @@ -35,6 +35,8 @@ tests: routingViaHost: false ipv4: internalMasqueradeSubnet: "169.254.168.0/29" + ipsecConfig: + mode: Disabled disableNetworkDiagnostics: false logLevel: Normal operatorLogLevel: Normal @@ -124,6 +126,8 @@ tests: ipv6: internalMasqueradeSubnet: "abcd:ef01:2345:6789:abcd:ef01:2345:6789/125" routingViaHost: false + ipsecConfig: + mode: Disabled disableNetworkDiagnostics: false logLevel: Normal operatorLogLevel: Normal @@ -147,6 +151,8 @@ tests: routingViaHost: false ipv6: internalMasqueradeSubnet: "abcd:ef01:2345:6789::2345:6789/20" + ipsecConfig: + mode: Disabled disableNetworkDiagnostics: false logLevel: Normal operatorLogLevel: Normal @@ -249,11 +255,11 @@ tests: ipv6: internalMasqueradeSubnet: "abcd:eff01:2345:6789::2345:6789/20" expectedError: "Invalid value: \"string\": each segment of an IPv6 address must be a hexadecimal number between 0 and FFFF, failed on segment 2" - - name: Should not be able to create migration mode + - name: Should be able to create migration mode initial: | apiVersion: operator.openshift.io/v1 kind: Network - spec: + spec: migration: mode: Live expected: | @@ -263,4 +269,141 @@ tests: disableNetworkDiagnostics: false logLevel: Normal operatorLogLevel: Normal - migration: {} + migration: + mode: Live + - name: "IPsec - Empty ipsecConfig is allowed in initial state" + initial: | + apiVersion: operator.openshift.io/v1 + kind: Network + spec: + defaultNetwork: + ovnKubernetesConfig: + ipsecConfig: {} + expected: | + apiVersion: operator.openshift.io/v1 + kind: Network + spec: + defaultNetwork: + ovnKubernetesConfig: + ipsecConfig: {} + disableNetworkDiagnostics: false + logLevel: Normal + operatorLogLevel: Normal + - name: "IPsec - Populated ipsecConfig is allowed" + initial: | + apiVersion: operator.openshift.io/v1 + kind: Network + spec: + defaultNetwork: + ovnKubernetesConfig: + ipsecConfig: + mode: Full + expected: | + apiVersion: operator.openshift.io/v1 + kind: Network + spec: + defaultNetwork: + ovnKubernetesConfig: + ipsecConfig: + mode: Full + disableNetworkDiagnostics: false + logLevel: Normal + operatorLogLevel: Normal + - name: "IPsec - Start without setting ipsecConfig" + initial: | + apiVersion: operator.openshift.io/v1 + kind: Network + spec: + defaultNetwork: + ovnKubernetesConfig: + expected: | + apiVersion: operator.openshift.io/v1 + kind: Network + spec: + defaultNetwork: {} + disableNetworkDiagnostics: false + logLevel: Normal + operatorLogLevel: Normal + - name: "IPsec - empty string is not allowed" + initial: | + apiVersion: operator.openshift.io/v1 + kind: Network + spec: + defaultNetwork: + ovnKubernetesConfig: + ipsecConfig: + mode: "" + expectedError: "Unsupported value: \"\": supported values: \"Disabled\", \"External\", \"Full\"" + onUpdate: + - name: "IPsec - Removing ipsecConfig.mode is not allowed" + initial: | + apiVersion: operator.openshift.io/v1 + kind: Network + spec: + defaultNetwork: + ovnKubernetesConfig: + ipsecConfig: + mode: Full + updated: | + apiVersion: operator.openshift.io/v1 + kind: Network + spec: + defaultNetwork: + ovnKubernetesConfig: + ipsecConfig: {} + expectedError: "ipsecConfig.mode is required" + - name: "IPsec - Disabling IPsec" + initial: | + apiVersion: operator.openshift.io/v1 + kind: Network + spec: + defaultNetwork: + ovnKubernetesConfig: + ipsecConfig: + mode: Full + updated: | + apiVersion: operator.openshift.io/v1 + kind: Network + spec: + defaultNetwork: + ovnKubernetesConfig: + ipsecConfig: + mode: Disabled + expected: | + apiVersion: operator.openshift.io/v1 + kind: Network + spec: + defaultNetwork: + ovnKubernetesConfig: + ipsecConfig: + mode: Disabled + disableNetworkDiagnostics: false + logLevel: Normal + operatorLogLevel: Normal + - name: "IPsec - Empty ipsecConfig when changing other parameters" + initial: | + apiVersion: operator.openshift.io/v1 + kind: Network + spec: + defaultNetwork: + ovnKubernetesConfig: + ipsecConfig: {} + updated: | + apiVersion: operator.openshift.io/v1 + kind: Network + spec: + defaultNetwork: + ovnKubernetesConfig: + ipsecConfig: {} + mtu: 5888 + expected: | + apiVersion: operator.openshift.io/v1 + kind: Network + spec: + defaultNetwork: + ovnKubernetesConfig: + ipsecConfig: {} + mtu: 5888 + disableNetworkDiagnostics: false + logLevel: Normal + operatorLogLevel: Normal diff --git a/vendor/github.com/openshift/api/operator/v1/types_csi_cluster_driver.go b/vendor/github.com/openshift/api/operator/v1/types_csi_cluster_driver.go index 8e9853b06fb9..9ec7e5bed5b0 100644 --- a/vendor/github.com/openshift/api/operator/v1/types_csi_cluster_driver.go +++ b/vendor/github.com/openshift/api/operator/v1/types_csi_cluster_driver.go @@ -159,7 +159,7 @@ type AWSCSIDriverConfigSpec struct { // kmsKeyARN sets the cluster default storage class to encrypt volumes with a user-defined KMS key, // rather than the default KMS key used by AWS. // The value may be either the ARN or Alias ARN of a KMS key. - // +kubebuilder:validation:Pattern:=`^arn:(aws|aws-cn|aws-us-gov):kms:[a-z0-9-]+:[0-9]{12}:(key|alias)\/.*$` + // +kubebuilder:validation:Pattern:=`^arn:(aws|aws-cn|aws-us-gov|aws-iso|aws-iso-b|aws-iso-e|aws-iso-f):kms:[a-z0-9-]+:[0-9]{12}:(key|alias)\/.*$` // +optional KMSKeyARN string `json:"kmsKeyARN,omitempty"` } diff --git a/vendor/github.com/openshift/api/operator/v1/types_network.go b/vendor/github.com/openshift/api/operator/v1/types_network.go index cec3b6318100..190605b8527f 100644 --- a/vendor/github.com/openshift/api/operator/v1/types_network.go +++ b/vendor/github.com/openshift/api/operator/v1/types_network.go @@ -157,7 +157,6 @@ type NetworkMigration struct { // An "Offline" migration operation will cause service interruption. During an "Offline" migration, two rounds of node reboots are required. The cluster network will be malfunctioning during the network migration. // When omitted, this means no opinion and the platform is left to choose a reasonable default which is subject to change over time. // The current default value is "Offline". - // +openshift:enable:FeatureSets=CustomNoUpgrade;TechPreviewNoUpgrade // +optional Mode NetworkMigrationMode `json:"mode"` } @@ -390,6 +389,8 @@ type OVNKubernetesConfig struct { // ipsecConfig enables and configures IPsec for pods on the pod network within the // cluster. // +optional + // +kubebuilder:default={"mode": "Disabled"} + // +default={"mode": "Disabled"} IPsecConfig *IPsecConfig `json:"ipsecConfig,omitempty"` // policyAuditConfig is the configuration for network policy audit events. If unset, // reported defaults are used. @@ -428,7 +429,19 @@ type HybridOverlayConfig struct { HybridOverlayVXLANPort *uint32 `json:"hybridOverlayVXLANPort,omitempty"` } +// +kubebuilder:validation:XValidation:rule="self == oldSelf || has(self.mode)",message="ipsecConfig.mode is required" type IPsecConfig struct { + // mode defines the behaviour of the ipsec configuration within the platform. + // Valid values are `Disabled`, `External` and `Full`. + // When 'Disabled', ipsec will not be enabled at the node level. + // When 'External', ipsec is enabled on the node level but requires the user to configure the secure communication parameters. + // This mode is for external secure communications and the configuration can be done using the k8s-nmstate operator. + // When 'Full', ipsec is configured on the node level and inter-pod secure communication within the cluster is configured. + // Note with `Full`, if ipsec is desired for communication with external (to the cluster) entities (such as storage arrays), + // this is left to the user to configure. + // +kubebuilder:validation:Enum=Disabled;External;Full + // +optional + Mode IPsecMode `json:"mode,omitempty"` } type IPForwardingMode string @@ -691,3 +704,17 @@ const ( // IPAMTypeStatic uses static IP IPAMTypeStatic IPAMType = "Static" ) + +// IPsecMode enumerates the modes for IPsec configuration +type IPsecMode string + +const ( + // IPsecModeDisabled disables IPsec altogether + IPsecModeDisabled IPsecMode = "Disabled" + // IPsecModeExternal enables IPsec on the node level, but expects the user to configure it using k8s-nmstate or + // other means - it is most useful for secure communication from the cluster to external endpoints + IPsecModeExternal IPsecMode = "External" + // IPsecModeFull enables IPsec on the node level (the same as IPsecModeExternal), and configures it to secure communication + // between pods on the cluster network. + IPsecModeFull IPsecMode = "Full" +) diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.swagger_doc_generated.go b/vendor/github.com/openshift/api/operator/v1/zz_generated.swagger_doc_generated.go index d50e77e44d31..48133af8df4b 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.swagger_doc_generated.go +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.swagger_doc_generated.go @@ -1374,6 +1374,14 @@ func (IPFIXConfig) SwaggerDoc() map[string]string { return map_IPFIXConfig } +var map_IPsecConfig = map[string]string{ + "mode": "mode defines the behaviour of the ipsec configuration within the platform. Valid values are `Disabled`, `External` and `Full`. When 'Disabled', ipsec will not be enabled at the node level. When 'External', ipsec is enabled on the node level but requires the user to configure the secure communication parameters. This mode is for external secure communications and the configuration can be done using the k8s-nmstate operator. When 'Full', ipsec is configured on the node level and inter-pod secure communication within the cluster is configured. Note with `Full`, if ipsec is desired for communication with external (to the cluster) entities (such as storage arrays), this is left to the user to configure.", +} + +func (IPsecConfig) SwaggerDoc() map[string]string { + return map_IPsecConfig +} + var map_IPv4GatewayConfig = map[string]string{ "": "IPV4GatewayConfig holds the configuration paramaters for IPV4 connections in the GatewayConfig for OVN-Kubernetes", "internalMasqueradeSubnet": "internalMasqueradeSubnet contains the masquerade addresses in IPV4 CIDR format used internally by ovn-kubernetes to enable host to service traffic. Each host in the cluster is configured with these addresses, as well as the shared gateway bridge interface. The values can be changed after installation. The subnet chosen should not overlap with other networks specified for OVN-Kubernetes as well as other networks used on the host. Additionally the subnet must be large enough to accommodate 6 IPs (maximum prefix length /29). When omitted, this means no opinion and the platform is left to choose a reasonable default which is subject to change over time. The current default subnet is 169.254.169.0/29 The value must be in proper IPV4 CIDR format", diff --git a/vendor/github.com/openshift/api/route/v1/generated.proto b/vendor/github.com/openshift/api/route/v1/generated.proto index d31fa5222e7a..66b35420e98a 100644 --- a/vendor/github.com/openshift/api/route/v1/generated.proto +++ b/vendor/github.com/openshift/api/route/v1/generated.proto @@ -213,7 +213,7 @@ message RouteIngress { // router. message RouteIngressCondition { // Type is the type of the condition. - // Currently only Admitted. + // Currently only Admitted or UnservableInFutureVersions. optional string type = 1; // Status is the status of the condition. diff --git a/vendor/github.com/openshift/api/route/v1/route-CustomNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/route/v1/route-CustomNoUpgrade.crd.yaml index 13461f666947..eeeccbc97a0a 100644 --- a/vendor/github.com/openshift/api/route/v1/route-CustomNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/route/v1/route-CustomNoUpgrade.crd.yaml @@ -344,7 +344,7 @@ spec: description: Status is the status of the condition. Can be True, False, Unknown. type: string type: - description: Type is the type of the condition. Currently only Admitted. + description: Type is the type of the condition. Currently only Admitted or UnservableInFutureVersions. type: string host: description: Host is the host string under which the route is exposed; this value is required diff --git a/vendor/github.com/openshift/api/route/v1/route-TechPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/route/v1/route-TechPreviewNoUpgrade.crd.yaml index 87b617cac119..a9146d716bf3 100644 --- a/vendor/github.com/openshift/api/route/v1/route-TechPreviewNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/route/v1/route-TechPreviewNoUpgrade.crd.yaml @@ -344,7 +344,7 @@ spec: description: Status is the status of the condition. Can be True, False, Unknown. type: string type: - description: Type is the type of the condition. Currently only Admitted. + description: Type is the type of the condition. Currently only Admitted or UnservableInFutureVersions. type: string host: description: Host is the host string under which the route is exposed; this value is required diff --git a/vendor/github.com/openshift/api/route/v1/route.crd.yaml b/vendor/github.com/openshift/api/route/v1/route.crd.yaml index cda46fc33f99..e12676025581 100644 --- a/vendor/github.com/openshift/api/route/v1/route.crd.yaml +++ b/vendor/github.com/openshift/api/route/v1/route.crd.yaml @@ -376,7 +376,7 @@ spec: description: Status is the status of the condition. Can be True, False, Unknown. type: string type: - description: Type is the type of the condition. Currently only Admitted. + description: Type is the type of the condition. Currently only Admitted or UnservableInFutureVersions. type: string required: - status diff --git a/vendor/github.com/openshift/api/route/v1/types.go b/vendor/github.com/openshift/api/route/v1/types.go index 2de728bc00f4..b5a567d6a5b3 100644 --- a/vendor/github.com/openshift/api/route/v1/types.go +++ b/vendor/github.com/openshift/api/route/v1/types.go @@ -369,14 +369,16 @@ type RouteIngressConditionType string const ( // RouteAdmitted means the route is able to service requests for the provided Host RouteAdmitted RouteIngressConditionType = "Admitted" - // TODO: add other route condition types + // RouteUnservableInFutureVersions indicates that the route is using an unsupported + // configuration that may be incompatible with a future version of OpenShift. + RouteUnservableInFutureVersions RouteIngressConditionType = "UnservableInFutureVersions" ) // RouteIngressCondition contains details for the current condition of this route on a particular // router. type RouteIngressCondition struct { // Type is the type of the condition. - // Currently only Admitted. + // Currently only Admitted or UnservableInFutureVersions. Type RouteIngressConditionType `json:"type" protobuf:"bytes,1,opt,name=type,casttype=RouteIngressConditionType"` // Status is the status of the condition. // Can be True, False, Unknown. diff --git a/vendor/github.com/openshift/api/route/v1/zz_generated.swagger_doc_generated.go b/vendor/github.com/openshift/api/route/v1/zz_generated.swagger_doc_generated.go index 8d495871771e..c65815a1cc62 100644 --- a/vendor/github.com/openshift/api/route/v1/zz_generated.swagger_doc_generated.go +++ b/vendor/github.com/openshift/api/route/v1/zz_generated.swagger_doc_generated.go @@ -85,7 +85,7 @@ func (RouteIngress) SwaggerDoc() map[string]string { var map_RouteIngressCondition = map[string]string{ "": "RouteIngressCondition contains details for the current condition of this route on a particular router.", - "type": "Type is the type of the condition. Currently only Admitted.", + "type": "Type is the type of the condition. Currently only Admitted or UnservableInFutureVersions.", "status": "Status is the status of the condition. Can be True, False, Unknown.", "reason": "(brief) reason for the condition's last transition, and is usually a machine and human readable constant", "message": "Human readable message indicating details about last transition.", diff --git a/vendor/modules.txt b/vendor/modules.txt index 0aa527ec1411..17d56bbf7c9f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -749,7 +749,7 @@ github.com/opencontainers/selinux/go-selinux github.com/opencontainers/selinux/go-selinux/label github.com/opencontainers/selinux/pkg/pwalk github.com/opencontainers/selinux/pkg/pwalkdir -# github.com/openshift/api v0.0.0-20231205121914-b5716b30456a +# github.com/openshift/api v0.0.0-20240522145529-93d6bda14341 ## explicit; go 1.20 github.com/openshift/api github.com/openshift/api/annotations