Bump library to v1.1.0 (#1216)
Some checks failed
Scorecard supply-chain security / Scorecard analysis (push) Failing after 28s
Post / coverage (push) Failing after 17s
Post / images (amd64, addon-manager) (push) Failing after 19s
Post / images (amd64, placement) (push) Failing after 26s
Post / images (amd64, registration) (push) Failing after 20s
Post / images (amd64, registration-operator) (push) Failing after 20s
Post / images (amd64, work) (push) Failing after 26s
Post / images (arm64, addon-manager) (push) Failing after 18s
Post / images (arm64, placement) (push) Failing after 17s
Post / images (arm64, registration) (push) Failing after 26s
Post / images (arm64, registration-operator) (push) Failing after 26s
Post / images (arm64, work) (push) Failing after 24s
Post / image manifest (addon-manager) (push) Has been skipped
Post / image manifest (placement) (push) Has been skipped
Post / image manifest (registration) (push) Has been skipped
Post / image manifest (registration-operator) (push) Has been skipped
Post / image manifest (work) (push) Has been skipped
Post / trigger clusteradm e2e (push) Has been skipped
Close stale issues and PRs / stale (push) Failing after 44s

Signed-off-by: Jian Qiu <jqiu@redhat.com>
This commit is contained in:
Jian Qiu
2025-10-21 12:51:21 +08:00
committed by GitHub
parent f61f5a6e32
commit 2867c26891
15 changed files with 128 additions and 52 deletions

View File

@@ -59,7 +59,7 @@ metadata:
categories: Integration & Delivery,OpenShift Optional
certified: "false"
containerImage: quay.io/open-cluster-management/registration-operator:latest
createdAt: "2025-10-10T01:31:41Z"
createdAt: "2025-10-21T02:16:40Z"
description: Manages the installation and upgrade of the ClusterManager.
operators.operatorframework.io/builder: operator-sdk-v1.32.0
operators.operatorframework.io/project_layout: go.kubebuilder.io/v3

View File

@@ -31,7 +31,7 @@ metadata:
categories: Integration & Delivery,OpenShift Optional
certified: "false"
containerImage: quay.io/open-cluster-management/registration-operator:latest
createdAt: "2025-10-10T01:31:41Z"
createdAt: "2025-10-21T02:16:41Z"
description: Manages the installation and upgrade of the Klusterlet.
operators.operatorframework.io/builder: operator-sdk-v1.32.0
operators.operatorframework.io/project_layout: go.kubebuilder.io/v3

8
go.mod
View File

@@ -28,7 +28,7 @@ require (
github.com/valyala/fasttemplate v1.2.2
google.golang.org/grpc v1.68.1
gopkg.in/yaml.v2 v2.4.0
helm.sh/helm/v3 v3.18.5
helm.sh/helm/v3 v3.18.6
k8s.io/api v0.33.4
k8s.io/apiextensions-apiserver v0.33.4
k8s.io/apimachinery v0.33.4
@@ -39,9 +39,9 @@ require (
k8s.io/kube-aggregator v0.33.4
k8s.io/kubectl v0.33.4
k8s.io/utils v0.0.0-20241210054802-24370beab758
open-cluster-management.io/addon-framework v1.0.1-0.20250916042555-c8a4fa748ce9
open-cluster-management.io/api v1.0.1-0.20251009064814-48b723491429
open-cluster-management.io/sdk-go v1.0.1-0.20251016065040-b82d34b3c2c2
open-cluster-management.io/addon-framework v1.1.0
open-cluster-management.io/api v1.1.0
open-cluster-management.io/sdk-go v1.1.0
sigs.k8s.io/about-api v0.0.0-20250131010323-518069c31c03
sigs.k8s.io/cluster-inventory-api v0.0.0-20240730014211-ef0154379848
sigs.k8s.io/controller-runtime v0.21.0

16
go.sum
View File

@@ -533,8 +533,8 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
helm.sh/helm/v3 v3.18.5 h1:Cc3Z5vd6kDrZq9wO9KxKLNEickiTho6/H/dBNRVSos4=
helm.sh/helm/v3 v3.18.5/go.mod h1:L/dXDR2r539oPlFP1PJqKAC1CUgqHJDLkxKpDGrWnyg=
helm.sh/helm/v3 v3.18.6 h1:S/2CqcYnNfLckkHLI0VgQbxgcDaU3N4A/46E3n9wSNY=
helm.sh/helm/v3 v3.18.6/go.mod h1:L/dXDR2r539oPlFP1PJqKAC1CUgqHJDLkxKpDGrWnyg=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
k8s.io/api v0.33.4 h1:oTzrFVNPXBjMu0IlpA2eDDIU49jsuEorGHB4cvKupkk=
@@ -561,12 +561,12 @@ k8s.io/kubectl v0.33.4 h1:nXEI6Vi+oB9hXxoAHyHisXolm/l1qutK3oZQMak4N98=
k8s.io/kubectl v0.33.4/go.mod h1:Xe7P9X4DfILvKmlBsVqUtzktkI56lEj22SJW7cFy6nE=
k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJJI8IUa1AmH/qa0=
k8s.io/utils v0.0.0-20241210054802-24370beab758/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
open-cluster-management.io/addon-framework v1.0.1-0.20250916042555-c8a4fa748ce9 h1:x0InHHM8GqY0qGYGyJx8SG7qNIOtMGs7n4EwowLksGA=
open-cluster-management.io/addon-framework v1.0.1-0.20250916042555-c8a4fa748ce9/go.mod h1:IrMjmd3dLjJtrP2Aqa0Sf/3lDysJHa4j5lNQQ13NxVs=
open-cluster-management.io/api v1.0.1-0.20251009064814-48b723491429 h1:jU4r3zijNA+Ab17oF7lBck0YHc7f7wM8r2RqZJw6ZSs=
open-cluster-management.io/api v1.0.1-0.20251009064814-48b723491429/go.mod h1:lEc5Wkc9ON5ym/qAtIqNgrE7NW7IEOCOC611iQMlnKM=
open-cluster-management.io/sdk-go v1.0.1-0.20251016065040-b82d34b3c2c2 h1:cQJuyf4p9VqqIbfpYkN8eRBrbyLpEc19WXeu8oyWpXA=
open-cluster-management.io/sdk-go v1.0.1-0.20251016065040-b82d34b3c2c2/go.mod h1:DH4EMNDMiousmaj+noHYQxm48T+dbogiAfALhDnrjMg=
open-cluster-management.io/addon-framework v1.1.0 h1:GoPbg5Q9KEI+Vvgs9PUs2IjIoU/BoXPHEyULVNLF/po=
open-cluster-management.io/addon-framework v1.1.0/go.mod h1:KPdLM+CfUKgwVuVE9Tyu2nOuD6LgDmx94HOCnJwLIdo=
open-cluster-management.io/api v1.1.0 h1:fu5xst9T/Ya6o41kqdd0zbNiDU+D3nNMTvoRVeF8j+U=
open-cluster-management.io/api v1.1.0/go.mod h1:lEc5Wkc9ON5ym/qAtIqNgrE7NW7IEOCOC611iQMlnKM=
open-cluster-management.io/sdk-go v1.1.0 h1:vYGkoihIVetyVT4ICO7HjoUHsnh6Gf+Da4ZSmWCamhc=
open-cluster-management.io/sdk-go v1.1.0/go.mod h1:DH4EMNDMiousmaj+noHYQxm48T+dbogiAfALhDnrjMg=
sigs.k8s.io/about-api v0.0.0-20250131010323-518069c31c03 h1:1ShFiMjGQOR/8jTBkmZrk1gORxnvMwm1nOy2/DbHg4U=
sigs.k8s.io/about-api v0.0.0-20250131010323-518069c31c03/go.mod h1:F1pT4mK53U6F16/zuaPSYpBaR7x5Kjym6aKJJC0/DHU=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 h1:jpcvIRr3GLoUoEKRkHKSmGjxb6lWwrBlJsXc+eUYQHM=

View File

@@ -741,7 +741,7 @@ spec:
description: Summary totals of resulting ManifestWorks for the
placement
properties:
Applied:
applied:
description: 'Applied is the number of ManifestWorks with
condition Applied: true'
type: integer
@@ -763,7 +763,7 @@ spec:
summary:
description: Summary totals of resulting ManifestWorks for all placements
properties:
Applied:
applied:
description: 'Applied is the number of ManifestWorks with condition
Applied: true'
type: integer

View File

@@ -41,10 +41,12 @@ spec:
properties:
agentInstallNamespace:
default: open-cluster-management-agent-addon
description: AgentInstallNamespace is the namespace where the add-on
agent should be installed on the managed cluster.
description: |-
AgentInstallNamespace is the namespace where the add-on agent should be installed on the managed cluster.
For template-type addons: set to empty string "" to use the namespace defined in the addonTemplate.
For non-template addons: defaults to "open-cluster-management-agent-addon" if not specified.
maxLength: 63
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?)?$
type: string
customizedVariables:
description: |-

View File

@@ -18,15 +18,57 @@ package chartutil
import (
"bytes"
"crypto/tls"
"errors"
"fmt"
"strings"
"time"
"github.com/santhosh-tekuri/jsonschema/v6"
"net/http"
"helm.sh/helm/v3/internal/version"
"helm.sh/helm/v3/pkg/chart"
)
// HTTPURLLoader implements a loader for HTTP/HTTPS URLs
type HTTPURLLoader http.Client
func (l *HTTPURLLoader) Load(urlStr string) (any, error) {
client := (*http.Client)(l)
req, err := http.NewRequest(http.MethodGet, urlStr, nil)
if err != nil {
return nil, fmt.Errorf("failed to create HTTP request for %s: %w", urlStr, err)
}
req.Header.Set("User-Agent", version.GetUserAgent())
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("HTTP request failed for %s: %w", urlStr, err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("HTTP request to %s returned status %d (%s)", urlStr, resp.StatusCode, http.StatusText(resp.StatusCode))
}
return jsonschema.UnmarshalJSON(resp.Body)
}
// newHTTPURLLoader creates a HTTP URL loader with proxy support.
func newHTTPURLLoader() *HTTPURLLoader {
httpLoader := HTTPURLLoader(http.Client{
Timeout: 15 * time.Second,
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
TLSClientConfig: &tls.Config{},
},
})
return &httpLoader
}
// ValidateAgainstSchema checks that values does not violate the structure laid out in schema
func ValidateAgainstSchema(chrt *chart.Chart, values map[string]interface{}) error {
var sb strings.Builder
@@ -68,7 +110,15 @@ func ValidateAgainstSingleSchema(values Values, schemaJSON []byte) (reterr error
return err
}
// Configure compiler with loaders for different URL schemes
loader := jsonschema.SchemeURLLoader{
"file": jsonschema.FileLoader{},
"http": newHTTPURLLoader(),
"https": newHTTPURLLoader(),
}
compiler := jsonschema.NewCompiler()
compiler.UseLoader(loader)
err = compiler.AddResource("file:///values.schema.json", schema)
if err != nil {
return err

8
vendor/modules.txt vendored
View File

@@ -973,7 +973,7 @@ gopkg.in/yaml.v2
# gopkg.in/yaml.v3 v3.0.1
## explicit
gopkg.in/yaml.v3
# helm.sh/helm/v3 v3.18.5
# helm.sh/helm/v3 v3.18.6
## explicit; go 1.24.0
helm.sh/helm/v3/internal/sympath
helm.sh/helm/v3/internal/version
@@ -1733,7 +1733,7 @@ k8s.io/utils/path
k8s.io/utils/pointer
k8s.io/utils/ptr
k8s.io/utils/trace
# open-cluster-management.io/addon-framework v1.0.1-0.20250916042555-c8a4fa748ce9
# open-cluster-management.io/addon-framework v1.1.0
## explicit; go 1.24.0
open-cluster-management.io/addon-framework/pkg/addonfactory
open-cluster-management.io/addon-framework/pkg/addonmanager
@@ -1749,7 +1749,7 @@ open-cluster-management.io/addon-framework/pkg/agent
open-cluster-management.io/addon-framework/pkg/assets
open-cluster-management.io/addon-framework/pkg/index
open-cluster-management.io/addon-framework/pkg/utils
# open-cluster-management.io/api v1.0.1-0.20251009064814-48b723491429
# open-cluster-management.io/api v1.1.0
## explicit; go 1.24.0
open-cluster-management.io/api/addon/v1alpha1
open-cluster-management.io/api/client/addon/clientset/versioned
@@ -1817,7 +1817,7 @@ open-cluster-management.io/api/operator/v1
open-cluster-management.io/api/utils/work/v1/workapplier
open-cluster-management.io/api/work/v1
open-cluster-management.io/api/work/v1alpha1
# open-cluster-management.io/sdk-go v1.0.1-0.20251016065040-b82d34b3c2c2
# open-cluster-management.io/sdk-go v1.1.0
## explicit; go 1.24.0
open-cluster-management.io/sdk-go/pkg/apis/cluster/v1alpha1
open-cluster-management.io/sdk-go/pkg/apis/cluster/v1beta1

View File

@@ -185,21 +185,28 @@ func (c *addonRegistrationController) sync(ctx context.Context, syncCtx factory.
}
managedClusterAddonCopy.Status.Registrations = configs
var agentInstallNamespace string
// explicitly set the default namespace value, since the mca.spec.installNamespace is deprceated and
// the addonDeploymentConfig.spec.agentInstallNamespace could be empty
managedClusterAddonCopy.Status.Namespace = "open-cluster-management-agent-addon"
// Set the default namespace to registrationOption.Namespace
if len(registrationOption.Namespace) > 0 {
managedClusterAddonCopy.Status.Namespace = registrationOption.Namespace
}
if len(managedClusterAddonCopy.Spec.InstallNamespace) > 0 {
managedClusterAddonCopy.Status.Namespace = managedClusterAddonCopy.Spec.InstallNamespace
}
if registrationOption.AgentInstallNamespace != nil {
agentInstallNamespace, err = registrationOption.AgentInstallNamespace(managedClusterAddonCopy)
ns, err := registrationOption.AgentInstallNamespace(managedClusterAddonCopy)
if err != nil {
return err
}
}
// Set the default namespace to registrationOption.Namespace
managedClusterAddonCopy.Status.Namespace = registrationOption.Namespace
// Override if agentInstallNamespace or InstallNamespace is specified
if len(agentInstallNamespace) > 0 {
managedClusterAddonCopy.Status.Namespace = agentInstallNamespace
} else if len(managedClusterAddonCopy.Spec.InstallNamespace) > 0 {
managedClusterAddonCopy.Status.Namespace = managedClusterAddonCopy.Spec.InstallNamespace
// Override if agentInstallNamespace or InstallNamespace is specified
if len(ns) > 0 {
managedClusterAddonCopy.Status.Namespace = ns
}
}
meta.SetStatusCondition(&managedClusterAddonCopy.Status.Conditions, metav1.Condition{

View File

@@ -41,10 +41,12 @@ spec:
properties:
agentInstallNamespace:
default: open-cluster-management-agent-addon
description: AgentInstallNamespace is the namespace where the add-on
agent should be installed on the managed cluster.
description: |-
AgentInstallNamespace is the namespace where the add-on agent should be installed on the managed cluster.
For template-type addons: set to empty string "" to use the namespace defined in the addonTemplate.
For non-template addons: defaults to "open-cluster-management-agent-addon" if not specified.
maxLength: 63
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?)?$
type: string
customizedVariables:
description: |-

View File

@@ -54,10 +54,12 @@ type AddOnDeploymentConfigSpec struct {
ProxyConfig ProxyConfig `json:"proxyConfig,omitempty"`
// AgentInstallNamespace is the namespace where the add-on agent should be installed on the managed cluster.
// For template-type addons: set to empty string "" to use the namespace defined in the addonTemplate.
// For non-template addons: defaults to "open-cluster-management-agent-addon" if not specified.
// +optional
// +kubebuilder:default=open-cluster-management-agent-addon
// +kubebuilder:validation:MaxLength=63
// +kubebuilder:validation:Pattern=^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
// +kubebuilder:validation:Pattern=^([a-z0-9]([-a-z0-9]*[a-z0-9])?)?$
AgentInstallNamespace string `json:"agentInstallNamespace,omitempty"`
// ResourceRequirements specify the resources required by add-on agents.

View File

@@ -517,6 +517,12 @@ const (
// WorkManifestsComplete represents that all completable manifests in the work
// have the Complete condition
WorkManifestsComplete string = "ManifestsComplete"
// WorkProgressingReasonApplying indicates resources are being applied
WorkProgressingReasonApplying string = "Applying"
// WorkProgressingReasonCompleted indicates all resources are applied and available
WorkProgressingReasonCompleted string = "Completed"
// WorkProgressingReasonFailed indicates the work failed to apply
WorkProgressingReasonFailed string = "Failed"
)
// ManifestCondition represents the conditions of the resources deployed on a

View File

@@ -741,7 +741,7 @@ spec:
description: Summary totals of resulting ManifestWorks for the
placement
properties:
Applied:
applied:
description: 'Applied is the number of ManifestWorks with
condition Applied: true'
type: integer
@@ -763,7 +763,7 @@ spec:
summary:
description: Summary totals of resulting ManifestWorks for all placements
properties:
Applied:
applied:
description: 'Applied is the number of ManifestWorks with condition
Applied: true'
type: integer

View File

@@ -132,7 +132,7 @@ type ManifestWorkReplicaSetSummary struct {
// TODO: Degraded is the number of ManifestWorks with condition Degraded: true
Degraded int `json:"degraded"`
// Applied is the number of ManifestWorks with condition Applied: true
Applied int `json:"Applied"`
Applied int `json:"applied"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

View File

@@ -48,6 +48,8 @@ type baseClient struct {
}
func (c *baseClient) connect(ctx context.Context) error {
logger := klog.FromContext(ctx)
var err error
c.cloudEventsClient, err = c.newCloudEventsClient(ctx)
if err != nil {
@@ -58,7 +60,7 @@ func (c *baseClient) connect(ctx context.Context) error {
go func() {
for {
if !c.isClientReady() {
klog.V(4).Infof("reconnecting the cloudevents client")
logger.V(2).Info("reconnecting the cloudevents client")
c.cloudEventsClient, err = c.newCloudEventsClient(ctx)
// TODO enhance the cloudevents SKD to avoid wrapping the error type to distinguish the net connection
@@ -70,7 +72,7 @@ func (c *baseClient) connect(ctx context.Context) error {
continue
}
// the cloudevents network connection is back, mark the client ready and send the receiver restart signal
klog.V(4).Infof("the cloudevents client is reconnected")
logger.V(2).Info("the cloudevents client is reconnected")
increaseClientReconnectedCounter(c.clientID)
c.setClientReady(true)
c.sendReceiverSignal(restartReceiverSignal)
@@ -108,6 +110,7 @@ func (c *baseClient) connect(ctx context.Context) error {
}
func (c *baseClient) publish(ctx context.Context, evt cloudevents.Event) error {
logger := klog.FromContext(ctx)
now := time.Now()
if err := c.cloudEventsRateLimiter.Wait(ctx); err != nil {
@@ -116,8 +119,11 @@ func (c *baseClient) publish(ctx context.Context, evt cloudevents.Event) error {
latency := time.Since(now)
if latency > longThrottleLatency {
klog.Warningf("Waited for %v due to client-side throttling, not priority and fairness, request: %s",
latency, evt.Context)
logger.V(3).Info(
"Client-side throttling delay (not priority and fairness)",
"latency", latency,
"request", evt.Context.GetID(),
)
}
sendingCtx, err := c.cloudEventsOptions.WithContext(ctx, evt.Context)
@@ -129,8 +135,8 @@ func (c *baseClient) publish(ctx context.Context, evt cloudevents.Event) error {
return fmt.Errorf("the cloudevents client is not ready")
}
klog.V(4).Infof("Sending event: %v\n%s", sendingCtx, evt.Context)
klog.V(5).Infof("Sending event: evt=%s", evt)
logger.V(2).Info("Sending event", "context", sendingCtx, "event", evt.Context)
logger.V(5).Info("Sending event", "event", func() any { return evt.String() })
if err := c.cloudEventsClient.Send(sendingCtx, evt); cloudevents.IsUndelivered(err) {
return err
}
@@ -142,9 +148,10 @@ func (c *baseClient) subscribe(ctx context.Context, receive receiveFn) {
c.Lock()
defer c.Unlock()
logger := klog.FromContext(ctx)
// make sure there is only one subscription go routine starting for one client.
if c.receiverChan != nil {
klog.Warningf("the subscription has already started")
logger.V(2).Info("the subscription has already started")
return
}
@@ -159,8 +166,8 @@ func (c *baseClient) subscribe(ctx context.Context, receive receiveFn) {
if startReceiving {
go func() {
if err := c.cloudEventsClient.StartReceiver(receiverCtx, func(evt cloudevents.Event) {
klog.V(4).Infof("Received event: %s", evt.Context)
klog.V(5).Infof("Received event: evt=%s", evt)
logger.V(2).Info("Received event", "event", evt.Context)
logger.V(5).Info("Received event", "event", func() any { return evt.String() })
receive(receiverCtx, evt)
}); err != nil {
@@ -183,12 +190,12 @@ func (c *baseClient) subscribe(ctx context.Context, receive receiveFn) {
switch signal {
case restartReceiverSignal:
klog.V(4).Infof("restart the cloudevents receiver")
logger.V(2).Info("restart the cloudevents receiver")
// rebuild the receiver context and restart receiving
receiverCtx, receiverCancel = context.WithCancel(context.TODO())
startReceiving = true
case stopReceiverSignal:
klog.V(4).Infof("stop the cloudevents receiver")
logger.V(2).Info("stop the cloudevents receiver")
receiverCancel()
default:
runtime.HandleError(fmt.Errorf("unknown receiver signal %d", signal))