Skip to content

Commit

Permalink
feat: add status api for ReferenceAddon
Browse files Browse the repository at this point in the history
  • Loading branch information
Ajpantuso committed Oct 31, 2022
1 parent 533fece commit 2523600
Show file tree
Hide file tree
Showing 11 changed files with 357 additions and 210 deletions.
40 changes: 40 additions & 0 deletions apis/reference/v1alpha1/referenceaddon_types.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package v1alpha1

import (
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

Expand All @@ -14,6 +15,39 @@ type ReferenceAddonStatus struct {
Conditions []metav1.Condition `json:"conditions,omitempty"`
}

type ReferenceAddonCondition string

func (c ReferenceAddonCondition) String() string {
return string(c)
}

const (
ReferenceAddonConditionAvailable ReferenceAddonCondition = "Available"
)

type ReferenceAddonAvailableReason string

func (r ReferenceAddonAvailableReason) String() string {
return string(r)
}

func (r ReferenceAddonAvailableReason) Status() metav1.ConditionStatus {
switch r {
case ReferenceAddonAvailableReasonReady:
return "True"
case ReferenceAddonAvailableReasonPending:
return "False"
default:
return "Unknown"
}
}

const (
ReferenceAddonAvailableReasonReady ReferenceAddonAvailableReason = "Ready"
ReferenceAddonAvailableReasonPending ReferenceAddonAvailableReason = "Pending"
ReferenceAddonAvailableReasonUninstalling ReferenceAddonAvailableReason = "Uninstalling"
)

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
Expand All @@ -25,6 +59,12 @@ type ReferenceAddon struct {
Status ReferenceAddonStatus `json:"status,omitempty"`
}

func (a *ReferenceAddon) HasConditionAvailable() bool {
condT := ReferenceAddonConditionAvailable.String()

return meta.FindStatusCondition(a.Status.Conditions, condT) != nil
}

// ReferenceAddonList contains a list of ReferenceAddons
// +kubebuilder:object:root=true
type ReferenceAddonList struct {
Expand Down
48 changes: 48 additions & 0 deletions internal/controllers/helpers.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
package controllers

import (
"context"
"errors"
"fmt"
"strings"

refv1alpha1 "github.com/openshift/reference-addon/apis/reference/v1alpha1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/util/workqueue"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/handler"
"sigs.k8s.io/controller-runtime/pkg/predicate"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"sigs.k8s.io/controller-runtime/pkg/source"
)

var ErrEmptyOptionValue = errors.New("empty option value")
Expand All @@ -26,3 +38,39 @@ func boolPtr(b bool) *bool {
func stringPtr(s string) *string {
return &s
}

func newAvailableCondition(reason refv1alpha1.ReferenceAddonAvailableReason, msg string) metav1.Condition {
return metav1.Condition{
Type: refv1alpha1.ReferenceAddonConditionAvailable.String(),
Status: reason.Status(),
Reason: reason.String(),
Message: msg,
LastTransitionTime: metav1.Now(),
}
}

func enqueueObject(obj types.NamespacedName) source.Func {
return func(_ context.Context, _ handler.EventHandler, q workqueue.RateLimitingInterface, _ ...predicate.Predicate) error {
q.Add(reconcile.Request{
NamespacedName: obj,
})

return nil
}
}

func hasNamePrefix(pfx string) predicate.Funcs {
return predicate.NewPredicateFuncs(
func(obj client.Object) bool {
return strings.HasPrefix(obj.GetName(), pfx)
},
)
}

func hasName(name string) predicate.Funcs {
return predicate.NewPredicateFuncs(
func(obj client.Object) bool {
return obj.GetName() == name
},
)
}
17 changes: 12 additions & 5 deletions internal/controllers/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package controllers
import (
"github.com/go-logr/logr"
netv1 "k8s.io/api/networking/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type WithLog struct{ Log logr.Logger }
Expand All @@ -15,10 +16,6 @@ func (w WithLog) ConfigurePhaseApplyNetworkPolicies(c *PhaseApplyNetworkPolicies
c.Log = w.Log
}

func (w WithLog) ConfigurePhaseSimulateReconciliation(c *PhaseSimulateReconciliationConfig) {
c.Log = w.Log
}

func (w WithLog) ConfigurePhaseUninstall(c *PhaseUninstallConfig) {
c.Log = w.Log
}
Expand Down Expand Up @@ -91,10 +88,20 @@ func (w WithNamespace) ConfigureListCSVs(c *ListCSVsConfig) {
c.Namespace = string(w)
}

type WithOwner struct{ Owner metav1.Object }

func (w WithOwner) ConfigureApplyNetworkPolicies(c *ApplyNetorkPoliciesConfig) {
c.Owner = w.Owner
}

type WithPolicies []netv1.NetworkPolicy

func (w WithPolicies) ConfigurePhaseApplyNetworkPolicies(c *PhaseApplyNetworkPoliciesConfig) {
c.Policies = []netv1.NetworkPolicy(w)
c.Policies = append(c.Policies, w...)
}

func (w WithPolicies) ConfigureApplyNetworkPolicies(c *ApplyNetorkPoliciesConfig) {
c.Policies = append(c.Policies, w...)
}

type WithPrefix string
Expand Down
81 changes: 63 additions & 18 deletions internal/controllers/phase/phase.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@ package phase
import (
"context"

"k8s.io/apimachinery/pkg/types"
refv1alpha1 "github.com/openshift/reference-addon/apis/reference/v1alpha1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type Phase interface {
Execute(ctx context.Context, req Request) Result
}

type Request struct {
Object types.NamespacedName
Addon refv1alpha1.ReferenceAddon
Params RequestParameters
}

Expand Down Expand Up @@ -74,46 +75,61 @@ type RequestParametersOption interface {
ConfigureRequestParameters(*RequestParametersConfig)
}

func Success() Result {
func Success(opts ...ResultOption) Result {
var cfg ResultConfig

cfg.Option(opts...)

return Result{
cfg: cfg,
status: StatusSuccess,
}
}

func Blocking() Result {
func Blocking(opts ...ResultOption) Result {
var cfg ResultConfig

cfg.Option(opts...)

return Result{
status: StatusSuccess,
blocking: true,
cfg: cfg,
status: StatusBlocking,
}
}

func Failure(msg string) Result {
func Failure(msg string, opts ...ResultOption) Result {
var cfg ResultConfig

cfg.Option(opts...)

return Result{
cfg: cfg,
status: StatusFailure,
failureMsg: msg,
}
}

func Error(err error) Result {
func Error(err error, opts ...ResultOption) Result {
var cfg ResultConfig

cfg.Option(opts...)

return Result{
cfg: cfg,
status: StatusError,
err: err,
}
}

type Result struct {
cfg ResultConfig
err error
failureMsg string
status Status
blocking bool
}

func (r Result) IsSuccess() bool {
return r.status == StatusSuccess
}

func (r Result) IsBlocking() bool {
return r.blocking
func (r Result) Status() Status {
return r.status
}

func (r Result) FailureMessage() string {
Expand All @@ -124,10 +140,39 @@ func (r Result) Error() error {
return r.err
}

func (r Result) Conditions() []metav1.Condition {
return r.cfg.Conditions
}

type Status string

func (s Status) String() string {
return string(s)
}

const (
StatusSuccess = "success"
StatusFailure = "failure"
StatusError = "error"
StatusBlocking Status = "blocking"
StatusError Status = "error"
StatusFailure Status = "failure"
StatusSuccess Status = "success"
)

type ResultConfig struct {
Conditions []metav1.Condition
}

func (c *ResultConfig) Option(opts ...ResultOption) {
for _, opt := range opts {
opt.ConfigureResult(c)
}
}

type ResultOption interface {
ConfigureResult(c *ResultConfig)
}

type WithConditions []metav1.Condition

func (w WithConditions) ConfigureResult(c *ResultConfig) {
c.Conditions = append(c.Conditions, w...)
}
38 changes: 32 additions & 6 deletions internal/controllers/phase_apply_network_policies.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func (p *PhaseApplyNetworkPolicies) Execute(ctx context.Context, req phase.Reque
return p.ensureNetworkPoliciesRemoved(ctx)
}

return p.ensureNetworkPoliciesApplied(ctx)
return p.ensureNetworkPoliciesApplied(ctx, req)
}

func (p *PhaseApplyNetworkPolicies) ensureNetworkPoliciesRemoved(ctx context.Context) phase.Result {
Expand All @@ -62,10 +62,10 @@ func (p *PhaseApplyNetworkPolicies) ensureNetworkPoliciesRemoved(ctx context.Con
return phase.Success()
}

func (p *PhaseApplyNetworkPolicies) ensureNetworkPoliciesApplied(ctx context.Context) phase.Result {
func (p *PhaseApplyNetworkPolicies) ensureNetworkPoliciesApplied(ctx context.Context, req phase.Request) phase.Result {
p.cfg.Log.Info("applying NetworkPolicies", "count", len(p.cfg.Policies))

if err := p.client.ApplyNetworkPolicies(ctx, p.cfg.Policies...); err != nil {
if err := p.client.ApplyNetworkPolicies(ctx, WithOwner{Owner: &req.Addon}, WithPolicies(p.cfg.Policies)); err != nil {
return phase.Error(fmt.Errorf("applying NetworkPolicies: %w", err))
}

Expand Down Expand Up @@ -97,7 +97,7 @@ type PhaseApplyNetworkPoliciesOption interface {
}

type NetworkPolicyClient interface {
ApplyNetworkPolicies(ctx context.Context, policies ...netv1.NetworkPolicy) error
ApplyNetworkPolicies(ctx context.Context, opts ...ApplyNetorkPoliciesOption) error
RemoveNetworkPolicies(ctx context.Context, policies ...netv1.NetworkPolicy) error
}

Expand All @@ -111,13 +111,23 @@ type NetworkPolicyClientImpl struct {
client client.Client
}

func (c *NetworkPolicyClientImpl) ApplyNetworkPolicies(ctx context.Context, policies ...netv1.NetworkPolicy) error {
func (c *NetworkPolicyClientImpl) ApplyNetworkPolicies(ctx context.Context, opts ...ApplyNetorkPoliciesOption) error {
ctx, cancel := context.WithCancel(ctx)
defer cancel()

var cfg ApplyNetorkPoliciesConfig

cfg.Option(opts...)

var finalErr error

for _, policy := range policies {
for _, policy := range cfg.Policies {
if cfg.Owner != nil {
if err := ctrl.SetControllerReference(cfg.Owner, &policy, c.client.Scheme()); err != nil {
return fmt.Errorf("setting controller reference: %w", err)
}
}

if err := c.createOrUpdatePolicy(ctx, policy); err != nil {
multierr.AppendInto(&finalErr, fmt.Errorf("creating/updating NetworkPolicy %q: %w", policy.Name, err))
}
Expand All @@ -126,6 +136,21 @@ func (c *NetworkPolicyClientImpl) ApplyNetworkPolicies(ctx context.Context, poli
return finalErr
}

type ApplyNetorkPoliciesConfig struct {
Owner metav1.Object
Policies []netv1.NetworkPolicy
}

func (c *ApplyNetorkPoliciesConfig) Option(opts ...ApplyNetorkPoliciesOption) {
for _, opt := range opts {
opt.ConfigureApplyNetworkPolicies(c)
}
}

type ApplyNetorkPoliciesOption interface {
ConfigureApplyNetworkPolicies(c *ApplyNetorkPoliciesConfig)
}

func (c *NetworkPolicyClientImpl) createOrUpdatePolicy(ctx context.Context, policy netv1.NetworkPolicy) error {
actualPolicy := &netv1.NetworkPolicy{
ObjectMeta: metav1.ObjectMeta{
Expand All @@ -136,6 +161,7 @@ func (c *NetworkPolicyClientImpl) createOrUpdatePolicy(ctx context.Context, poli

_, err := ctrl.CreateOrUpdate(ctx, c.client, actualPolicy, func() error {
actualPolicy.Labels = labels.Merge(actualPolicy.Labels, policy.Labels)
actualPolicy.OwnerReferences = policy.OwnerReferences
actualPolicy.Spec = policy.Spec

return nil
Expand Down
Loading

0 comments on commit 2523600

Please sign in to comment.