GithubHelp home page GithubHelp logo

openstack-k8s-operators / dataplane-operator Goto Github PK

View Code? Open in Web Editor NEW
3.0 3.0 46.0 3.02 MB

Operator for OpenStack Dataplane

Home Page: https://openstack-k8s-operators.github.io/dataplane-operator/

License: Apache License 2.0

Dockerfile 0.87% Makefile 6.59% Go 83.53% Shell 0.89% Jinja 8.03% Ruby 0.08%

dataplane-operator's People

Contributors

abays avatar booxter avatar bshephar avatar bshewale avatar cschwede avatar dependabot[bot] avatar dprince avatar fao89 avatar fultonj avatar gibizer avatar jlarriba avatar jpodivin avatar kajinamit avatar karelyatin avatar luis5tb avatar olliewalsh avatar openshift-ci[bot] avatar openshift-merge-bot[bot] avatar openshift-merge-robot avatar pablintino avatar rabi avatar raukadah avatar rebtoor avatar sandeepyadav93 avatar seanmooney avatar slagle avatar slawqo avatar steveb avatar stuggi avatar vakwetu avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dataplane-operator's Issues

dataplane operator loops on role reconcile due to self update of deploy stragey field

if a contoler updates its own spec filed on an instance it will trigger a reconcile

the dataplen role controller sets the deploy stragey filed to false explicitly after deployment is compelted

// Explicitly set instance.Spec.Deploy = false
// We don't want another deploy triggered by any reconcile request, it should
// only be triggered when the user (or another controller) specifically
// sets it to true.
logger.Info("Set DeployStrategy.Deploy to false")
instance.Spec.DeployStrategy.Deploy = false

to prevent this we either need to stop updating the CR we are reconsiling outside the status filed
or we need to check instance.Status.Deployed

https://github.com/openstack-k8s-operators/dataplane-operator/blob/0efa4a48fc8ab796158ff12d549b9ae94108f909/controllers/openstackdataplanerole_controller.go#L329C6-L329C6

and early out of the reconsile function here
before the defer function.

role controller panics when the secret is not found

I try to apply the sample dataplane_v1beta1_openstackdataplanerole.yaml which has no ssh secret defined, it resulted in a panic:

2023-03-17T10:57:14Z	INFO	Observed a panic in reconciler: runtime error: invalid memory address or nil pointer dereference	{"controller": "openstackdataplanerole", "controllerGroup": "dataplane.openstack.org", "controllerKind": "OpenStackDataPlaneRole", "OpenStackDataPlaneRole": {"name":"openstackdataplanerole-sample","namespace":"openstack"}, "namespace": "openstack", "name": "openstackdataplanerole-sample", "reconcileID": "cf107eb6-f69b-4efe-8bde-5327b6b1c3cc"}
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
	panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x48 pc=0x15de837]

goroutine 479 [running]:
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Reconcile.func1()
	/go/pkg/mod/sigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:119 +0x1fa
panic({0x17a2320, 0x287a120})
	/usr/local/go/src/runtime/panic.go:884 +0x212
github.com/openstack-k8s-operators/dataplane-operator/controllers.(*OpenStackDataPlaneRoleReconciler).Reconcile.func1()
	/remote-source/controllers/openstackdataplanerole_controller.go:147 +0x177
github.com/openstack-k8s-operators/dataplane-operator/controllers.(*OpenStackDataPlaneRoleReconciler).Reconcile(0xc0007a9200, {0x1c3ccd8, 0xc000804660}, {{{0xc0007e3e30?, 0x10?}, {0xc000500640?, 0x40da67?}}})
	/remote-source/controllers/openstackdataplanerole_controller.go:173 +0x1502
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Reconcile(0x1c3ccd8?, {0x1c3ccd8?, 0xc000804660?}, {{{0xc0007e3e30?, 0x16dbc00?}, {0xc000500640?, 0x0?}}})
	/go/pkg/mod/sigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:122 +0xc8
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).reconcileHandler(0xc00047ea00, {0x1c3cc30, 0xc0007a8140}, {0x1816b40?, 0xc000684140?})
	/go/pkg/mod/sigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:323 +0x38f
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).processNextWorkItem(0xc00047ea00, {0x1c3cc30, 0xc0007a8140})
	/go/pkg/mod/sigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:274 +0x1d9
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Start.func2.2()
	/go/pkg/mod/sigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:235 +0x85
created by sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Start.func2
	/go/pkg/mod/sigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:231 +0x333

I think it is related to the stauts.condition handling during the defer function but I did not looked at it deeply.

Implement validation webhook call forwarding to OpenStackBaremetalSetSpec

The OpenStackBaremetalSet CR has its own validation webhook. The OpenStackBaremetalSetSpec is included in the OpenStackDataPlaneRoleSpec validation of the OpenStackDataPlaneRoleSpec should also cal the validation of the OpenStackBaremetalSetSpec so that the user can get the validation issues right at the API response when creating OpenStackDataPlaneRole CR.

There is documented pattern to follow, see: openstack-k8s-operators/docs#47

// +kubebuilder:validation:Optional
// BaremetalSetTemplate Template for BaremetalSet for the Role
BaremetalSetTemplate baremetalv1.OpenStackBaremetalSetSpec `json:"baremetalSetTemplate,omitempty"`

Action Required: Fix Renovate Configuration

There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.

Error type: Cannot find preset's package (github>openstack-k8s-operators/renovate-config)

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

This repository currently has no open or pending branches.

Detected dependencies

gomod
api/go.mod
  • github.com/openstack-k8s-operators/infra-operator/apis v0.3.1-0.20240327192142-3a7330c5f527@3a7330c5f527
  • github.com/openstack-k8s-operators/lib-common/modules/common v0.3.1-0.20240326081751-56015b1ae3f6@56015b1ae3f6
  • github.com/openstack-k8s-operators/lib-common/modules/storage v0.3.1-0.20240326081751-56015b1ae3f6@56015b1ae3f6
  • github.com/openstack-k8s-operators/openstack-baremetal-operator/api v0.3.1-0.20240327125944-20c4db02e417@20c4db02e417
  • k8s.io/api v0.28.8
  • k8s.io/apimachinery v0.28.8
  • sigs.k8s.io/controller-runtime v0.16.5
  • github.com/cert-manager/cert-manager v1.13.5
  • github.com/go-playground/validator/v10 v10.19.0
  • github.com/go-logr/logr v1.4.1
  • github.com/onsi/ginkgo/v2 v2.17.1
  • github.com/onsi/gomega v1.32.0
  • k8s.io/apiextensions-apiserver v0.28.8
  • k8s.io/client-go v0.28.8
  • k8s.io/component-base v0.28.8
  • k8s.io/klog/v2 v2.110.1
  • k8s.io/utils v0.0.0-20240310230437-4693a0247e57@4693a0247e57
go.mod
  • github.com/cert-manager/cert-manager v1.13.5
  • github.com/go-logr/logr v1.4.1
  • github.com/go-playground/validator/v10 v10.19.0
  • github.com/google/uuid v1.6.0
  • github.com/iancoleman/strcase v0.3.0
  • github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.4.0
  • github.com/onsi/ginkgo/v2 v2.17.1
  • github.com/onsi/gomega v1.32.0
  • github.com/openstack-k8s-operators/infra-operator/apis v0.3.1-0.20240327192142-3a7330c5f527@3a7330c5f527
  • github.com/openstack-k8s-operators/lib-common/modules/ansible v0.3.1-0.20240326081751-56015b1ae3f6@56015b1ae3f6
  • github.com/openstack-k8s-operators/lib-common/modules/certmanager v0.0.0-20240326081751-56015b1ae3f6@56015b1ae3f6
  • github.com/openstack-k8s-operators/lib-common/modules/common v0.3.1-0.20240326081751-56015b1ae3f6@56015b1ae3f6
  • github.com/openstack-k8s-operators/lib-common/modules/storage v0.3.1-0.20240326081751-56015b1ae3f6@56015b1ae3f6
  • github.com/openstack-k8s-operators/lib-common/modules/test v0.3.1-0.20240326081751-56015b1ae3f6@56015b1ae3f6
  • github.com/openstack-k8s-operators/openstack-ansibleee-operator/api v0.3.1-0.20240328134020-bd54c1a833b8@bd54c1a833b8
  • github.com/openstack-k8s-operators/openstack-baremetal-operator/api v0.3.1-0.20240327125944-20c4db02e417@20c4db02e417
  • gopkg.in/yaml.v3 v3.0.1
  • k8s.io/api v0.28.8
  • k8s.io/apimachinery v0.28.8
  • k8s.io/client-go v0.28.8
  • k8s.io/utils v0.0.0-20240310230437-4693a0247e57@4693a0247e57
  • sigs.k8s.io/controller-runtime v0.16.5
  • go.uber.org/zap v1.27.0
  • k8s.io/apiextensions-apiserver v0.28.8
  • k8s.io/component-base v0.28.8
  • k8s.io/klog/v2 v2.110.1

DeployStrategy is not consistent between OpenstackDataplane to OpenStackDataplaneNode

I deployed the OpenstackDataPlane sample from the repo and I got the following result:

$ oc get -o yaml   OpenstackDataPlane
apiVersion: v1
items:
- apiVersion: dataplane.openstack.org/v1beta1
  kind: OpenStackDataPlane
  metadata:
    annotations:
[...snip...]
  spec:
    deployStrategy:
      deploy: true
    nodes:
      edpm-compute-0:
        ansibleHost: 192.168.122.100
        deployStrategy:
          deploy: false
        hostName: edpm-compute-0
        node:
          ansibleSSHPrivateKeySecret: dataplane-ansible-ssh-private-key-secret
          ansibleVars: |
            tenant_ip: 192.168.122.100
        openStackAnsibleEERunnerImage: quay.io/openstack-k8s-operators/openstack-ansibleee-runner:latest
        role: edpm-compute
    roles:
      edpm-compute:
        deployStrategy:
          deploy: false
$ oc get -o yaml   OpenstackDataPlaneNode
apiVersion: v1
items:
- apiVersion: dataplane.openstack.org/v1beta1
  kind: OpenStackDataPlaneNode
  metadata:
    creationTimestamp: "2023-03-21T11:56:06Z"
    generation: 1
    labels:
      openstackdataplanerole: edpm-compute
    name: edpm-compute-0
    namespace: openstack
    resourceVersion: "139974"
    uid: 3fd5246e-ce4d-4397-9789-50647846ef61
  spec:
    ansibleHost: 192.168.122.100
    deployStrategy:
      deploy: false

The deployStrategy is different on the top level than in the lower layers.

This shows two things:

  1. the deployStrategy is not propagated from OpenstackDataplane to OpenStackDataplaneNode (and probably Role)
  2. the defaulting behavior of deployStrategy is broken as the original sample I applied contains
spec:
  deployStrategy:
      deploy: false

but the resulting CR contains:

  spec:
    deployStrategy:
      deploy: true

Dataplane status is wrongly set to ready when initialized

I've observed the following behavior when watching the dataplane resource

[dpadev@osp-dev-05 devsetup]$ oc get osdp -w
NAME        STATUS   MESSAGE
openstack            
openstack   Unknown   Init
openstack   True      DataPlane ready
openstack   True      DataPlane ready
openstack   False     Deployment in progress
openstack   True      DataPlane ready

When OpenStackDataPlane is deleted the child OpenStackDataPlaneRole and OpenStackDatalPlaneNode CRs are not deleted.

It seems neither CreateDataPlaneNode and CreateDataPlaneRole set controller reference to the created resource:

func CreateDataPlaneNode(ctx context.Context, instance *dataplanev1beta1.OpenStackDataPlane, helper *helper.Helper) error {
client := helper.GetClient()
logger := helper.GetLogger()
for nodeName, nodeSpec := range instance.Spec.Nodes {
node := &dataplanev1beta1.OpenStackDataPlaneNode{
ObjectMeta: metav1.ObjectMeta{
Name: nodeName,
Namespace: instance.Namespace,
},
}
nodeSpec.DeepCopyInto(&node.Spec)
err := client.Get(ctx, types.NamespacedName{Name: node.Name, Namespace: instance.Namespace}, node)
if err != nil && !k8s_errors.IsNotFound(err) {
logger.Info("Failed to get Node", "Node.Namespace", instance.Namespace, "Node.Name", node.Name)
return err
}
if k8s_errors.IsNotFound(err) {
err := client.Create(ctx, node)
if err != nil {
logger.Info("Failed to create Node", "Node.Namespace", instance.Namespace, "Node.Name", node.Name)
return err
}
}
}
return nil
}
// CreateDataPlaneRole -
func CreateDataPlaneRole(ctx context.Context, instance *dataplanev1beta1.OpenStackDataPlane, helper *helper.Helper) error {
client := helper.GetClient()
logger := helper.GetLogger()
for roleName, roleSpec := range instance.Spec.Roles {
role := &dataplanev1beta1.OpenStackDataPlaneRole{
ObjectMeta: metav1.ObjectMeta{
Name: roleName,
Namespace: instance.Namespace,
},
}
roleSpec.DeepCopyInto(&role.Spec)
if len(role.Spec.DataPlane) == 0 {
role.Spec.DataPlane = instance.Name
}
err := client.Get(ctx, types.NamespacedName{Name: role.Name, Namespace: instance.Namespace}, role)
if err != nil && !k8s_errors.IsNotFound(err) {
logger.Info("Failed to get Role", "Role.Namespace", instance.Namespace, "Role.Name", role.Name)
return err
}
if k8s_errors.IsNotFound(err) {
err := client.Create(ctx, role)
if err != nil {
logger.Info("Failed to create Role", "Role.Namespace", instance.Namespace, "Role.Name", role.Name)
return err
}
}
}
return nil
}

I also noticed that these functions use client.Create which means this code cannot update the already created resource in a later reconciliation. I suggest to use controllerutil.CreateOrPatch instead of the simple Create.

Implement validation webhook call forwarding to IpSet

The IpSet CR has validation webhook implemented. The DataPlaneRole and Node includes a list of infranetworkv1.IPSetNetwork in its definition. So the DataPlaneRole and Node validation webhook needs to call the parts of the IPSet validation webhook logic so that the user can get immediate feedback during the DataPlaneRole / Node creation in case the input is invalid.

nets := node.Spec.Node.Networks
if len(nets) == 0 {
nets = instance.Spec.NodeTemplate.Networks
}
if len(nets) > 0 {
util.LogForObject(helper, "Reconciling IPSet", instance)
ipSet := &infranetworkv1.IPSet{
ObjectMeta: metav1.ObjectMeta{
Namespace: instance.Namespace,
Name: node.Name,
},
}
_, err := controllerutil.CreateOrPatch(ctx, helper.GetClient(), ipSet, func() error {
ipSet.Spec.Networks = nets
// Set controller reference to the DataPlaneNode object
err := controllerutil.SetControllerReference(
helper.GetBeforeObject(), ipSet, helper.GetScheme())
return err
})
if err != nil {
return nil, err
}
allIPSets[node.Name] = *ipSet

the ssh private key secret shoudl be of type 'kubernetes.io/ssh-auth'

currently we are using a generic secret for the ansible ssh key we should use --type 'kubernetes.io/ssh-auth'

this requires the private and public keys to have a specific name "ssh-privatekey" and "ssh-publickey"

https://kubernetes.io/docs/concepts/configuration/secret/#use-case-pod-with-ssh-keys

currently we use ssh_private_key

// +kubebuilder:validation:Optional
// +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:io.kubernetes:Secret"}
// AnsibleSSHPrivateKeySecret Private SSH Key secret containing private SSH
// key for connecting to node. Must be of the form:
// Secret.data.ssh_private_key: <base64 encoded private key contents>
AnsibleSSHPrivateKeySecret string `json:"ansibleSSHPrivateKeySecret"`

which is allowed because we were using generic secret types but is not following standard convention.

we should adapt to 'kubernetes.io/ssh-auth' instead.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.