Skip to content

Commit

Permalink
Extend kubectl output (#59)
Browse files Browse the repository at this point in the history
  • Loading branch information
jgomezve authored Jun 1, 2022
1 parent 1e4da15 commit 72f56d4
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 68 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -286,8 +286,8 @@ spec:

```
$ kubectl get segmentationpolicies
NAME AGE
segpol1 22s
NAME NAMESPACES RULES STATE AGE
segpol1 ns1, ns2 ip-tcp-443 Enforced 20s
```

* The Kubernetes Operator configures the following Objects/Relationship on the APIC Controller
Expand Down
10 changes: 8 additions & 2 deletions api/v1alpha1/segmentationpolicy_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,20 @@ type RuleSpec struct {

// SegmentationPolicyStatus defines the observed state of SegmentationPolicy
type SegmentationPolicyStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file
Namespaces string `json:"namespaces"`
Rules string `json:"rules"`
State string `json:"state"`
}

//+kubebuilder:object:root=true
//+kubebuilder:printcolumn:name="Namespaces",type="string",JSONPath=".status.namespaces",description="Namespaces"
//+kubebuilder:printcolumn:name="Rules",type="string",JSONPath=".status.rules",description="Rules"
//+kubebuilder:printcolumn:name="State",type="string",JSONPath=".status.state",description="APIC Objects state"
//+kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
//+kubebuilder:resource:shortName=segpol
//+kubebuilder:subresource:status

// Group is the Schema for the groups API
// SegmentationPolicy is the Schema for the segmentationpolicies API
type SegmentationPolicy struct {
metav1.TypeMeta `json:",inline"`
Expand Down
33 changes: 30 additions & 3 deletions config/crd/bases/apic.aci.cisco_segmentationpolicies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,27 @@ spec:
singular: segmentationpolicy
scope: Namespaced
versions:
- name: v1alpha1
- additionalPrinterColumns:
- description: Namespaces
jsonPath: .status.namespaces
name: Namespaces
type: string
- description: Rules
jsonPath: .status.rules
name: Rules
type: string
- description: APIC Objects state
jsonPath: .status.state
name: State
type: string
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1alpha1
schema:
openAPIV3Schema:
description: SegmentationPolicy is the Schema for the segmentationpolicies
API
description: Group is the Schema for the groups API SegmentationPolicy is
the Schema for the segmentationpolicies API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
Expand Down Expand Up @@ -59,6 +75,17 @@ spec:
type: object
status:
description: SegmentationPolicyStatus defines the observed state of SegmentationPolicy
properties:
namespaces:
type: string
rules:
type: string
state:
type: string
required:
- namespaces
- rules
- state
type: object
type: object
served: true
Expand Down
1 change: 1 addition & 0 deletions config/samples/apic_v1alpha1_segmentationpolicy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ spec:
- eth: ip
ip: tcp
port: 443

35 changes: 35 additions & 0 deletions controllers/segmentationpolicy_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"context"
"fmt"
"strconv"
"strings"

corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
Expand All @@ -31,6 +32,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"sigs.k8s.io/controller-runtime/pkg/handler"
"sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/predicate"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"sigs.k8s.io/controller-runtime/pkg/source"

Expand Down Expand Up @@ -99,6 +101,12 @@ func (r *SegmentationPolicyReconciler) Reconcile(ctx context.Context, req ctrl.R
return ctrl.Result{}, err
}

segPolObject.Status.State = "Creating"
err = r.Status().Update(context.Background(), segPolObject)
if err != nil {
return reconcile.Result{}, fmt.Errorf("error occurred while setting the status: %w", err)
}

// if the event is not related to delete, just check if the finalizers are rightfully set on the resource
if segPolObject.GetDeletionTimestamp().IsZero() && !controllerutil.ContainsFinalizer(segPolObject, finalizersSegPol) {
// set the finalizers of the SegmentationPolicy to the rightful ones
Expand Down Expand Up @@ -126,6 +134,12 @@ func (r *SegmentationPolicyReconciler) Reconcile(ctx context.Context, req ctrl.R
return result, err
}

segPolObject.Status.State = "EPGs Created"
err = r.Status().Update(context.Background(), segPolObject)
if err != nil {
return reconcile.Result{}, fmt.Errorf("error occurred while setting the status: %w", err)
}

// Create Contract and Subject and associate the filters
filtersSegPol := []string{}
for _, rule := range segPolObject.Spec.Rules {
Expand All @@ -151,6 +165,11 @@ func (r *SegmentationPolicyReconciler) Reconcile(ctx context.Context, req ctrl.R
if err != nil {
return result, err
}
segPolObject.Status.State = "Enforced"
err = r.Status().Update(context.Background(), segPolObject)
if err != nil {
return reconcile.Result{}, fmt.Errorf("error occurred while setting the status: %w", err)
}

return ctrl.Result{}, nil
}
Expand All @@ -161,6 +180,8 @@ func (r *SegmentationPolicyReconciler) SetupWithManager(mgr ctrl.Manager) error
For(&v1alpha1.SegmentationPolicy{}).
Watches(&source.Kind{Type: &corev1.Namespace{}},
handler.EnqueueRequestsFromMapFunc(r.nameSpaceSegPolicyMapFunc)).
//TODO: Make the code convergent. Status attributes should only be modified if the APIC is actually modified
WithEventFilter(predicate.GenerationChangedPredicate{}).
Complete(r)
}

Expand Down Expand Up @@ -254,6 +275,13 @@ func (r *SegmentationPolicyReconciler) ReconcileNamespacesEpgs(ctx context.Conte
nsClusterNames = append(nsClusterNames, ns.Name)
}

// Set the status
segPolObject.Status.Namespaces = strings.Join(utils.Intersect(nsClusterNames, segPolObject.Spec.Namespaces), ", ")
err := r.Status().Update(context.Background(), segPolObject)
if err != nil {
return reconcile.Result{}, fmt.Errorf("error occurred while setting the status: %w", err)
}

// Always create/overwrite the same Application Profile
logger.Info(fmt.Sprintf("Creating Application Profile %s", segPolObject.Name))
r.ApicClient.CreateApplicationProfile(fmt.Sprintf(ApplicationProfileNamePrefix, r.CniConfig.PolicyTenant), "", r.CniConfig.PolicyTenant)
Expand Down Expand Up @@ -318,6 +346,13 @@ func (r *SegmentationPolicyReconciler) ReconcileRulesFilters(logger logr.Logger,
//Create Filters and filter entries based on the policy rules
filtersSegPol := []string{}

// Set the status
segPolObject.Status.Rules = flattenRules(segPolObject.Spec.Rules)
err := r.Status().Update(context.Background(), segPolObject)
if err != nil {
return reconcile.Result{}, err
}

// Create Filters for those rules listed in the SegmentationPolicy
for _, rule := range segPolObject.Spec.Rules {
filterName := fmt.Sprintf("%s_%s%s%s", segPolObject.Name, rule.Eth, rule.IP, strconv.Itoa(rule.Port))
Expand Down
40 changes: 40 additions & 0 deletions controllers/segmentationpolicy_utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
Copyright 2022.
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.
*/

package controllers

import (
"strconv"
"strings"

"github.com/jgomezve/aci-k8s-operator/api/v1alpha1"
)

func flattenRules(rules []v1alpha1.RuleSpec) string {

listRules := []string{}
for _, rule := range rules {
item := rule.Eth
if rule.IP != "" {
item = item + "-" + rule.IP
}
if rule.Port != 0 {
item = item + "-" + strconv.Itoa(rule.Port)
}
listRules = append(listRules, item)
}
return strings.Join(listRules, ", ")
}
Loading

0 comments on commit 72f56d4

Please sign in to comment.