Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ossm merge #112

Merged
merged 11 commits into from
Dec 13, 2022
3 changes: 0 additions & 3 deletions .github/workflows/build-images.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,7 @@ jobs:
run: |
echo "IMG_TAGS=latest ${{ env.IMG_TAGS }}" >> $GITHUB_ENV
- name: Run make bundle
if: ${{ github.ref_name != env.MAIN_BRANCH_NAME }}
run: make bundle REGISTRY=${{ env.IMG_REGISTRY_HOST }} ORG=${{ env.IMG_REGISTRY_ORG }} IMAGE_TAG=${{ github.ref_name }}
- name: Git diff
run: git diff
- name: Install qemu dependency
run: |
sudo apt-get update
Expand Down
20 changes: 15 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ act: $(ACT) ## Download act locally if necessary.

.PHONY: manifests
manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
$(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
$(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./api/v1beta1" output:crd:artifacts:config=config/crd/bases
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's because of the external API defs now hosted in our code base. We don't want them in the output generated manifests.


.PHONY: dependencies-manifests
dependencies-manifests: export AUTHORINO_OPERATOR_GITREF := $(AUTHORINO_OPERATOR_GITREF)
Expand Down Expand Up @@ -245,15 +245,19 @@ local-setup: $(KIND) ## Deploy locally kuadrant operator from the current code
local-cleanup: ## Delete local cluster
$(MAKE) kind-delete-cluster

# kuadrant is not deployed
.PHONY: local-env-setup
local-env-setup: ## Deploys all services and manifests required by kuadrant to run. Used to run kuadrant with "make run"
.PHONY: local-cluster-setup
local-cluster-setup: ## Sets up Kind cluster with GatewayAPI manifests and istio GW, nothing Kuadrant.
$(MAKE) kind-delete-cluster
$(MAKE) kind-create-cluster
$(MAKE) namespace
$(MAKE) gateway-api-install
$(MAKE) istio-install
$(MAKE) deploy-gateway

# kuadrant is not deployed
.PHONY: local-env-setup
local-env-setup: ## Deploys all services and manifests required by kuadrant to run. Used to run kuadrant with "make run"
$(MAKE) local-cluster-setup
$(MAKE) deploy-dependencies
$(MAKE) install

Expand Down Expand Up @@ -282,6 +286,12 @@ docker-build: ## Build docker image with the manager.
docker-push: ## Push docker image with the manager.
docker push $(IMG)

kind-load-image: ## Load image to local cluster
$(KIND) load docker-image $(IMG) --name $(KIND_CLUSTER_NAME)

kind-load-bundle: ## Load image to local cluster
$(KIND) load docker-image $(BUNDLE_IMG) --name $(KIND_CLUSTER_NAME)

##@ Deployment

install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config.
Expand Down Expand Up @@ -310,7 +320,7 @@ install-olm: $(OPERATOR_SDK)
uninstall-olm:
$(OPERATOR_SDK) olm uninstall

deploy-catalog: $(KUSTOMIZE) $(YQ) ## Deploy controller to the K8s cluster specified in ~/.kube/config using OLM catalog image.
deploy-catalog: $(KUSTOMIZE) $(YQ) ## Deploy operator to the K8s cluster specified in ~/.kube/config using OLM catalog image.
V="$(CATALOG_IMG)" $(YQ) eval '.spec.image = strenv(V)' -i config/deploy/olm/catalogsource.yaml
$(KUSTOMIZE) build config/deploy/olm | kubectl apply -f -

Expand Down
12 changes: 12 additions & 0 deletions api/external/maistra/addtoscheme_maistra_v1.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package apis

import (
v1 "github.com/kuadrant/kuadrant-operator/api/external/maistra/v1"
)

func init() {
// Register the types with the Scheme so the components can map objects to GroupVersionKinds and back
AddToSchemes = append(AddToSchemes,
v1.SchemeBuilder.AddToScheme,
)
}
12 changes: 12 additions & 0 deletions api/external/maistra/addtoscheme_maistra_v2.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package apis

import (
v2 "github.com/kuadrant/kuadrant-operator/api/external/maistra/v2"
)

func init() {
// Register the types with the Scheme so the components can map objects to GroupVersionKinds and back
AddToSchemes = append(AddToSchemes,
v2.SchemeBuilder.AddToScheme,
)
}
13 changes: 13 additions & 0 deletions api/external/maistra/apis.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package apis

import (
"k8s.io/apimachinery/pkg/runtime"
)

// AddToSchemes may be used to add all resources defined in the project to a Scheme
var AddToSchemes runtime.SchemeBuilder

// AddToScheme adds all Resources to the Scheme
func AddToScheme(s *runtime.Scheme) error {
return AddToSchemes.AddToScheme(s)
}
280 changes: 280 additions & 0 deletions api/external/maistra/status/status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,280 @@
//nolint
package status

import (
"fmt"
"strings"
"time"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"

"github.com/kuadrant/kuadrant-operator/api/external/maistra/version"
)

type StatusBase struct {
// Annotations is an unstructured key value map used to store additional,
// usually redundant status information, such as the number of components
// deployed by the ServiceMeshControlPlane (number is redundant because
// you could just as easily count the elements in the ComponentStatus
// array). The reason to add this redundant information is to make it
// available to kubectl, which does not yet allow counting objects in
// JSONPath expressions.
// +optional
Annotations map[string]string `json:"annotations,omitempty"`
}

func (s *StatusBase) GetAnnotation(name string) string {
if s.Annotations == nil {
return ""
}
return s.Annotations[name]
}

func (s *StatusBase) SetAnnotation(name string, value string) {
if s.Annotations == nil {
s.Annotations = map[string]string{}
}
s.Annotations[name] = value
}

func (s *StatusBase) RemoveAnnotation(name string) {
if s.Annotations != nil {
delete(s.Annotations, name)
}
}

// StatusType represents the status for a control plane, component, or resource
type StatusType struct {
// Represents the latest available observations of the object's current state.
Conditions []Condition `json:"conditions,omitempty"`
}

// NewStatus returns a new StatusType object
func NewStatus() StatusType {
return StatusType{Conditions: make([]Condition, 0, 3)}
}

type ComponentStatusList struct {
// +optional
ComponentStatus []ComponentStatus `json:"components,omitempty"`
}

// FindComponentByName returns the status for a specific component
func (s *ComponentStatusList) FindComponentByName(name string) *ComponentStatus {
for i, status := range s.ComponentStatus {
if status.Resource == name {
return &s.ComponentStatus[i]
}
}
return nil
}

// NewComponentStatus returns a new ComponentStatus object
func NewComponentStatus() *ComponentStatus {
return &ComponentStatus{StatusType: NewStatus()}
}

// ComponentStatus represents the status of an object with children
type ComponentStatus struct {
StatusType `json:",inline"`

// The name of the component this status pertains to.
Resource string `json:"resource,omitempty"`

// TODO: can we remove this? it's not used anywhere
// The status of each resource that comprises this component.
Resources []*StatusType `json:"children,omitempty"`
}

// ConditionType represents the type of the condition. Condition stages are:
// Installed, Reconciled, Ready
type ConditionType string

const (
// ConditionTypeInstalled signifies the whether or not the controller has
// installed the resources defined through the CR.
ConditionTypeInstalled ConditionType = "Installed"
// ConditionTypeReconciled signifies the whether or not the controller has
// reconciled the resources defined through the CR.
ConditionTypeReconciled ConditionType = "Reconciled"
// ConditionTypeReady signifies the whether or not any Deployment, StatefulSet,
// etc. resources are Ready.
ConditionTypeReady ConditionType = "Ready"
)

// ConditionStatus represents the status of the condition
type ConditionStatus string

const (
// ConditionStatusTrue represents completion of the condition, e.g.
// Initialized=True signifies that initialization has occurred.
ConditionStatusTrue ConditionStatus = "True"
// ConditionStatusFalse represents incomplete status of the condition, e.g.
// Initialized=False signifies that initialization has not occurred or has
// failed.
ConditionStatusFalse ConditionStatus = "False"
// ConditionStatusUnknown represents unknown completion of the condition, e.g.
// Initialized=Unknown signifies that initialization may or may not have been
// completed.
ConditionStatusUnknown ConditionStatus = "Unknown"
)

// ConditionReason represents a short message indicating how the condition came
// to be in its present state.
type ConditionReason string

const (
// ConditionReasonDeletionError ...
ConditionReasonDeletionError ConditionReason = "DeletionError"
// ConditionReasonInstallSuccessful ...
ConditionReasonInstallSuccessful ConditionReason = "InstallSuccessful"
// ConditionReasonInstallError ...
ConditionReasonInstallError ConditionReason = "InstallError"
// ConditionReasonReconcileSuccessful ...
ConditionReasonReconcileSuccessful ConditionReason = "ReconcileSuccessful"
// ConditionReasonValidationError ...
ConditionReasonValidationError ConditionReason = "ValidationError"
// ConditionReasonValidationError ...
ConditionReasonMultipleSMCPs ConditionReason = "ErrMultipleSMCPs"
// ConditionReasonDependencyMissingError ...
ConditionReasonDependencyMissingError ConditionReason = "DependencyMissingError"
// ConditionReasonReconcileError ...
ConditionReasonReconcileError ConditionReason = "ReconcileError"
// ConditionReasonResourceCreated ...
ConditionReasonResourceCreated ConditionReason = "ResourceCreated"
// ConditionReasonSpecUpdated ...
ConditionReasonSpecUpdated ConditionReason = "SpecUpdated"
// ConditionReasonOperatorUpdated indicates that the SMCP is being reconciled
// because the operator was upgraded
ConditionReasonOperatorUpdated ConditionReason = "OperatorUpdated"
// ConditionReasonUpdateSuccessful ...
ConditionReasonUpdateSuccessful ConditionReason = "UpdateSuccessful"
// ConditionReasonComponentsReady ...
ConditionReasonComponentsReady ConditionReason = "ComponentsReady"
// ConditionReasonComponentsNotReady ...
ConditionReasonComponentsNotReady ConditionReason = "ComponentsNotReady"
// ConditionReasonProbeError ...
ConditionReasonProbeError ConditionReason = "ProbeError"
// ConditionReasonPausingInstall ...
ConditionReasonPausingInstall ConditionReason = "PausingInstall"
// ConditionReasonPausingUpdate ...
ConditionReasonPausingUpdate ConditionReason = "PausingUpdate"
// ConditionReasonDeleting ...
ConditionReasonDeleting ConditionReason = "Deleting"
// ConditionReasonDeleted ...
ConditionReasonDeleted ConditionReason = "Deleted"
)

// A Condition represents a specific observation of the object's state.
type Condition struct {
// The type of this condition.
Type ConditionType `json:"type,omitempty"`

// The status of this condition. Can be True, False or Unknown.
Status ConditionStatus `json:"status,omitempty"`

// Unique, single-word, CamelCase reason for the condition's last transition.
Reason ConditionReason `json:"reason,omitempty"`

// Human-readable message indicating details about the last transition.
Message string `json:"message,omitempty"`

// Last time the condition transitioned from one status to another.
LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"`
}

func (c *Condition) Matches(status ConditionStatus, reason ConditionReason, message string) bool {
return c.Status == status && c.Reason == reason && c.Message == message
}

// CurrentReconciledVersion returns a ReconciledVersion for this release of the operator
func CurrentReconciledVersion(generation int64) string {
return ComposeReconciledVersion(version.Info.Version, generation)
}

// ComposeReconciledVersion returns a string for use in ReconciledVersion fields
func ComposeReconciledVersion(operatorVersion string, generation int64) string {
return fmt.Sprintf("%s-%d", operatorVersion, generation)
}

// GetCondition removes a condition for the list of conditions
func (s *StatusType) GetCondition(conditionType ConditionType) Condition {
if s == nil {
return Condition{Type: conditionType, Status: ConditionStatusUnknown}
}
for i := range s.Conditions {
if s.Conditions[i].Type == conditionType {
return s.Conditions[i]
}
}
return Condition{Type: conditionType, Status: ConditionStatusUnknown}
}

// SetCondition sets a specific condition in the list of conditions
func (s *StatusType) SetCondition(condition Condition) *StatusType {
if s == nil {
return nil
}
// These only get serialized out to the second. This can break update
// skipping, as the time in the resource returned from the client may not
// match the time in our cached status during a reconcile. We truncate here
// to save any problems down the line.
now := metav1.NewTime(time.Now().Truncate(time.Second))
for i, prevCondition := range s.Conditions {
if prevCondition.Type == condition.Type {
if prevCondition.Status != condition.Status {
condition.LastTransitionTime = now
} else {
condition.LastTransitionTime = prevCondition.LastTransitionTime
}
s.Conditions[i] = condition
return s
}
}

// If the condition does not exist,
// initialize the lastTransitionTime
condition.LastTransitionTime = now
s.Conditions = append(s.Conditions, condition)
return s
}

// RemoveCondition removes a condition for the list of conditions
func (s *StatusType) RemoveCondition(conditionType ConditionType) *StatusType {
if s == nil {
return nil
}
for i := range s.Conditions {
if s.Conditions[i].Type == conditionType {
s.Conditions = append(s.Conditions[:i], s.Conditions[i+1:]...)
return s
}
}
return s
}

// ResourceKey is a typedef for key used in ManagedGenerations. It is a string
// with the format: namespace/name=group/version,kind
type ResourceKey string

// NewResourceKey for the object and type
func NewResourceKey(o metav1.Object, t metav1.Type) ResourceKey {
return ResourceKey(fmt.Sprintf("%s/%s=%s,Kind=%s", o.GetNamespace(), o.GetName(), t.GetAPIVersion(), t.GetKind()))
}

// ToUnstructured returns a an Unstructured object initialized with Namespace,
// Name, APIVersion, and Kind fields from the ResourceKey
func (key ResourceKey) ToUnstructured() *unstructured.Unstructured {
// ResourceKey is guaranteed to be at least "/=," meaning we are guaranteed
// to get two elements in all of the splits
retval := &unstructured.Unstructured{}
parts := strings.SplitN(string(key), "=", 2)
nn := strings.SplitN(parts[0], "/", 2)
gvk := strings.SplitN(parts[1], ",Kind=", 2)
retval.SetNamespace(nn[0])
retval.SetName(nn[1])
retval.SetAPIVersion(gvk[0])
retval.SetKind(gvk[1])
return retval
}
Loading