Skip to content

Commit

Permalink
[cni-cilium] New module (#592)
Browse files Browse the repository at this point in the history
Co-authored-by: Artem Kladov <artem.gen.kladov@gmail.com>
Co-authored-by: Yuriy Losev <yuriy.losev@flant.com>
Co-authored-by: Maksim Nabokikh <maksim.nabokikh@flant.com>
Co-authored-by: Artem Kladov <6360800+z9r5@users.noreply.github.com>
  • Loading branch information
5 people committed May 11, 2022
1 parent 3052371 commit 563808f
Show file tree
Hide file tree
Showing 111 changed files with 16,384 additions and 15 deletions.

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

20 changes: 20 additions & 0 deletions docs/documentation/_data/sidebars/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,26 @@ entries:
en: Other modules
ru: Другие модули
folders:
- title: cni-cilium
folders:
- title:
ru: Описание
en: Description
url: /modules/021-cni-cilium/
- title:
ru: Настройки
en: Configuration
url: /modules/021-cni-cilium/configuration.html
- title: cilium-hubble
folders:
- title:
ru: Описание
en: Description
url: /modules/500-cilium-hubble/
- title:
ru: Настройки
en: Configuration
url: /modules/500-cilium-hubble/configuration.html
- title: cni-flannel
folders:
- title:
Expand Down
76 changes: 68 additions & 8 deletions global-hooks/enable_cni.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,23 @@
package hooks

import (
"fmt"
"strconv"
"strings"

"github.com/flant/addon-operator/pkg/module_manager/go_hook"
"github.com/flant/addon-operator/sdk"
"github.com/flant/shell-operator/pkg/kube_events_manager/types"
v1core "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/utils/pointer"
)

var (
cniNameToModule = map[string]string{
"flannel": "cniFlannelEnabled",
"simple-bridge": "cniSimpleBridgeEnabled",
"cilium": "cniCiliumEnabled",
}
)

Expand All @@ -45,9 +51,48 @@ var _ = sdk.RegisterFunc(&go_hook.HookConfig{
},
FilterFunc: applyCniConfigFilter,
},
{
Name: "deckhouse_cm",
ApiVersion: "v1",
Kind: "ConfigMap",
NameSelector: &types.NameSelector{
MatchNames: []string{"deckhouse"},
},
NamespaceSelector: &types.NamespaceSelector{
NameSelector: &types.NameSelector{
MatchNames: []string{"d8-system"},
},
},
ExecuteHookOnEvents: pointer.BoolPtr(false),
ExecuteHookOnSynchronization: pointer.BoolPtr(false),
FilterFunc: applyD8CMFilter,
},
},
}, enableCni)

func applyD8CMFilter(obj *unstructured.Unstructured) (go_hook.FilterResult, error) {
var cm v1core.ConfigMap
err := sdk.FromUnstructured(obj, &cm)
if err != nil {
return "", err
}

cniMap := make(map[string]bool)

for k, v := range cm.Data {
// looking for keys like 'cniCiliumEnabled' or 'cniFlannelEnabled'
if strings.HasPrefix(k, "cni") && strings.HasSuffix(k, "Enabled") {
boolValue, err := strconv.ParseBool(v)
if err != nil {
return nil, fmt.Errorf("parse cni enable flag failed: %s", err)
}
cniMap[k] = boolValue
}
}

return cniMap, nil
}

func applyCniConfigFilter(obj *unstructured.Unstructured) (go_hook.FilterResult, error) {
var cm v1core.Secret
err := sdk.FromUnstructured(obj, &cm)
Expand All @@ -65,25 +110,40 @@ func applyCniConfigFilter(obj *unstructured.Unstructured) (go_hook.FilterResult,

func enableCni(input *go_hook.HookInput) error {
cniNameSnap := input.Snapshots["cni_name"]
deckhouseCMSnap := input.Snapshots["deckhouse_cm"]

if len(cniNameSnap) == 0 {
input.LogEntry.Warnln("Cni name not found")
return nil
}

cniToEnable := cniNameSnap[0].(string)
if _, ok := cniNameToModule[cniToEnable]; !ok {
input.LogEntry.Warnf("Incorrect cni name: '%v'. Skip", cniToEnable)
if len(deckhouseCMSnap) == 0 {
input.LogEntry.Warnln("Deckhouse CM not found")
return nil
}

for cniName, module := range cniNameToModule {
if cniToEnable == cniName {
input.Values.Set(module, true)
} else {
input.Values.Remove(module)
cmEnabledCNIs := make([]string, 0)
for cni, enabled := range deckhouseCMSnap[0].(map[string]bool) {
if enabled {
cmEnabledCNIs = append(cmEnabledCNIs, cni)
}
}

if len(cmEnabledCNIs) > 1 {
return fmt.Errorf("more then one CNI enabled: %v", cmEnabledCNIs)
} else if len(cmEnabledCNIs) == 1 {
input.LogEntry.Infof("enabled CNI from Deckhouse CM: %s", strings.TrimSuffix(cmEnabledCNIs[0], "Enabled"))
return nil
}

// nor any CNI enabled directly via CM, found default CNI from secret
cniToEnable := cniNameSnap[0].(string)
if _, ok := cniNameToModule[cniToEnable]; !ok {
input.LogEntry.Warnf("Incorrect cni name: '%v'. Skip", cniToEnable)
return nil
}

input.LogEntry.Infof("enabled CNI by secret: %s", cniToEnable)
input.Values.Set(cniNameToModule[cniToEnable], true)
return nil
}
4 changes: 2 additions & 2 deletions global-hooks/enable_cni_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ var _ = Describe("Global hooks :: enable_cni ::", func() {

It("Enables cni module "+module, func() {
Expect(f).To(ExecuteSuccessfully())
Expect(f.ValuesGet(module).Exists()).To(BeTrue())
Expect(f.ValuesGet(module).Exists()).To(BeFalse())
})

It("Disables another cni modules", func() {
Expand All @@ -104,7 +104,7 @@ var _ = Describe("Global hooks :: enable_cni ::", func() {

It("Does not change cni module", func() {
Expect(f).To(ExecuteSuccessfully())
Expect(f.ValuesGet(module).Exists()).To(BeTrue())
Expect(f.ValuesGet(module).Exists()).To(BeFalse())
})
})
}
Expand Down
8 changes: 8 additions & 0 deletions modules/021-cni-cilium/.helmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
images
hooks
openapi
crds
template_tests
enabled
README.md
candi
1 change: 1 addition & 0 deletions modules/021-cni-cilium/.namespace
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
d8-cni-cilium
2 changes: 2 additions & 0 deletions modules/021-cni-cilium/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
name: cni-cilium
version: 0.1.0
1 change: 1 addition & 0 deletions modules/021-cni-cilium/charts/helm_lib
185 changes: 185 additions & 0 deletions modules/021-cni-cilium/crds/ciliumbgploadbalancerippools.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@

---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
labels:
heritage: deckhouse
module: deckhouse
name: ciliumbgploadbalancerippools.cilium.io
spec:
group: cilium.io
names:
categories:
- cilium
- ciliumbgp
kind: CiliumBGPLoadBalancerIPPool
listKind: CiliumBGPLoadBalancerIPPoolList
plural: ciliumbgploadbalancerippools
shortNames:
- bgppools
singular: ciliumbgploadbalancerippool
scope: Cluster
versions:
- additionalPrinterColumns:
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v2alpha1
schema:
openAPIV3Schema:
description: CiliumBGPLoadBalancerIPPool is a Kubernetes third-party resource
which instructs the BGP control plane to allocate and advertise IPs for
Services of type LoadBalancer.
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 a human readable description for a BGP load balancer
ip pool.
properties:
default:
description: Default determines if this is the default IP pool for
allocating from when LBSelector is nil or empty.
type: boolean
lbSelector:
description: LBSelector will determine if a created LoadBalancer is
allocated an IP from this pool.
properties:
matchExpressions:
description: matchExpressions is a list of label selector requirements.
The requirements are ANDed.
items:
description: A label selector requirement is a selector that
contains values, a key, and an operator that relates the key
and values.
properties:
key:
description: key is the label key that the selector applies
to.
type: string
operator:
description: operator represents a key's relationship to
a set of values. Valid operators are In, NotIn, Exists
and DoesNotExist.
enum:
- In
- NotIn
- Exists
- DoesNotExist
type: string
values:
description: values is an array of string values. If the
operator is In or NotIn, the values array must be non-empty.
If the operator is Exists or DoesNotExist, the values
array must be empty. This array is replaced during a strategic
merge patch.
items:
type: string
type: array
required:
- key
- operator
type: object
type: array
matchLabels:
additionalProperties:
description: MatchLabelsValue represents the value from the
MatchLabels {key,value} pair.
maxLength: 63
pattern: ^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$
type: string
description: matchLabels is a map of {key,value} pairs. A single
{key,value} in the matchLabels map is equivalent to an element
of matchExpressions, whose key field is "key", the operator
is "In", and the values array contains only "value". The requirements
are ANDed.
type: object
type: object
nodeSelector:
description: "NodeSelector selects a group of nodes which will advertise
the presence of any LoadBalancers allocated from this IP pool. \n
If nil all nodes will advertise the presence of any LoadBalancer
allocated an IP from this pool."
properties:
matchExpressions:
description: matchExpressions is a list of label selector requirements.
The requirements are ANDed.
items:
description: A label selector requirement is a selector that
contains values, a key, and an operator that relates the key
and values.
properties:
key:
description: key is the label key that the selector applies
to.
type: string
operator:
description: operator represents a key's relationship to
a set of values. Valid operators are In, NotIn, Exists
and DoesNotExist.
enum:
- In
- NotIn
- Exists
- DoesNotExist
type: string
values:
description: values is an array of string values. If the
operator is In or NotIn, the values array must be non-empty.
If the operator is Exists or DoesNotExist, the values
array must be empty. This array is replaced during a strategic
merge patch.
items:
type: string
type: array
required:
- key
- operator
type: object
type: array
matchLabels:
additionalProperties:
description: MatchLabelsValue represents the value from the
MatchLabels {key,value} pair.
maxLength: 63
pattern: ^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$
type: string
description: matchLabels is a map of {key,value} pairs. A single
{key,value} in the matchLabels map is equivalent to an element
of matchExpressions, whose key field is "key", the operator
is "In", and the values array contains only "value". The requirements
are ANDed.
type: object
type: object
prefix:
description: The CIDR block of IPs to allocate from.
format: cidr
type: string
required:
- prefix
type: object
required:
- metadata
type: object
served: true
storage: true
subresources: {}
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []

0 comments on commit 563808f

Please sign in to comment.