operator-framework / operator-sdk

SDK for building Kubernetes applications. Provides high level APIs, useful abstractions, and project scaffolding.
https://sdk.operatorframework.io
Apache License 2.0
7.2k stars 1.74k forks source link

Svc not upport customize namespace #6553

Closed UmfintechWtc closed 7 months ago

UmfintechWtc commented 1 year ago

Bug Report

What did you do?

i specify namespace with spec.namespace, not metadata.namespace, because i want to customize the namespace, like "lweim" ns

What did you expect to see?

nginx_v1_nginx.yaml

specify namespace with spec.namespace


apiVersion: nginx.wtc.com/v1
kind: Nginx
metadata:
annotations:
version: 1.1.1
labels:
app.kubernetes.io/name: nginx-TesdLablesUpdate
app.kubernetes.io/managed-by: tianciwang
name: nginx-sample
spec:
namespace: lweim
image: nginx:latest
replicas: 1
imagePullPolicy: Always
command: ["/usr/sbin/nginx"]
args: ["-g", "daemon off;"]
env:
- name: TianCiwang-20230813
value: TianCiwang-Test-OperatorSDK-20230813
- name: Company
value: Starcross
resources:
cpu:
requests: "600m"
limits: "700m"
memory:
requests: "100Mi"
limits: "100Mi"
ports:
- port: 8900
targetPort: 80
nodePort: 8900
protocol: TCP
nginx_types.go
> i can get customize namespace with spec.namespace
```golang
type NginxSpec struct {
    // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
    // Important: Run "make" to regenerate code after modifying this file
    // Foo is an example field of Nginx. Edit nginx_types.go to remove/update
    Replicas        *int32               `json:"replicas"`
    Image           string               `json:"image"`
    Ports           []corev1.ServicePort `json:"ports,omitempty"`
    ImagePullPolicy corev1.PullPolicy    `json:"imagePullPolicy,omitempty"`
    Command         []string             `json:"command,omitempty"`
    Args            []string             `json:"args,omitempty"`
    Env             []corev1.EnvVar      `json:"env,omitempty"`
    Namespace       string               `json:"namespace,omitempty"`
    ResourceConfig  Resources            `json:"resources"`
}

type Nginx struct {
    metav1.TypeMeta   `json:",inline"`
    metav1.ObjectMeta `json:"metadata,omitempty"`
    Spec              NginxSpec   `json:"spec,omitempty"`
    Status            NginxStatus `json:"status,omitempty"`
}

nginx_controller.go

nginx.ObjecteMate.Namespace is lweim

func (r *NginxReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
log.Infof("Starting............................")
// init nginx resources
nginx := &nginxv1.Nginx{}
// Check Nginx Resources with default namespace, for init nginx resources
r.Get(context.TODO(), req.NamespacedName, nginx)
err := r.Get(context.TODO(), req.NamespacedName, nginx)
if err != nil {
if errors.IsNotFound(err) {
log.Info("Nginx resource not found. Ignoring since object must be deleted")
return ctrl.Result{}, nil
}
log.Error(err, "Failed to get Nginx Resources")
return ctrl.Result{}, err
}
// Create Service NameSpace
req.NamespacedName.Namespace = nginx.Spec.Namespace
nginx.ObjectMeta.Namespace = nginx.Spec.Namespace
newNsMetaData := namespace.NameSpaceForNginx(nginx)
err = r.Create(context.TODO(), newNsMetaData)
if err != nil && errors.IsAlreadyExists(err) {
log.Infof("[%v] namespace already exists. ", nginx.ObjectMeta.Namespace)
} else if err != nil {
log.Errorf("Failed create [%v] namespace. errors: %v ", nginx.ObjectMeta.Namespace, err)
} else {
log.Infof("Successfully create [%v] namespace. ", nginx.ObjectMeta.Namespace)
}
// Create Service Svc
oldSvcMetaData, svcTypes := service.CheckServiceMeta(nginx)
err = r.Get(context.TODO(), svcTypes, oldSvcMetaData)
newSvcMetaData := service.NodePortForNginx(nginx)
if err != nil && errors.IsNotFound(err) {
log.Warnf("Not found svc [%v] with [%v] namespace, it will be to creating", nginx.Name, nginx.Spec.Namespace)
if err = r.Create(context.TODO(), newSvcMetaData); err != nil {
log.Errorf("Failed to create svc [%v] with [%v] namespace , errors: [%v]", nginx.Name, nginx.Spec.Namespace, err)
} else {
log.Infof("Successfully create svc [%v] with [%v] namespace. ", nginx.Name, nginx.Spec.Namespace)
}
return ctrl.Result{}, err
}

service.go i think Namespace: service.ObjectMeta.Namespace is lweim


var (
Port       *int32
TargetPort *intstr.IntOrString
NodePort   *int32
)

func NodePortForNginx(service nginxv1.Nginx) corev1.Service {

nports := service.Spec.Ports
for _, port := range nports {
    Port = &port.Port
    NodePort = &port.NodePort
    TargetPort = &port.TargetPort
}
return &corev1.Service{
    TypeMeta: metav1.TypeMeta{
        Kind:       "Service",
        APIVersion: service.APIVersion,
    },
    ObjectMeta: metav1.ObjectMeta{
        Name:      service.ObjectMeta.Name,
        Namespace: service.ObjectMeta.Namespace,  // even write "lweim"  not ok 
        OwnerReferences: []metav1.OwnerReference{
            *metav1.NewControllerRef(service, schema.GroupVersionKind{
                Group:   nginxv1.GroupVersion.Group,
                Version: nginxv1.GroupVersion.Version,
                Kind:    "Nginx",
            }),
        },
        Annotations: service.ObjectMeta.Annotations,
        Labels:      service.ObjectMeta.Labels,
    },
    Spec: corev1.ServiceSpec{
        Ports: []corev1.ServicePort{
            {
                Name:       "http",
                Port:       *Port,
                NodePort:   *NodePort,
                TargetPort: *TargetPort,
                Protocol:   corev1.ProtocolTCP,
            },
        },
        Selector: service.ObjectMeta.Labels,
        Type:     corev1.ServiceTypeNodePort,
    },
}

}

> create svc i want in lweim namespace, but not exists
> I have found that when a namespace is not specified under metadata in yaml, svc creation fails. When a namespace is specified, svc creation succeeds, like metadata.namespace: lweim

#### Environment
```text
[root@k8s-master-1:operator-sdk-example-with-nginx_0]# cat /etc/os-release 
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"

Operator type:

operator-sdk
use with operator-sdk init

Kubernetes cluster type:

[root@k8s-master-1:operator-sdk-example-with-nginx_0]# kubectl version
Client Version: version.Info{Major:"1", Minor:"23", GitVersion:"v1.23.9", GitCommit:"c1de2d70269039fe55efb98e737d9a29f9155246", GitTreeState:"clean", BuildDate:"2022-07-13T14:26:51Z", GoVersion:"go1.17.11", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"23", GitVersion:"v1.23.9", GitCommit:"c1de2d70269039fe55efb98e737d9a29f9155246", GitTreeState:"clean", BuildDate:"2022-07-13T14:19:57Z", GoVersion:"go1.17.11", Compiler:"gc", Platform:"linux/amd64"}

$ operator-sdk version

[root@k8s-master-1:operator-sdk-example-with-nginx_0]# operator-sdk version
operator-sdk version: "v1.30.0", commit: "b794fe909abc1affa1f28cfb75ceaf3bf79187e6", kubernetes version: "1.26.0", go version: "go1.19.10", GOOS: "linux", GOARCH: "amd64"

$ go version (if language is Go)

[root@k8s-master-1:operator-sdk-example-with-nginx_0]# go version go version go1.20 linux/amd64

$ kubectl version

[root@k8s-master-1:operator-sdk-example-with-nginx_0]# kubectl version
Client Version: version.Info{Major:"1", Minor:"23", GitVersion:"v1.23.9", GitCommit:"c1de2d70269039fe55efb98e737d9a29f9155246", GitTreeState:"clean", BuildDate:"2022-07-13T14:26:51Z", GoVersion:"go1.17.11", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"23", GitVersion:"v1.23.9", GitCommit:"c1de2d70269039fe55efb98e737d9a29f9155246", GitTreeState:"clean", BuildDate:"2022-07-13T14:19:57Z", GoVersion:"go1.17.11", Compiler:"gc", Platform:"linux/amd64"}
acornett21 commented 1 year ago

Hi @UmfintechWtc I'm not sure I understand the question. It seems like you want to move metadata.namespace to spec.namespace. but pre K8s API conventions spec.namespace is required on every object that is created. This isn't an operator-sdk convention this is a K8's convention . I hope this helps

varshaprasad96 commented 1 year ago

+1 to what @acornett21 mentioned. Also, could you elaborate on what you mean by "customizing namespace". I would highly discourage from doing req.NamespacedName.Namespace = nginx.Spec.Namespace -- the request has already been added to the queue based on what namespaces are being watched by the controller. There is no use of over-writing them, and they shouldn't be overwritten either.

openshift-bot commented 9 months ago

Issues go stale after 90d of inactivity.

Mark the issue as fresh by commenting /remove-lifecycle stale. Stale issues rot after an additional 30d of inactivity and eventually close. Exclude this issue from closing by commenting /lifecycle frozen.

If this issue is safe to close now please do so with /close.

/lifecycle stale

openshift-bot commented 8 months ago

Stale issues rot after 30d of inactivity.

Mark the issue as fresh by commenting /remove-lifecycle rotten. Rotten issues close after an additional 30d of inactivity. Exclude this issue from closing by commenting /lifecycle frozen.

If this issue is safe to close now please do so with /close.

/lifecycle rotten /remove-lifecycle stale

openshift-bot commented 7 months ago

Rotten issues close after 30d of inactivity.

Reopen the issue by commenting /reopen. Mark the issue as fresh by commenting /remove-lifecycle rotten. Exclude this issue from closing again by commenting /lifecycle frozen.

/close

openshift-ci[bot] commented 7 months ago

@openshift-bot: Closing this issue.

In response to [this](https://github.com/operator-framework/operator-sdk/issues/6553#issuecomment-1936922482): >Rotten issues close after 30d of inactivity. > >Reopen the issue by commenting `/reopen`. >Mark the issue as fresh by commenting `/remove-lifecycle rotten`. >Exclude this issue from closing again by commenting `/lifecycle frozen`. > >/close Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md). If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository.