Skip to content

Commit

Permalink
Nephio operator for focom to oran-provisioning requests (#849)
Browse files Browse the repository at this point in the history
***

**__NOTE:__** All data under the /config directory is generated by the
operator sdk so does not require a full review.

***

Very basic implementation of FOCOM operator, which reconciles FOCOM
provisioning requests into oran provisioning requests. This PR contains
very basic functionality based on the POCs explored earlier, and with
the review, more functionality will be added if needed.

Reconciling FOCOM provisioning requests into oran provisioning requests,
will look for correct TemplateInfo referenced in the request. Current
validation only checks if the referenced TemplateInfo exists, with given
name and version. Template parameters are not validated yet, it will be
done in the future. Once the referenced template is validated, reconcile
will proceed to find OCloudId referenced in the request and make sure it
exists. From the OCloudId it will read the secret referenced in the
OCloud.

In this early stage, secret contains kubeconfig for the OCloud cluster,
which will be used to build client to interact with the remote cluster.
Using this client reconciler will produce Oran provisioning requests on
the remote cluster.

Later, this is planned to be changed to support REST-like interface on
the remote cluster, rather then using kubeconfig. Secret in this phase
should be endpoint and bearer token,

Project contains few test samples, using testenv, and there is usual e2e
test from the operator-sdk that can validate operator deployment. This
code is at the POC level, and needs more work to be production ready.

ORAN provisioning request CRD is located inside oran-provisioning-crd
folder. Focom CRDS are generated by operator-sdk/kubebuilder from go
structs in the api folder. Generated yaml files are located in
config/crd/bases.

Current code does not cater for more then one-shot operations, and
patching of ORAN provisioning requests is not supported yet. Validation
of the TemplateInfo parameters is not implemented yet, potentially this
can be done by validating webhook, making them immutable for a start.

---------

Signed-off-by: Fiachra Corcoran <fiachra.corcoran@est.tech>
Signed-off-by: Dejan Kitic <dejan.kitic@ericsson.com>
Co-authored-by: Fiachra Corcoran <fiachra.corcoran@est.tech>
Co-authored-by: Liam Fallon <35595825+liamfallon@users.noreply.github.com>
  • Loading branch information
3 people authored Feb 17, 2025
1 parent a5f4a67 commit 2e13897
Show file tree
Hide file tree
Showing 81 changed files with 4,971 additions and 25 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,7 @@ vendor
go.work
go.work.sum
lcov.info

# go tools artifacts
coverage_unit.html
*-results.html
3 changes: 3 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
run:
build-tags:
- "-buildvcs=false"
timeout: 10m

issues:
exclude-dirs:
- "vendor"
- "test"

exclude-files:
- ".*\\_test.go$"
Expand Down
10 changes: 5 additions & 5 deletions .prow.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ presubmits:
always_run: true
spec:
containers:
- image: nephio/gotests:1817817865340850176
- image: nephio/gotests:1885274380137664512
command:
- make
args:
Expand All @@ -14,7 +14,7 @@ presubmits:
always_run: true
spec:
containers:
- image: nephio/gotests:1817817865340850176
- image: nephio/gotests:1885274380137664512
command:
- make
args:
Expand All @@ -24,7 +24,7 @@ presubmits:
always_run: true
spec:
containers:
- image: nephio/gotests:1817817865340850176
- image: nephio/gotests:1885274380137664512
command:
- make
args:
Expand All @@ -34,7 +34,7 @@ presubmits:
always_run: true
spec:
containers:
- image: nephio/gotests:1817817865340850176
- image: nephio/gotests:1885274380137664512
command:
- "/bin/sh"
- "-c"
Expand Down Expand Up @@ -74,7 +74,7 @@ presubmits:
always_run: true
spec:
containers:
- image: nephio/gotests:1817817865340850176
- image: nephio/gotests:1885274380137664512
command:
- "/usr/local/bin/lichen.sh"

Expand Down
7 changes: 3 additions & 4 deletions default-go-lint.mk
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2023 The Nephio Authors.
# Copyright 2023,2025 The Nephio Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -12,8 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.


GOLANG_CI_VER ?= v1.57
GOLANG_CI_VER ?= v1.63.4
GIT_ROOT_DIR ?= $(dir $(lastword $(MAKEFILE_LIST)))
include $(GIT_ROOT_DIR)/detect-container-runtime.mk

Expand All @@ -22,7 +21,7 @@ include $(GIT_ROOT_DIR)/detect-container-runtime.mk
lint: ## Run Go linter against the codebase
ifeq ($(CONTAINER_RUNNABLE), 0)
$(RUN_CONTAINER_COMMAND) docker.io/golangci/golangci-lint:${GOLANG_CI_VER}-alpine \
golangci-lint run ./... -v
golangci-lint run ./... -v
else
golangci-lint run ./... -v
endif
4 changes: 1 addition & 3 deletions default-go-test.mk
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.


GO_VERSION ?= 1.22.2
TEST_COVERAGE_FILE=lcov.info
TEST_COVERAGE_HTML_FILE=coverage_unit.html
TEST_COVERAGE_FUNC_FILE=func_coverage.out
Expand All @@ -28,7 +26,7 @@ unit: test
.PHONY: test
test: ## Run unit tests (go test)
ifeq ($(CONTAINER_RUNNABLE), 0)
$(RUN_CONTAINER_COMMAND) docker.io/library/golang:${GO_VERSION}-alpine3.19 \
$(RUN_CONTAINER_COMMAND) docker.io/nephio/gotests:1885274380137664512 \
sh -e -c "go test ./... -v -coverprofile ${TEST_COVERAGE_FILE}; \
go tool cover -html=${TEST_COVERAGE_FILE} -o ${TEST_COVERAGE_HTML_FILE}; \
go tool cover -func=${TEST_COVERAGE_FILE} -o ${TEST_COVERAGE_FUNC_FILE}"
Expand Down
6 changes: 3 additions & 3 deletions default-gosec.mk
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@
# See the License for the specific language governing permissions and
# limitations under the License.

GOSEC_VER ?= 2.15.0
GIT_ROOT_DIR ?= $(dir $(lastword $(MAKEFILE_LIST)))
include $(GIT_ROOT_DIR)/detect-container-runtime.mk

# Install link at https://github.com/securego/gosec#install if not running inside a container
.PHONY: gosec
gosec: ## Inspect the source code for security problems by scanning the Go Abstract Syntax Tree
ifeq ($(CONTAINER_RUNNABLE), 0)
$(RUN_CONTAINER_COMMAND) docker.io/securego/gosec:${GOSEC_VER} ./...
$(RUN_CONTAINER_COMMAND) docker.io/nephio/gotests:1885274380137664512 gosec -fmt=html -out=gosec-results.html \
-stdout -verbose=text -exclude-dir=test -exclude-generated ./...
else
gosec ./...
gosec -fmt=html -out=gosec-results.html -stdout -verbose=text -exclude-dir=test -exclude-generated ./...
endif
9 changes: 5 additions & 4 deletions krm-functions/lib/condkptsdk/sdk.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ limitations under the License.
package condkptsdk

import (
"errors"
"fmt"

"github.com/GoogleContainerTools/kpt-functions-sdk/go/fn"
kptfilelibv1 "github.com/nephio-project/nephio/krm-functions/lib/kptfile/v1"
corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -100,9 +100,10 @@ func (r *sdk) Run() (bool, error) {
kfko := r.rl.Items.GetRootKptfile()
if kfko == nil {
msg := "mandatory Kptfile is missing from the package"
fn.Log(msg)
r.rl.Results.Errorf(msg)
return false, fmt.Errorf(msg)
err := errors.New(msg)
fn.Logf("%s, error: %s\n", msg, err.Error())
r.rl.Results.Errorf("%s, error: %s\n", msg, err.Error())
return false, fmt.Errorf(err.Error(), msg)
}
r.kptfile = kptfilelibv1.KptFile{Kptfile: kfko}

Expand Down
12 changes: 6 additions & 6 deletions krm-functions/lib/nad/v1/nad.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ func (r *NadStruct) getNadConfig() (NadConfig, error) {
case VlanClaimOnly:
return nadConfigStruct, nil
case IpVlanType:
if nadConfigStruct.Plugins == nil || len(nadConfigStruct.Plugins) == 0 {
if len(nadConfigStruct.Plugins) == 0 {
nadConfigStruct.Plugins = []PluginCniType{
{
Capabilities: Capabilities{Ips: true},
Expand All @@ -159,7 +159,7 @@ func (r *NadStruct) getNadConfig() (NadConfig, error) {
}
return nadConfigStruct, nil
case MacVlanType:
if nadConfigStruct.Plugins == nil || len(nadConfigStruct.Plugins) == 0 {
if len(nadConfigStruct.Plugins) == 0 {
nadConfigStruct.Plugins = []PluginCniType{
{
Capabilities: Capabilities{Ips: true},
Expand All @@ -178,7 +178,7 @@ func (r *NadStruct) getNadConfig() (NadConfig, error) {
}
return nadConfigStruct, nil
case SriovType:
if nadConfigStruct.Plugins == nil || len(nadConfigStruct.Plugins) == 0 {
if len(nadConfigStruct.Plugins) == 0 {
nadConfigStruct.Plugins = []PluginCniType{
{
Capabilities: Capabilities{
Expand All @@ -193,7 +193,7 @@ func (r *NadStruct) getNadConfig() (NadConfig, error) {
}
return nadConfigStruct, nil
case VlanType:
if nadConfigStruct.Plugins == nil || len(nadConfigStruct.Plugins) == 0 {
if len(nadConfigStruct.Plugins) == 0 {
nadConfigStruct.Plugins = []PluginCniType{
{
Ipam: Ipam{
Expand All @@ -204,7 +204,7 @@ func (r *NadStruct) getNadConfig() (NadConfig, error) {
}
return nadConfigStruct, nil
case BridgeType:
if nadConfigStruct.Plugins == nil || len(nadConfigStruct.Plugins) == 0 {
if len(nadConfigStruct.Plugins) == 0 {
nadConfigStruct.Plugins = []PluginCniType{
{
Ipam: Ipam{
Expand All @@ -215,7 +215,7 @@ func (r *NadStruct) getNadConfig() (NadConfig, error) {
}
return nadConfigStruct, nil
case OtherType:
if nadConfigStruct.Plugins == nil || len(nadConfigStruct.Plugins) == 0 {
if len(nadConfigStruct.Plugins) == 0 {
nadConfigStruct.Plugins = []PluginCniType{
{
Capabilities: Capabilities{
Expand Down
3 changes: 3 additions & 0 deletions operators/focom-operator/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# More info: https://docs.docker.com/engine/reference/builder/#dockerignore-file
# Ignore build and test binaries.
bin/
28 changes: 28 additions & 0 deletions operators/focom-operator/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
bin/*
Dockerfile.cross

# Test binary, built with `go test -c`
*.test
test-data/create-secret.sh
# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Go workspace file
go.work

# Kubernetes Generated files - skip generated files, except for vendored files
!vendor/**/zz_generated.*
bin/*
testbin/*
# editor and IDE paraphernalia
.idea
.vscode
*.swp
*.swo
*~
47 changes: 47 additions & 0 deletions operators/focom-operator/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Copyright 2025 The Nephio Authors.
#
# 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.

# Build the manager binary
FROM golang:1.23 AS builder
ARG TARGETOS
ARG TARGETARCH

WORKDIR /workspace
# Copy the Go Modules manifests
COPY go.mod go.mod
COPY go.sum go.sum
# cache deps before building and copying source so that we don't need to re-download as much
# and so that source changes don't invalidate our downloaded layer
RUN go mod download

# Copy the go source
COPY cmd/main.go cmd/main.go
COPY api/ api/
COPY internal/controller/ internal/controller/

# Build
# the GOARCH has not a default value to allow the binary be built according to the host where the command
# was called. For example, if we call make docker-build in a local env which has the Apple Silicon M1 SO
# the docker BUILDPLATFORM arg will be linux/arm64 when for Apple x86 it will be linux/amd64. Therefore,
# by leaving it empty we can ensure that the container and binary shipped on it will have the same platform.
RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o manager cmd/main.go

# Use distroless as minimal base image to package the manager binary
# Refer to https://github.com/GoogleContainerTools/distroless for more details
FROM gcr.io/distroless/static:nonroot
WORKDIR /
COPY --from=builder /workspace/manager .
USER 65532:65532

ENTRYPOINT ["/manager"]
Loading

0 comments on commit 2e13897

Please # to comment.