Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions assets/components/c2cc/clusterrole.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: microshift-c2cc-probe
rules:
- apiGroups:
- microshift.io
resources:
- remoteclusters
verbs:
- get
- list
- watch
- apiGroups:
- microshift.io
resources:
- remoteclusters/status
verbs:
- update
- patch
- apiGroups:
- security.openshift.io
resources:
- securitycontextconstraints
verbs:
- use
resourceNames:
- privileged
12 changes: 12 additions & 0 deletions assets/components/c2cc/clusterrolebinding.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: microshift-c2cc-probe
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: microshift-c2cc-probe
subjects:
- kind: ServiceAccount
namespace: openshift-c2cc
name: c2cc-probe
68 changes: 68 additions & 0 deletions assets/components/c2cc/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: openshift-c2cc
name: c2cc-probe
labels:
app: c2cc-probe
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: c2cc-probe
template:
metadata:
labels:
app: c2cc-probe
annotations:
target.workload.openshift.io/management: '{"effect": "PreferredDuringScheduling"}'
openshift.io/required-scc: privileged
spec:
serviceAccountName: c2cc-probe
containers:
- name: c2cc-probe
image: '{{ .ReleaseImage.cli }}'
imagePullPolicy: IfNotPresent
command:
- /host/usr/bin/microshift
- c2cc-probe
ports:
- containerPort: 8080
name: probe
protocol: TCP
livenessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 10
periodSeconds: 10
Comment thread
pmtk marked this conversation as resolved.
resources:
requests:
cpu: 50m
memory: 64Mi
volumeMounts:
- name: microshift-binary
mountPath: /host/usr/bin/microshift
readOnly: true
volumes:
- name: microshift-binary
hostPath:
path: /usr/bin/microshift
type: File
nodeSelector:
node-role.kubernetes.io/master: ""
priorityClassName: system-cluster-critical
tolerations:
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
Comment thread
pmtk marked this conversation as resolved.
- key: node.kubernetes.io/unreachable
operator: Exists
effect: NoExecute
tolerationSeconds: 120
- key: node.kubernetes.io/not-ready
operator: Exists
effect: NoExecute
tolerationSeconds: 120
11 changes: 11 additions & 0 deletions assets/components/c2cc/namespace.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: v1
kind: Namespace
metadata:
name: openshift-c2cc
labels:
pod-security.kubernetes.io/enforce: privileged
pod-security.kubernetes.io/audit: privileged
pod-security.kubernetes.io/warn: privileged
annotations:
openshift.io/node-selector: ""
workload.openshift.io/allowed: "management"
14 changes: 14 additions & 0 deletions assets/components/c2cc/service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
apiVersion: v1
kind: Service
metadata:
namespace: openshift-c2cc
name: c2cc-probe
spec:
clusterIP: '{{ .ProbeServiceClusterIP }}'
ports:
- name: probe
port: 8080
targetPort: 8080
protocol: TCP
selector:
app: c2cc-probe
5 changes: 5 additions & 0 deletions assets/components/c2cc/serviceaccount.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
apiVersion: v1
kind: ServiceAccount
metadata:
namespace: openshift-c2cc
name: c2cc-probe
24 changes: 22 additions & 2 deletions assets/crd/microshift.io_remoteclusters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,28 @@ spec:
- probeTarget
type: object
status:
description: RemoteClusterStatus is populated by the probe pod in a future
ticket.
description: RemoteClusterStatus is populated by the probe pod with health
probe results.
properties:
errors:
items:
type: string
type: array
lastProbeTime:
format: date-time
type: string
lastSuccessfulProbe:
format: date-time
type: string
state:
default: NeverProbed
enum:
- NeverProbed
- Healthy
- Unhealthy
type: string
required:
- state
type: object
required:
- spec
Expand Down
1 change: 1 addition & 0 deletions cmd/microshift/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,6 @@ func newCommand() *cobra.Command {
cmd.AddCommand(cmds.NewRestoreCommand())
cmd.AddCommand(cmds.NewHealthcheckCommand())
cmd.AddCommand(cmds.NewAddNodeCommand())
cmd.AddCommand(cmds.NewC2CCProbeCommand())
return cmd
}
14 changes: 12 additions & 2 deletions pkg/apis/microshift/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,18 @@ type RemoteClusterSpec struct {
ProbeInterval metav1.Duration `json:"probeInterval"`
}

// RemoteClusterStatus is populated by the probe pod in a future ticket.
type RemoteClusterStatus struct{}
// RemoteClusterStatus is populated by the probe pod with health probe results.
type RemoteClusterStatus struct {
// +kubebuilder:validation:Enum=NeverProbed;Healthy;Unhealthy
// +kubebuilder:default="NeverProbed"
State string `json:"state"`
// +optional
LastSuccessfulProbe *metav1.Time `json:"lastSuccessfulProbe,omitempty"`
// +optional
LastProbeTime *metav1.Time `json:"lastProbeTime,omitempty"`
// +optional
Errors []string `json:"errors,omitempty"`
}

// +kubebuilder:object:root=true
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
Expand Down
15 changes: 14 additions & 1 deletion pkg/apis/microshift/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions pkg/cmd/c2cc_probe.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package cmd

import (
"github.com/openshift/microshift/pkg/controllers/c2cc"
"github.com/spf13/cobra"
)

func NewC2CCProbeCommand() *cobra.Command {
return &cobra.Command{
Use: "c2cc-probe",
Short: "Run C2CC remote cluster probe (designed to run as a pod)",
Hidden: true,
RunE: func(cmd *cobra.Command, _ []string) error {
return c2cc.RunProbe(cmd.Context())
},
}
}
10 changes: 10 additions & 0 deletions pkg/controllers/c2cc/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ func (c *C2CCRouteManager) fullReconcile(ctx context.Context) {
{"service-routes", c.svcRoutes.reconcile},
{"nftables", c.nftMgr.reconcile},
{"healthcheck-crs", c.healthcheck.reconcile},
{"probe-deployment", c.deployProbe},
}
for _, s := range subsystems {
if err := s.fn(ctx); err != nil {
Expand Down Expand Up @@ -258,6 +259,15 @@ func (c *C2CCRouteManager) cleanupAll(ctx context.Context) {
if c.nftMgr != nil {
cleanups = append(cleanups, cleanable{"nftables", c.nftMgr.cleanup})
}
cleanups = append(cleanups, cleanable{"probe-namespace", func(ctx context.Context) error {
return assets.DeleteNamespaces(ctx, c2ccNamespace, c.kubeconfig)
}})
cleanups = append(cleanups, cleanable{"probe-clusterrolebinding", func(ctx context.Context) error {
return assets.DeleteClusterRoleBindings(ctx, c2ccClusterRoleBinding, c.kubeconfig)
}})
cleanups = append(cleanups, cleanable{"probe-clusterrole", func(ctx context.Context) error {
return assets.DeleteClusterRoles(ctx, c2ccClusterRole, c.kubeconfig)
}})
cleanups = append(cleanups, cleanable{"healthcheck-crd", func(ctx context.Context) error {
return assets.DeleteCRDs(ctx, healthcheckCRD, c.kubeconfig)
}})
Expand Down
73 changes: 73 additions & 0 deletions pkg/controllers/c2cc/deploy_probe.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package c2cc

import (
"bytes"
"context"
"fmt"
"net"
"text/template"

"github.com/apparentlymart/go-cidr/cidr"
"github.com/openshift/microshift/pkg/assets"
"github.com/openshift/microshift/pkg/release"
"k8s.io/klog/v2"
)

var (
c2ccNamespace = []string{"components/c2cc/namespace.yaml"}
c2ccServiceAccount = []string{"components/c2cc/serviceaccount.yaml"}
c2ccClusterRole = []string{"components/c2cc/clusterrole.yaml"}
c2ccClusterRoleBinding = []string{"components/c2cc/clusterrolebinding.yaml"}
c2ccDeployment = []string{"components/c2cc/deployment.yaml"}
c2ccService = []string{"components/c2cc/service.yaml"}
)

func (c *C2CCRouteManager) deployProbe(ctx context.Context) error {
_, svcNet, err := net.ParseCIDR(c.cfg.Network.ServiceNetwork[0])
if err != nil {
return fmt.Errorf("failed to parse local service network: %w", err)
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
probeIP, err := cidr.Host(svcNet, 11)
if err != nil {
return fmt.Errorf("failed to compute probe service ClusterIP: %w", err)
}

params := assets.RenderParams{
"ReleaseImage": release.Image,
"ProbeServiceClusterIP": probeIP.String(),
}

if err := assets.ApplyNamespaces(ctx, c2ccNamespace, c.kubeconfig); err != nil {
return fmt.Errorf("failed to apply c2cc namespace: %w", err)
}
if err := assets.ApplyServiceAccounts(ctx, c2ccServiceAccount, c.kubeconfig); err != nil {
return fmt.Errorf("failed to apply c2cc service account: %w", err)
}
if err := assets.ApplyClusterRoles(ctx, c2ccClusterRole, c.kubeconfig); err != nil {
return fmt.Errorf("failed to apply c2cc cluster role: %w", err)
}
if err := assets.ApplyClusterRoleBindings(ctx, c2ccClusterRoleBinding, c.kubeconfig); err != nil {
return fmt.Errorf("failed to apply c2cc cluster role binding: %w", err)
}
if err := assets.ApplyDeployments(ctx, c2ccDeployment, renderTemplate, params, c.kubeconfig); err != nil {
return fmt.Errorf("failed to apply c2cc deployment: %w", err)
}
if err := assets.ApplyServices(ctx, c2ccService, renderTemplate, params, c.kubeconfig); err != nil {
return fmt.Errorf("failed to apply c2cc service: %w", err)
}

klog.V(4).Infof("C2CC probe assets deployed (probe ClusterIP=%s)", probeIP)
return nil
}

func renderTemplate(tb []byte, data assets.RenderParams) ([]byte, error) {
tmpl, err := template.New("").Option("missingkey=error").Parse(string(tb))
if err != nil {
return nil, err
}
var buf bytes.Buffer
if err := tmpl.Execute(&buf, data); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
Loading