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

oran: add new oran package and provisioning request builder #839

Merged
merged 2 commits into from
Jan 29, 2025
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
1 change: 1 addition & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ linters-settings:
- "github.com/red-hat-storage/odf-operator"
- "github.com/stmcginnis/gofish"
- "github.com/prometheus-operator/prometheus-operator"
- "github.com/google/uuid"
govet:
disable:
- printf
Expand Down
11 changes: 9 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ require (
github.com/go-openapi/validate v0.24.0
github.com/golang/glog v1.2.4
github.com/google/go-cmp v0.6.0
github.com/google/uuid v1.6.0
github.com/grafana/loki/operator/apis/loki v0.0.0-20241021105923-5e970e50b166
github.com/hashicorp/vault/api v1.15.0
github.com/hashicorp/vault/api/auth/approle v0.8.0
Expand All @@ -29,6 +30,7 @@ require (
github.com/openshift-kni/cluster-group-upgrades-operator v0.0.0-20241213003211-a57a58a5c4f2 // release-4.18
github.com/openshift-kni/lifecycle-agent v0.0.0-20250120220331-9547280df193 // release-4.18
github.com/openshift-kni/numaresources-operator v0.4.18-0.2024100201.0.20250114093602-01c00730991d // release-4.18
github.com/openshift-kni/oran-o2ims/api/provisioning v0.0.0-20250123151805-c935b06062f9
github.com/openshift/api v3.9.1-0.20191111211345-a27ff30ebf09+incompatible
github.com/openshift/client-go v0.0.0-20241107164952-923091dd2b1a
github.com/openshift/cluster-logging-operator v0.0.0-20241003210634-afb65cea19d1 // release-5.9
Expand Down Expand Up @@ -121,7 +123,6 @@ require (
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/websocket v1.5.1 // indirect
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
Expand Down Expand Up @@ -164,6 +165,7 @@ require (
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.61.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/r3labs/diff/v3 v3.0.1 // indirect
github.com/robfig/cron v1.2.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/ryanuber/go-glob v1.0.0 // indirect
Expand All @@ -173,12 +175,17 @@ require (
github.com/spf13/pflag v1.0.6-0.20210604193023-d5e0c0615ace // indirect
github.com/vincent-petithory/dataurl v1.0.0 // indirect
github.com/vishvananda/netns v0.0.4 // indirect
github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
github.com/vmware-tanzu/velero v1.13.2
github.com/x448/float16 v0.8.4 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
github.com/xlab/treeprint v1.2.0 // indirect
go.mongodb.org/mongo-driver v1.17.1 // indirect
go4.org v0.0.0-20230225012048-214862532bf5 // indirect
golang.org/x/oauth2 v0.24.0 // indirect
golang.org/x/oauth2 v0.25.0 // indirect
golang.org/x/sync v0.10.0 // indirect
golang.org/x/sys v0.29.0 // indirect
golang.org/x/term v0.28.0 // indirect
Expand Down
19 changes: 17 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,8 @@ github.com/openshift-kni/lifecycle-agent v0.0.0-20250120220331-9547280df193 h1:p
github.com/openshift-kni/lifecycle-agent v0.0.0-20250120220331-9547280df193/go.mod h1:DwQZz++aIo/wJG/yYA3NcojzOn+nPpmxUt7OXhDRt+o=
github.com/openshift-kni/numaresources-operator v0.4.18-0.2024100201.0.20250114093602-01c00730991d h1:asZpmqVNGcasAyRoI8NcqxfrQggI516QazKWrVfbeWo=
github.com/openshift-kni/numaresources-operator v0.4.18-0.2024100201.0.20250114093602-01c00730991d/go.mod h1:0Nx16xaZzxDbBs12tRjAWxDJdA9RknYEf2edrOjOdrU=
github.com/openshift-kni/oran-o2ims/api/provisioning v0.0.0-20250123151805-c935b06062f9 h1:AP4psTmffaPv3IS/PkXIqRo2lmC0chWv33piK6m28sU=
github.com/openshift-kni/oran-o2ims/api/provisioning v0.0.0-20250123151805-c935b06062f9/go.mod h1:7dmhnmqiO1VP3SuqaAdnlFbBdeTLK3FI3vQHapVMNQg=
github.com/openshift/api v0.0.0-20241210155609-29859d55727b h1:IrtLpBrlSL7a3HK+Brg7C1DFO/gsztIEMlCRJW0M82s=
github.com/openshift/api v0.0.0-20241210155609-29859d55727b/go.mod h1:Shkl4HanLwDiiBzakv+con/aMGnVE2MAGvoKp5oyYUo=
github.com/openshift/client-go v0.0.0-20241107164952-923091dd2b1a h1:h3F55x+zOXwSG4okUlXmOlU/5CQ7Ve2HKxYjseJPVoY=
Expand Down Expand Up @@ -541,6 +543,8 @@ github.com/prometheus/common v0.61.0 h1:3gv/GThfX0cV2lpO7gkTUwZru38mxevy90Bj8YFS
github.com/prometheus/common v0.61.0/go.mod h1:zr29OCN/2BsJRaFwG8QOBr41D6kkchKbpeNH7pAjb/s=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/r3labs/diff/v3 v3.0.1 h1:CBKqf3XmNRHXKmdU7mZP1w7TV0pDyVCis1AUHtA4Xtg=
github.com/r3labs/diff/v3 v3.0.1/go.mod h1:f1S9bourRbiM66NskseyUdo0fTmEE0qKrikYJX63dgo=
github.com/red-hat-storage/odf-operator v0.0.0-20241124050455-02681e6c10df h1:vVue8Ytv9xEMIC15PPh2FiL8k8YAZvtUd6E6r1xRyJk=
github.com/red-hat-storage/odf-operator v0.0.0-20241124050455-02681e6c10df/go.mod h1:Qgmgk+Wa61zuvR9mRQEOjD6tcUezT7aU5GXaBup6eXM=
github.com/rh-ecosystem-edge/kernel-module-management v0.0.0-20240925181841-898c27853e89 h1:J8wb1aU7globChbOrZdygjJUBXefv032W168wzi1HC4=
Expand Down Expand Up @@ -605,12 +609,23 @@ github.com/vincent-petithory/dataurl v1.0.0 h1:cXw+kPto8NLuJtlMsI152irrVw9fRDX8A
github.com/vincent-petithory/dataurl v1.0.0/go.mod h1:FHafX5vmDzyP+1CQATJn7WFKc9CvnvxyvZy6I1MrG/U=
github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU=
github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc=
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
github.com/vmware-tanzu/velero v1.13.2 h1:72Rw+11HJB6XUYfH9/M/jle6duSLyGhMisMMYFr/1qs=
github.com/vmware-tanzu/velero v1.13.2/go.mod h1:yHFPyr+iwpKRf66xJ88MriAHiX58tTnKmQXY2FQZClM=
github.com/vmware/vmw-guestinfo v0.0.0-20170707015358-25eff159a728/go.mod h1:x9oS4Wk2s2u4tS29nEaDLdzvuHdB19CvSGJjPgkZJNk=
github.com/vmware/vmw-ovflib v0.0.0-20170608004843-1f217b9dc714/go.mod h1:jiPk45kn7klhByRvUq5i2vo1RtHKBHj+iWGFpxbXuuI=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ=
github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
Expand Down Expand Up @@ -758,8 +773,8 @@ golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4Iltr
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE=
golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70=
golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand Down
275 changes: 275 additions & 0 deletions pkg/oran/provisioningrequest.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,275 @@
package oran

import (
"context"
"fmt"

"github.com/golang/glog"
"github.com/google/uuid"
"github.com/openshift-kni/eco-goinfra/pkg/clients"
"github.com/openshift-kni/eco-goinfra/pkg/msg"
provisioningv1alpha1 "github.com/openshift-kni/oran-o2ims/api/provisioning/v1alpha1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
)

// ProvisioningRequestBuilder provides a struct to inferface with ProvisioningRequest resources on a specific cluster.
type ProvisioningRequestBuilder struct {
// Definition of the ProvisioningRequest used to create the resource.
Definition *provisioningv1alpha1.ProvisioningRequest
// Object of the ProvisioningRequest as it is on the cluster.
Object *provisioningv1alpha1.ProvisioningRequest
// apiClient used to interact with the cluster.
apiClient runtimeclient.Client
// errorMsg used to store latest error message from functions that do not return errors.
errorMsg string
}

// NewPRBuilder creates a new instance of a ProvisioningRequest builder.
func NewPRBuilder(
apiClient *clients.Settings, name, templateName, templateVersion string) *ProvisioningRequestBuilder {
glog.V(100).Infof(
"Initializing new ProvisioningRequest structure with the following params: "+
"name: %s, templateName: %s, templateVersion: %s",
name, templateName, templateVersion)

if apiClient == nil {
glog.V(100).Infof("The apiClient of the ProvisioningRequest is nil")

return nil
}

err := apiClient.AttachScheme(provisioningv1alpha1.AddToScheme)
if err != nil {
glog.V(100).Infof("Failed to add provisioning v1alpha1 scheme to client schemes: %v", err)

return nil
}

builder := &ProvisioningRequestBuilder{
apiClient: apiClient.Client,
Definition: &provisioningv1alpha1.ProvisioningRequest{
ObjectMeta: metav1.ObjectMeta{
Name: name,
},
Spec: provisioningv1alpha1.ProvisioningRequestSpec{
TemplateName: templateName,
TemplateVersion: templateVersion,
},
},
}

if err := uuid.Validate(name); err != nil {
glog.V(100).Infof("The name of the ProvisioningRequest is not a valid UUID: %v", err)

builder.errorMsg = "provisioningRequest 'name' must be a valid UUID"

return builder
}

if templateName == "" {
glog.V(100).Info("The template name of the ProvisioningRequest is empty")

builder.errorMsg = "provisioningRequest 'templateName' cannot be empty"

return builder
}

if templateVersion == "" {
glog.V(100).Info("The template version of the ProvisioningRequest is empty")

builder.errorMsg = "provisioningRequest 'templateVersion' cannot be empty"

return builder
}

return builder
}

// PullPR pulls an existing ProvisioningRequest into a Builder struct.
func PullPR(apiClient *clients.Settings, name string) (*ProvisioningRequestBuilder, error) {
glog.V(100).Infof("Pulling existing ProvisioningRequest %s from cluster", name)

if apiClient == nil {
glog.V(100).Infof("The apiClient of the ProvisioningRequest is nil")

return nil, fmt.Errorf("provisioningRequest 'apiClient' cannot be nil")
}

err := apiClient.AttachScheme(provisioningv1alpha1.AddToScheme)
if err != nil {
glog.V(100).Infof("Failed to add provisioning v1alpha1 scheme to client schemes: %v", err)

return nil, err
}

builder := &ProvisioningRequestBuilder{
apiClient: apiClient.Client,
Definition: &provisioningv1alpha1.ProvisioningRequest{
ObjectMeta: metav1.ObjectMeta{
Name: name,
},
},
}

if name == "" {
glog.V(100).Info("The name of the ProvisioningRequest is empty")

return nil, fmt.Errorf("provisioningRequest 'name' cannot be empty")
}

if !builder.Exists() {
glog.V(100).Info("The ProvisioningRequest %s does not exist", name)

return nil, fmt.Errorf("provisioningRequest object %s does not exist", name)
}

builder.Definition = builder.Object

return builder, nil
}

// Get returns the ProvisioningRequest object if found.
func (builder *ProvisioningRequestBuilder) Get() (*provisioningv1alpha1.ProvisioningRequest, error) {
if valid, err := builder.validate(); !valid {
return nil, err
}

glog.V(100).Infof(
"Getting ProvisioningRequest object %s", builder.Definition.Name)

provisioningRequest := &provisioningv1alpha1.ProvisioningRequest{}
err := builder.apiClient.Get(context.TODO(), runtimeclient.ObjectKey{
Name: builder.Definition.Name,
}, provisioningRequest)

if err != nil {
glog.V(100).Infof("Failed to get ProvisioningRequest object %s: %v", builder.Definition.Name, err)

return nil, err
}

return provisioningRequest, nil
}

// Exists checks whether the given ProvisioningRequest exists on the cluster.
func (builder *ProvisioningRequestBuilder) Exists() bool {
if valid, _ := builder.validate(); !valid {
return false
}

glog.V(100).Infof("Checking if ProvisioningRequest %s exists", builder.Definition.Name)

var err error
builder.Object, err = builder.Get()

return err == nil || !k8serrors.IsNotFound(err)
}

// Create makes a ProvisioningRequest on the cluster if it does not already exist.
func (builder *ProvisioningRequestBuilder) Create() (*ProvisioningRequestBuilder, error) {
if valid, err := builder.validate(); !valid {
return nil, err
}

glog.V(100).Infof("Creating ProvisioningRequest %s", builder.Definition.Name)

if builder.Exists() {
return builder, nil
}

err := builder.apiClient.Create(context.TODO(), builder.Definition)
if err != nil {
return nil, err
}

builder.Object = builder.Definition

return builder, nil
}

// Update changes the existing ProvisioningRequest resource on the cluster. Since deleting a ProvisioningRequest is a
// non-trivial operation and corresponds to deleting a cluster, there is no option to fall back to deleting and
// recreating the ProvisioningRequest.
func (builder *ProvisioningRequestBuilder) Update() (*ProvisioningRequestBuilder, error) {
if valid, err := builder.validate(); !valid {
return nil, err
}

glog.V(100).Infof("Updating ProvisioningRequest %s", builder.Definition.Name)

if !builder.Exists() {
glog.V(100).Infof("ProvisioningRequest %s does not exist", builder.Definition.Name)

return nil, fmt.Errorf("cannot update non-existent provisioningRequest")
}

builder.Definition.ResourceVersion = builder.Object.ResourceVersion

err := builder.apiClient.Update(context.TODO(), builder.Definition)
if err != nil {
return nil, err
}

builder.Object = builder.Definition

return builder, nil
}

// Delete removes a ProvisioningRequest from the cluster if it exists.
func (builder *ProvisioningRequestBuilder) Delete() error {
if valid, err := builder.validate(); !valid {
return err
}

glog.V(100).Infof("Deleting ProvisioningRequest %s", builder.Definition.Name)

if !builder.Exists() {
glog.V(100).Infof("ProvisioningRequest %s does not exist", builder.Definition.Name)

builder.Object = nil

return nil
}

err := builder.apiClient.Delete(context.TODO(), builder.Object)
if err != nil {
return err
}

builder.Object = nil

return nil
}

// validate checks that the builder, definition, and apiClient are properly initialized and there is no errorMsg.
func (builder *ProvisioningRequestBuilder) validate() (bool, error) {
resourceCRD := "provisioningRequest"

if builder == nil {
glog.V(100).Infof("The %s builder is uninitialized", resourceCRD)

return false, fmt.Errorf("error: received nil %s builder", resourceCRD)
}

if builder.Definition == nil {
glog.V(100).Infof("The %s is uninitialized", resourceCRD)

return false, fmt.Errorf(msg.UndefinedCrdObjectErrString(resourceCRD))
}

if builder.apiClient == nil {
glog.V(100).Infof("The %s builder apiClient is nil", resourceCRD)

return false, fmt.Errorf("%s builder cannot have nil apiClient", resourceCRD)
}

if builder.errorMsg != "" {
glog.V(100).Infof("The %s builder has error message %s", resourceCRD, builder.errorMsg)

return false, fmt.Errorf(builder.errorMsg)
}

return true, nil
}
Loading
Loading