Skip to content
Snippets Groups Projects
Commit a648394e authored by Alka Nixon's avatar Alka Nixon
Browse files

Add Neighbourhood CR creation and distribution logic with cluster removal and claim update handling

parent 7ac9099a
No related branches found
No related tags found
No related merge requests found
Showing
with 1384 additions and 357 deletions
......@@ -19,7 +19,7 @@
# Build the manager binary
ARG VERSION=1.22
FROM golang:${VERSION} as builder
FROM golang:${VERSION} AS builder
ARG TARGETOS
ARG TARGETARCH
......
......@@ -25,12 +25,22 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// Observed and Aggregated metrics from Codeco App Nodes
type ClusterClaim struct {
Name string `json:"name"`
Value string `json:"value"`
}
// ManagedClusterRef represents a reference to a managed cluster with its claims
type ManagedClusterRef struct {
Name string `json:"name"`
ClusterClaims []ClusterClaim `json:"clusterClaims,omitempty"`
}
type NeighbourhoodSpec struct {
// Neighbourhood name (unique, assigned by K8s)
NeighbourhoodName string `json:"neighbourhoodName,omitempty"`
ApplicationName string `json:"applicationName,omitempty"`
ManagedClusters []string `json:"managedClusters,omitempty"`
NeighbourhoodName string `json:"neighbourhoodName,omitempty"`
ApplicationName string `json:"applicationName,omitempty"`
ManagedClusters []ManagedClusterRef `json:"managedClusters,omitempty"`
// todo simple string list of managed cluster for now, replace with selector later}
//ManagedClusterSelector []ocmv1.ManagedClusterSelector `json:"managedClusters,omitempty"`
}
......
......@@ -42,6 +42,21 @@ func (in *ChannelSettings) DeepCopy() *ChannelSettings {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ClusterClaim) DeepCopyInto(out *ClusterClaim) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterClaim.
func (in *ClusterClaim) DeepCopy() *ClusterClaim {
if in == nil {
return nil
}
out := new(ClusterClaim)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CodecoApp) DeepCopyInto(out *CodecoApp) {
*out = *in
......@@ -217,6 +232,26 @@ func (in *CodecoChannels) DeepCopy() *CodecoChannels {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ManagedClusterRef) DeepCopyInto(out *ManagedClusterRef) {
*out = *in
if in.ClusterClaims != nil {
in, out := &in.ClusterClaims, &out.ClusterClaims
*out = make([]ClusterClaim, len(*in))
copy(*out, *in)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManagedClusterRef.
func (in *ManagedClusterRef) DeepCopy() *ManagedClusterRef {
if in == nil {
return nil
}
out := new(ManagedClusterRef)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Neighbourhood) DeepCopyInto(out *Neighbourhood) {
*out = *in
......@@ -281,8 +316,10 @@ func (in *NeighbourhoodSpec) DeepCopyInto(out *NeighbourhoodSpec) {
*out = *in
if in.ManagedClusters != nil {
in, out := &in.ManagedClusters, &out.ManagedClusters
*out = make([]string, len(*in))
copy(*out, *in)
*out = make([]ManagedClusterRef, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
......
This diff is collapsed.
......@@ -39,12 +39,35 @@ spec:
spec:
description: Observed and Aggregated metrics from Codeco App Nodes
properties:
applicationName:
type: string
managedClusters:
items:
type: string
description: ManagedClusterRef represents a reference to a managed
cluster with its claims
properties:
clusterClaims:
items:
description: ClusterClaim represents a claim about a managed
cluster
properties:
name:
type: string
value:
type: string
required:
- name
- value
type: object
type: array
name:
type: string
required:
- name
type: object
type: array
neighbourhoodName:
description: Node name (unique, assigned by K8s)
description: Neighbourhood name (unique, assigned by K8s)
type: string
type: object
status:
......
......@@ -22,6 +22,7 @@
# It should be run by config/default
resources:
- bases/codeco.he-codeco.eu_codecoapps.yaml
- bases/codeco.he-codeco.eu_neighbourhoods.yaml
#+kubebuilder:scaffold:crdkustomizeresource
patchesStrategicMerge:
......
apiVersion: cluster.open-cluster-management.io/v1alpha1
kind: ClusterClaim
metadata:
name: id.k8s.io
spec:
value: Cluster2
\ No newline at end of file
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: neighbourhood-access-binding
namespace: he-codeco-acm
subjects:
- kind: ServiceAccount
name: klusterlet-work-sa
namespace: open-cluster-management-agent
roleRef:
kind: Role
name: neighbourhood-access
apiGroup: rbac.authorization.k8s.io
\ No newline at end of file
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: neighbourhood-access
namespace: he-codeco-acm
rules:
- apiGroups: ["codeco.he-codeco.eu"]
resources: ["neighbourhoods"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
# Copyright (c) 2024 Red Hat, Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
# Contributors:
# [name] - [contribution]
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: neighbourhood-role
rules:
- apiGroups:
- codeco.he-codeco.eu
resources:
- neighbourhoods
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
\ No newline at end of file
# Copyright (c) 2024 Red Hat, Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
# Contributors:
# [name] - [contribution]
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: neighbourhood-role-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: neighbourhood-role
subjects:
- kind: ServiceAccount
name: acm-operator-controller-manager
namespace: he-codeco-acm
\ No newline at end of file
......@@ -54,9 +54,34 @@ rules:
resources:
- "placements"
- "placementdecisions"
- "managedclusters"
verbs: ["get", "list", "watch", "create"]
- apiGroups:
- cluster.open-cluster-management.io
resources:
- "managedclusters/status"
verbs: ["get"]
- apiGroups:
- work.open-cluster-management.io
resources: ["manifestworks"]
verbs: ["get", "list", "create", "update", "patch", "delete"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups:
- codeco.he-codeco.eu
resources:
- neighbourhoods
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- codeco.he-codeco.eu
resources:
- neighbourhoods/status
verbs:
- get
- update
- patch
......@@ -51,7 +51,6 @@ spec:
maxDelay: "1"
sendInterval: "10"
channelName: frontend
serviceClass: ASSURED
otherService:
appName: acm-swm-app
port: 9090
......@@ -73,7 +72,6 @@ spec:
maxDelay: "1"
sendInterval: "10"
channelName: backend
serviceClass: ASSURED
otherService:
appName: acm-swm-app
port: 8080
......
......@@ -20,11 +20,16 @@
apiVersion: codeco.he-codeco.eu/v1alpha1
kind: Neighbourhood
metadata:
generation: 1
name: neighbourhood_app1
name: neighbourhood-app1
namespace: he-codeco-acm
spec:
neighbourhoodName: "MyNeighbourhood"
managedClusters:
cluster1
cluster2
\ No newline at end of file
- name: cluster1
clusterClaims:
- name: id.k8s.io
value: cluster1-unique-id
- name: cluster2
clusterClaims:
- name: id.k8s.io
value: cluster2-unique-id
\ No newline at end of file
......@@ -50,7 +50,7 @@ import (
// CodecoAppReconciler reconciles a CodecoApp object
type CodecoAppReconciler struct {
client.Client
Scheme *runtime.Scheme
Scheme *runtime.Scheme
NeighbourhoodReconciler *NeighbourhoodReconciler
}
......@@ -386,7 +386,23 @@ func (r *CodecoAppReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
fmt.Println(time.Now().Format(time.UnixDate), "---------------------- Create Neighbourhood -----------------------")
// Function to create neighborhood whenever user deploys codecoapp
r.NeighbourhoodReconciler.CreateNeighbourhood(ctx, []string{"cluster1", "cluster2"}, codecoAppCR)
managedClusters := []codecov1alpha1.ManagedClusterRef{
{
Name: "cluster1",
ClusterClaims: []codecov1alpha1.ClusterClaim{
{Name: "id.k8s.io", Value: "cluster1-unique-id"},
},
},
{
Name: "cluster2",
ClusterClaims: []codecov1alpha1.ClusterClaim{
{Name: "id.k8s.io", Value: "cluster2-unique-id"},
},
},
}
m, err := r.NeighbourhoodReconciler.CreateNeighbourhood(ctx, managedClusters, codecoAppCR)
fmt.Println(m, err)
fmt.Println(time.Now().Format(time.UnixDate), "---------------------- Initialize SWM App -----------------------")
qos_scheduler_app := &swmv1alpha1.Application{}
......@@ -449,7 +465,7 @@ func (r *CodecoAppReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
qos_scheduler_new_application_group.Spec = swmv1alpha1.ApplicationGroupSpec{}
err := r.Get(ctx, client.ObjectKey{Namespace: codecoAppCR.Namespace, Name: "acm-applicationgroup"}, qos_scheduler_new_application_group)
err = r.Get(ctx, client.ObjectKey{Namespace: codecoAppCR.Namespace, Name: "acm-applicationgroup"}, qos_scheduler_new_application_group)
if err != nil {
if errors.IsNotFound(err) {
fmt.Println("Creating new SWM application group")
......
This diff is collapsed.
......@@ -32,6 +32,8 @@ import (
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
_ "k8s.io/client-go/plugin/pkg/client/auth"
clusterv1 "open-cluster-management.io/api/cluster/v1"
workv1 "open-cluster-management.io/api/work/v1"
swmApi "siemens.com/qos-scheduler/api/v1alpha1"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/healthz"
......@@ -49,6 +51,8 @@ func init() {
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
utilruntime.Must(codecov1alpha1.AddToScheme(scheme))
utilruntime.Must(swmApi.AddToScheme(scheme))
utilruntime.Must(workv1.AddToScheme(scheme))
utilruntime.Must(clusterv1.AddToScheme(scheme))
//utilruntime.Must(neighbourhoodApi.AddToScheme(scheme))
monitoringv1.AddToScheme(scheme)
......@@ -96,14 +100,25 @@ func main() {
os.Exit(1)
}
if err = (&controllers.CodecoAppReconciler{
nr := &controllers.NeighbourhoodReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
}
if err = (&controllers.CodecoAppReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
NeighbourhoodReconciler: nr,
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "CodecoApp")
os.Exit(1)
}
if err = nr.SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "Neighbourhood")
os.Exit(1)
}
//+kubebuilder:scaffold:builder
if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment