profile
viewpoint

open-cluster-management-io/api 179

Core APIs for open cluster management

open-cluster-management-io/community 42

open-cluster-management governance material.

gyliu513/roadmap 14

Daily Work

open-cluster-management-io/placement 13

Controller to make placement decisions based on Placement APIs

open-cluster-management-io/enhancements 7

Maintain design docs for core apis and components.

gyliu513/dcos-ui 1

The UI for The Datacenter Operating System

qiujian16/kcp-ocm 1

kcp ocm integration

chenzhiwei/ingress-nginx 0

Ingress controller for nginx

Pull request review commentopen-cluster-management-io/addon-framework

implement an addon using helm chart

+package helmaddonfactory++import (+	"fmt"++	"helm.sh/helm/v3/pkg/chart"+	"helm.sh/helm/v3/pkg/chartutil"+	"helm.sh/helm/v3/pkg/engine"+	"k8s.io/apimachinery/pkg/runtime"+	"k8s.io/apimachinery/pkg/runtime/serializer"+	"k8s.io/klog/v2"+	"open-cluster-management.io/addon-framework/pkg/agent"+	addonapiv1alpha1 "open-cluster-management.io/api/addon/v1alpha1"+	clusterv1 "open-cluster-management.io/api/cluster/v1"+)++// the annotation Name of customized chart values+const annotationValuesName string = "addon.open-cluster-management.io/helmchart-values"++// the build-in values+const (+	clusterName           string = "clusterName"+	addonInstallNamespace string = "addonInstallNamespace"+	hubKubeConfigSecret   string = "hubKubeConfigSecret"+)++type Values map[string]interface{}++type GetValuesFunc func(cluster *clusterv1.ManagedCluster,+	addon *addonapiv1alpha1.ManagedClusterAddOn) (Values, error)++type HelmAgentAddon struct {+	decoder           runtime.Decoder+	chart             *chart.Chart+	getValuesFuncs    []GetValuesFunc+	agentAddonOptions agent.AgentAddonOptions+}++func newHelmAgentAddon(+	scheme *runtime.Scheme,+	chart *chart.Chart,+	getValuesFuncs []GetValuesFunc,+	agentAddonOptions agent.AgentAddonOptions) *HelmAgentAddon {+	return &HelmAgentAddon{+		decoder:           serializer.NewCodecFactory(scheme).UniversalDeserializer(),+		chart:             chart,+		getValuesFuncs:    getValuesFuncs,+		agentAddonOptions: agentAddonOptions}+}++func (a *HelmAgentAddon) Manifests(+	cluster *clusterv1.ManagedCluster,+	addon *addonapiv1alpha1.ManagedClusterAddOn) ([]runtime.Object, error) {+	var objects []runtime.Object++	values, err := a.getValues(cluster, addon)+	if err != nil {+		return objects, err+	}++	helmEngine := engine.Engine{+		Strict:   true,+		LintMode: false,+	}++	crds := a.chart.CRDObjects()+	for _, crd := range crds {+		klog.V(4).Infof("%v/n", crd.File.Data)+		object, _, err := a.decoder.Decode(crd.File.Data, nil, nil)+		if err != nil {+			return nil, err+		}+		objects = append(objects, object)+	}++	templates, err := helmEngine.Render(a.chart, values)+	if err != nil {+		return objects, err+	}+	for _, data := range templates {+		if len(data) == 0 {+			continue+		}+		klog.V(4).Infof("%v/n", data)+		object, _, err := a.decoder.Decode([]byte(data), nil, nil)+		if err != nil {+			return nil, err+		}+		objects = append(objects, object)+	}++	return objects, nil+}++func (a *HelmAgentAddon) GetAgentAddonOptions() agent.AgentAddonOptions {+	return a.agentAddonOptions+}++func (a *HelmAgentAddon) getValues(+	cluster *clusterv1.ManagedCluster,+	addon *addonapiv1alpha1.ManagedClusterAddOn) (chartutil.Values, error) {+	overrideValues := map[string]interface{}{}++	for i := 0; i < len(a.getValuesFuncs); i++ {+		if a.getValuesFuncs[i] != nil {+		}+		userValues, err := a.getValuesFuncs[i](cluster, addon)+		if err != nil {+			return overrideValues, err+		}+		overrideValues = MergeValues(overrideValues, userValues)+	}++	overrideValues = MergeValues(overrideValues, a.getBuildInValues(cluster, addon))++	values, err := chartutil.ToRenderValues(a.chart, overrideValues,+		a.releaseOptions(cluster, addon), a.capabilities(cluster, addon))+	if err != nil {+		klog.Error("failed to render helm chart with values %v. err:%v", overrideValues, err)+		return values, err+	}++	return values, nil+}++func (a *HelmAgentAddon) getBuildInValues(

BuiltIn

zhiweiyin318

comment created time in 2 days

Pull request review commentopen-cluster-management-io/addon-framework

implement an addon using helm chart

+package main+

can we just build a common helloworld agent? It seems each example shows the same agent.

zhiweiyin318

comment created time in 2 days

PullRequestReviewEvent
PullRequestReviewEvent

Pull request review commentopen-cluster-management-io/addon-framework

implement an addon using helm chart

+# Overview+This doc is used to introduce how to migrate Helm Chart to an Addon.++## Limitations+1. Not all of build-in Objects of Helm Chart are support in Addon. We only support below:+* Capabilities.KubeVersion+* Release.Name+* Release.Namespace++2. Not support Hooks of Helm Chart currently.++## Migration +We have an example for Helm Chart migration in [helloworld_helm](../examples/helloworld_helm).+1. Copy your helm charts into repo.

I think you would need to import this into embed.FS

zhiweiyin318

comment created time in 2 days

Pull request review commentopen-cluster-management-io/addon-framework

implement an addon using helm chart

+# Overview+This doc is used to introduce how to migrate Helm Chart to an Addon.++## Limitations+1. Not all of build-in Objects of Helm Chart are support in Addon. We only support below:+* Capabilities.KubeVersion+* Release.Name+* Release.Namespace++2. Not support Hooks of Helm Chart currently.++## Migration +We have an example for Helm Chart migration in [helloworld_helm](../examples/helloworld_helm).+1. Copy your helm charts into repo.+2. Create and start helmAgentAddon instance like this:+   ```goZ

rm Z

zhiweiyin318

comment created time in 2 days

Pull request review commentopen-cluster-management-io/addon-framework

implement an addon using helm chart

+package helmaddonfactory++import (+	"embed"+	"io/fs"+	"path/filepath"+	"strings"++	"helm.sh/helm/v3/pkg/chart"+	"helm.sh/helm/v3/pkg/chart/loader"+	apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"+	apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"+	"k8s.io/apimachinery/pkg/runtime"+	"k8s.io/client-go/kubernetes/scheme"+	"k8s.io/klog/v2"+	"open-cluster-management.io/addon-framework/pkg/agent"+)++const AddonDefaultInstallNamespace = "open-cluster-management-agent-addon"++// HelmAgentAddonFactory builds an agentAddon instance from helm chart.+type HelmAgentAddonFactory struct {+	scheme            *runtime.Scheme+	chartPrefix       string+	chartFS           embed.FS+	getValuesFuncs    []GetValuesFunc+	agentAddonOptions agent.AgentAddonOptions+}++// NewAgentAddonFactoryWithHelmChartFS builds an addon agent with chart fs.+// chartPrefix is the path prefix based on the fs path.+func NewAgentAddonFactoryWithHelmChartFS(addonName string, fs embed.FS, chartPrefix string) *HelmAgentAddonFactory {+	return &HelmAgentAddonFactory{+		chartFS:     fs,+		chartPrefix: chartPrefix,+		agentAddonOptions: agent.AgentAddonOptions{+			AddonName:       addonName,+			Registration:    nil,+			InstallStrategy: nil,+		},+	}+}++// WithScheme is an optional configuration, only used when the helm chart has customized resource types.+func (f *HelmAgentAddonFactory) WithScheme(scheme *runtime.Scheme) *HelmAgentAddonFactory {+	f.scheme = scheme+	return f+}++// WithGetValuesFuncs adds a list of the getValues func.+// the values got from the big index Func will override the one from small index Func.+func (f *HelmAgentAddonFactory) WithGetValuesFuncs(getValuesFuncs []GetValuesFunc) *HelmAgentAddonFactory {+	f.getValuesFuncs = getValuesFuncs+	return f+}++// WithInstallStrategy defines the installation strategy of the manifests prescribed by Manifests(..).+func (f *HelmAgentAddonFactory) WithInstallStrategy(strategy *agent.InstallStrategy) *HelmAgentAddonFactory {+	if strategy.InstallNamespace == "" {+		strategy.InstallNamespace = AddonDefaultInstallNamespace+	}+	f.agentAddonOptions.InstallStrategy = strategy++	return f+}++// WithAgentRegistrationOption defines how agent is registered to the hub cluster.+func (f *HelmAgentAddonFactory) WithAgentRegistrationOption(option *agent.RegistrationOption) *HelmAgentAddonFactory {+	f.agentAddonOptions.Registration = option+	return f+}++// Build creates a new agentAddon.+func (f *HelmAgentAddonFactory) Build() (agent.AgentAddon, error) {+	if f.scheme == nil {+		f.scheme = runtime.NewScheme()+		_ = scheme.AddToScheme(f.scheme)+		_ = apiextensionsv1.AddToScheme(f.scheme)+		_ = apiextensionsv1beta1.AddToScheme(f.scheme)+	}++	//	chart, err := loader.Load(f.chartPath)+	userChart, err := f.loadChart()+	if err != nil {+		return nil, err+	}+	// TODO: validate chart+	agentAddon := newHelmAgentAddon(f.scheme, userChart, f.getValuesFuncs, f.agentAddonOptions)++	return agentAddon, nil+}++func (f *HelmAgentAddonFactory) loadChart() (*chart.Chart, error) {+	files, err := f.getChartFiles()+	if err != nil {+		return nil, err+	}++	klog.Info(files)++	var bfs []*loader.BufferedFile+	for _, fileName := range files {+		b, err := fs.ReadFile(f.chartFS, fileName)+		if err != nil {+			klog.Errorf("failed to read file %v. err:%v", fileName, err)+			return nil, err+		}+		klog.Info(fileName)+		bf := &loader.BufferedFile{+			Name: f.stripPrefix(fileName),+			Data: b,+		}+		bfs = append(bfs, bf)+	}++	userChart, err := loader.LoadFiles(bfs)+	if err != nil {+		klog.Errorf("failed to load chart. err:%v", err)+		return nil, err+	}+	klog.Info(userChart.ChartPath())

do you need these Info?

zhiweiyin318

comment created time in 2 days

pull request commentopenshift/release

rename to stolostron

/lgtm

skeeey

comment created time in 2 days

pull request commentopen-cluster-management-io/clusteradm

modify integration test for command addon enable

/approve /lgtm

thanks merge this to ensure we have a passed test.

ycyaoxdu

comment created time in 2 days

push eventqiujian16/work

Jian Qiu

commit sha 07816b841183b973ccad7094112543f68e87f099

Update go to 1.17 Signed-off-by: Jian Qiu <jqiu@redhat.com>

view details

push time in 2 days

PullRequestReviewEvent

Pull request review commentopen-cluster-management-io/open-cluster-management-io.github.io

replace word master with main

 the two models we will be frequently using throughout the world of OCM:   the hub cluster and consistently reconciles the physical Kubernetes cluster   to the expected state.   -### "Master-agent" architecture+### "Main-agent" architecture

hub-agent

xuezhaojun

comment created time in 2 days

PullRequestReviewEvent

push eventqiujian16/work

Jian Qiu

commit sha 127c4d7cb81065bd39fe2f9c5860697f576ce0fa

Update go to 1.17 Signed-off-by: Jian Qiu <jqiu@redhat.com>

view details

push time in 2 days

pull request commentopen-cluster-management-io/api

Add PlacementConditionMisconfigured

/approve /lgtm

haoqing0110

comment created time in 2 days

pull request commentopen-cluster-management-io/work

Update go to 1.17

/hold

qiujian16

comment created time in 2 days

PR opened open-cluster-management-io/work

Update go to 1.17

Signed-off-by: Jian Qiu jqiu@redhat.com

+89348 -16336

0 comment

1201 changed files

pr created time in 2 days

create barnchqiujian16/work

branch : upgrade-go

created branch time in 2 days

pull request commentopen-cluster-management-io/registration

Update builder image

/assign @skeeey

qiujian16

comment created time in 2 days

create barnchqiujian16/registration

branch : update-dockerfile

created branch time in 2 days

Pull request review commentopen-cluster-management-io/registration-operator

add nil check for nil clients in helper

 require ( 	github.com/onsi/gomega v1.10.1 	github.com/openshift/api v0.0.0-20210331193751-3acddb19d360 	github.com/openshift/build-machinery-go v0.0.0-20211213093930-7e33a7eb4ce3-	github.com/openshift/library-go v0.0.0-20210406144447-d9cdfbd844ea+	github.com/openshift/library-go v0.0.0-20210401181443-5cf97eb29077

why we use a lower version of library-go?

xuezhaojun

comment created time in 2 days

PullRequestReviewEvent

Pull request review commentopen-cluster-management-io/work

Add interested field

 func (c *AvailableStatusController) syncManifestWork(ctx context.Context, origin  	needStatusUpdate := false 	// handle status condition of manifests+	// TODO revist this controller since this might bring races when user change the manifests in spec. 	for index, manifest := range manifestWork.Status.ResourceStatus.Manifests {-		availableStatusCondition := buildAvailableStatusCondition(manifest.ResourceMeta, c.spokeDynamicClient)+		obj, availableStatusCondition := buildAvailableStatusCondition(manifest.ResourceMeta, c.spokeDynamicClient) 		newConditions := helper.MergeStatusConditions(manifest.Conditions, []metav1.Condition{availableStatusCondition})-		if !reflect.DeepEqual(manifestWork.Status.ResourceStatus.Manifests[index].Conditions, newConditions) {+		if !equality.Semantic.DeepEqual(manifestWork.Status.ResourceStatus.Manifests[index].Conditions, newConditions) { 			manifestWork.Status.ResourceStatus.Manifests[index].Conditions = newConditions 			needStatusUpdate = true 		}++		values, err := c.getFeedbackValues(manifest.ResourceMeta, obj, manifestWork.Spec.ManifestConfigs)

yeah, there is good/bad to have such informers. given the current informer filtering mechanism. We might monitor a lot of unrelated resource on the spoke. It would be quite costly on a large spoke I think.

qiujian16

comment created time in 2 days

PullRequestReviewEvent

push eventqiujian16/work

Jian Qiu

commit sha 7e919368b0295d5ef1752b1e56675b05d3217ee5

Resolve comments Signed-off-by: Jian Qiu <jqiu@redhat.com>

view details

push time in 2 days

Pull request review commentAzure/multi-cluster-networking

push model one pager

+# Push based Fleet Management Design++The proposed work would support our initial push based fleet management solution in a way that is compatible with the pull model used in OCM.+++## Motivation++Currently, the open cluster management default solution requires the user to install multiple controllers in both the hub and the +member cluster. The member clusters join the hub cluster through a CertificateSigningRequest,+and it also requires the hub controller to accept before the member cluster mark itself as joined.+While this is a more secure approach and scale better, the initial setup can be a little daunting for a casual user to give our solution a try.+Therefore, we are proposing to simplify the overall architecture in our initial open source solution to only support push model.++This ability will bring some additional possible benefits:++* The hub cluster controller can directly pull the status of any object it applies to the member cluster. +Thus, we can get a single panel view of any distributed resources.+* This setup matches well with managed/hosted hub clusters where they are hosted in a cloud provider's private virtual network +while the member clusters are running in the user space. +* This setup can also address the problem that some users cannot run CertificateSigningRequest(CSR) in their environment.++### Goals++* Design the CRD of the push based managedCluster and functionality of its controller+* Support as much existing functionalities of the OCM as possible++### Non-Goals++* Support running managed controllers outside the hub/member cluster+* Authenticate managed cluster without using CSR(CertificateSigningRequest) in the original pull model.++## Proposal++With the push based approach, we simplified the architect of a fleet to only have one controller, sitting in the hub cluster,+that manages the fleet membership and work/policy distribution. Luckily, there is an existing CRD called `ManagedCluster` +in OCM that provides (almost) all the necessary information. In this design, we propose to reuse this customer resource as +is in the push model.++However, in order to differentiate from the existing pull based model, we will implement a new controller to watch the `ManagedCluster` custom resources.+In this way, we can start our project with a clean sheet but still keep compatible with most the existing OCM solutions. ++### API Design+Just to make this document more self-contained. Here I paste the golang definition of the `ManagedCluster` CRD spec.++```golang++type ManagedClusterSpec struct {+	// +optional+	ManagedClusterClientConfigs []ClientConfig `json:"managedClusterClientConfigs,omitempty"`++	// +required+	HubAcceptsClient bool `json:"hubAcceptsClient"`++	// +optional+	LeaseDurationSeconds int32 `json:"leaseDurationSeconds,omitempty"`+}++// TODO: we can add the cert information here so we don't need a kubeconfig+type ClientConfig struct {+    // URL is the URL of apiserver endpoint of the managed cluster.+    // +required+    URL string `json:"url"`++    // CABundle is the ca bundle to connect to apiserver of the managed cluster.+    // System certs are used if it is not set.+    // +optional+    CABundle []byte `json:"caBundle,omitempty"`+}++// ManagedClusterStatus represents the current status of joined managed cluster.+type ManagedClusterStatus struct {+    // Conditions contains the different condition statuses for this managed cluster.+    Conditions []metav1.Condition `json:"conditions"`+    +    // Capacity represents the total resource capacity from all nodeStatuses+    // on the managed cluster.+    Capacity ResourceList `json:"capacity,omitempty"`+    +    // Allocatable represents the total allocatable resources on the managed cluster.+    Allocatable ResourceList `json:"allocatable,omitempty"`+    +    // Version represents the kubernetes version of the managed cluster.+    Version ManagedClusterVersion `json:"version,omitempty"`+    +    // +optional+    ClusterClaims []ManagedClusterClaim `json:"clusterClaims,omitempty"`+}++type ManagedClusterClaim struct {+    // Name is the name of a ClusterClaim resource on managed cluster. It's a well known+    // or customized name to identify the claim.+    Name string `json:"name,omitempty"`+    +    // Value is a claim-dependent string+    Value string `json:"value,omitempty"`+}++// ResourceList defines a map for the quantity of different resources, the definition+// matches the ResourceList defined in k8s.io/api/core/v1.+type ResourceList map[ResourceName]resource.Quantity++```++### Design details+Here is how we handle the following functionalities in the OCM in our new controller. The overall idea is that +a `managedCluster` CR represents a member cluster. A cluster joins the fleet when a corresponding `managedCluster` CR is+successfully applied to the hub cluster. Similarly, a member cluster leaves the hub cluster when its corresponding +`managedCluster` CR is removed from the cluster. ++#### Join a member cluster to the fleet

it might not need registration process for cluster, but i think you probably still need registration process for addon. For example, an addon that needs to run on the spoke but needs to talk to hub apiserver.

ryanzhang-oss

comment created time in 2 days

more