dot-i / k8s-operator-node Goto Github PK
View Code? Open in Web Editor NEWNodeJS Kubernetes operator framework
License: Apache License 2.0
NodeJS Kubernetes operator framework
License: Apache License 2.0
whoever last committed the lock file committed references to a private verdaccio instance. I am unable to npm i
on my fork until I deleted the lockfile.
npm i
npm ERR! code ENOTFOUND
npm ERR! syscall getaddrinfo
npm ERR! errno ENOTFOUND
npm ERR! network request to https://verdaccio.qover.io/ws/-/ws-8.13.0.tgz failed, reason: getaddrinfo ENOTFOUND verdaccio.qover.io
npm ERR! network This is a problem related to network connectivity.
npm ERR! network In most cases you are behind a proxy or have bad network settings.
npm ERR! network
npm ERR! network If you are behind a proxy, please make sure that the
npm ERR! network 'proxy' config is set properly. See: 'npm help config'
This used to work a couple of months ago ..
I have a file index.mjs contains
import TenantOperator from './modules/operator/tenantoperator.mjs';
var tenantOperator = new TenantOperator();
./modules/operator/tenantoperator.mjs
contains this
import Operator from '@dot-i/k8s-operator';
export default class TenantOperator extends Operator {
constructor() {}
async init() { ... code ... }
}
Node.js V16.18.0 (Same as I had earlier) is now giving this error @dot-i/k8s-operator": "^1.3.5
installed
Uncaught TypeError TypeError: Class extends value #<Object> is not a constructor or null
At first I thought I had a circular reference, but dpdm
says I am good
AL that is changed is that I want form a index.js
to index.mjs
, Im happily importing other commonJS packages
I'm actually stumped at the moment .. Amny suggestions?
Version Info:
Component | Version |
---|---|
Kubernetes | v1.25.3 |
k8s-operator-node | 1.3.5 |
I was unable to update the status of my Custom resource and was alwys presented with the error
{"name":"Error","message":"Request failed with status code 404","stack":"Error: Request failed with status code 404\n at Gaxios._request (/path-to-project/node_modules/gaxios/build/src/gaxios.js:130:23)
I checked debugged and it comes down to the path to the resource that is calling kubernetes api
v1/namespaces/<group>/<crd-plural>/<resource-name>/status
When I rebuilt the request in Insomnia and left out the status at the end of the path the update worked but if you dont patches kills all the content but status in your object as well. I don't know if there has been a change in the kubernetes API but this seems to be a bug at least with the current kubernetes version
Hi,
I have noticed that the watchResource
does not contain any cache which helps while re-listing
and re-watching
k8s resources. This functionality already exists in the underlying kubernetes@client-node
but was surprised to see not being used in this project.
Any idea as to why?
I have this issue in TS with the current latest version and the example from the README:
import Operator, { ResourceEventType, ResourceEvent } from '@dot-i/k8s-operator';
export default class MyOperator extends Operator {
constructor() {
super(/* pass in optional logger*/);
}
protected async init() {
// NOTE: we pass the plural name of the resource
await this.watchResource('dot-i.com', 'v1', 'mycustomresources', async (e) => {
try {
if (e.type === ResourceEventType.Added || e.type === ResourceEventType.Modified) {
if (!await this.handleResourceFinalizer(e, 'mycustomresources.dot-i.com', (event) => this.resourceDeleted(event))) {
await this.resourceModified(e);
}
}
} catch (err) {
// Log here...
}
});
}
private async resourceModified(e: ResourceEvent) {
const object = e.object;
const metadata = object.metadata;
if (!object.status || object.status.observedGeneration !== metadata.generation) {
// TODO: handle resource modification here
await this.setResourceStatus(e.meta, {
observedGeneration: metadata.generation
});
}
}
private async resourceDeleted(e: ResourceEvent) {
// TODO: handle resource deletion here
}
}
Error: Property 'status' does not exist on type 'KubernetesObject'
Code: if (!object.status || object.status.observedGeneration !== metadata.generation)
What is wrong: Errors from @kubernetes/client-node returned as "{}"
Why: Properties of the Error object are not enumerable.
From the documentation of JSON.stringify(),
For all the other Object instances (including Map, Set, WeakMap and WeakSet), only their enumerable properties will be serialized.
Possible solutions:
https://stackoverflow.com/questions/18391212/is-it-not-possible-to-stringify-an-error-using-json-stringify
I'm want to update the status of custom resources outside of event handlers. However, invoking setResourceStatus
requires an instance of ResourceMetaImpl, which is available only in event handlers.
See https://github.com/pfisterer/edsc-dns-domains/blob/f8886556c1644718522913f982953417ac548fff/src/crd-watcher.js#L60 for my use case.
Would it be possible to export ResourceMetaImpl
from the module?
Hi,
there is some kind of incompatibility between k8s versions for the watchResource() observer?
I released an operator that monitors the events of some custom resources and in cluster 1.21.x it works, while in cluster 1.18.x it doesn't.
I get a generic 403 Forbidden error when I try to watch the resources.
The service account with which the operator runs has all verbs enabled and if queried directly, using the same service account, the k8s API respond correctly without any kind of permission problem.
[info][2021-09-03T14:58:27.563Z] [K8S Main Operator] Operator start - undefined
[info][2021-09-03T14:58:27.765Z] watching resource lambdas.company.org/v1 - undefined
[error][2021-09-03T14:58:29.142Z] watch on resource lambdas.company.org/v1 failed: {"name":"Error","message":"Forbidden","stack":"Error: Forbidden\n at Request.<anonymous> (/operator/main.js:159289:35)\n at Request.emit (events.js:400:28)\n at Request../node_modules/request/request.js.Request.onRequestResponse (/operator/main.js:253512:10)\n at ClientRequest.emit (events.js:400:28)\n at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:647:27)\n at HTTPParser.parserOnHeadersComplete (_http_common.js:126:17)\n at TLSSocket.socketOnData (_http_client.js:515:22)\n at TLSSocket.emit (events.js:400:28)\n at addChunk (internal/streams/readable.js:290:12)\n at readableAddChunk (internal/streams/readable.js:265:9)"} - undefined
> kubectl auth can-i --list -n devel --as system:serviceaccount:devel:default
Resources Non-Resource URLs Resource Names Verbs
routes.company.org [] [] [*]
functions.company.org [] [] [*]
lambdas.company.org [] [] [*]
selfsubjectaccessreviews.authorization.k8s.io [] [] [create]
selfsubjectrulesreviews.authorization.k8s.io [] [] [create]
[/api/*] [] [get]
[/api] [] [get]
[/apis/*] [] [get]
[/apis] [] [get]
[/healthz] [] [get]
[/healthz] [] [get]
[/livez] [] [get]
[/livez] [] [get]
[/openapi/*] [] [get]
[/openapi] [] [get]
[/readyz] [] [get]
[/readyz] [] [get]
[/version/] [] [get]
[/version/] [] [get]
[/version] [] [get]
[/version] [] [get]
Some idea?
Thanks!
can you please provide a sample application? :)
that would help me a lot
First of all, thank you for this! This has been really helpful for building an operator in JS.
I was wondering if you can add support for apiextensions.k8s.io/v1
instead of apiextensions.k8s.io/v1beta
. I pulled and tried to modify the Operator class, but when I made that change I was unable to receive any events after the first event.
As the title says, it would be a great feature to be able to filter watchResource
by labels. Perhaps just expose a few of the options available for the watch query params?
e.g.
export type WatchOptions = {
labelSelector: { [key: string]: string; };
}
protected async watchResource(
group: string,
version: string,
plural: string,
onEvent: (event: ResourceEvent) => Promise<void>,
namespace?: string,
options: WatchOptions,
): Promise<void>
I would be happy to work on this and open a PR.
Btw, I'm curious if your implementation is inspired by any existing solution like the Operator SDK?
In the README, it is not annotated where the KubernetesObject
interface comes from in the example where a CRD is declared in TypeScript. After a little bit of searching I realized there is an assumption that developers are also importing @kubernetes/client-node
.
I recommend updating the example code block to include the import statement, like so:
// ADD THIS
import { KubernetesObject } from '@kubernetes/client-node';
export interface MyCustomResource extends KubernetesObject {
spec: MyCustomResourceSpec;
status: MyCustomResourceStatus;
}
export interface MyCustomResourceSpec {
foo: string;
bar?: number;
}
export interface MyCustomResourceStatus {
observedGeneration?: number;
}
When I attempt to update the status on my custom resource, I get the following error:
TypeError: Converting circular structure to JSON
--> starting at object with constructor 'TLSSocket'
| property '_httpMessage' -> object with constructor 'ClientRequest'
--- property 'socket' closes the circle
at JSON.stringify (<anonymous>)
at CompletionOperator.errorToJson (/home/oleg/Programming/main/openshift-copilot-poc/operator-in-JavaScript/node_modules/@dot-i/k8s-operator/dist/operator.js:341:21)
at CompletionOperator.resourceStatusRequest (/home/oleg/Programming/main/openshift-copilot-poc/operator-in-JavaScript/node_modules/@dot-i/k8s-operator/dist/operator.js:332:36)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async CompletionOperator.setResourceStatus (/home/oleg/Programming/main/openshift-copilot-poc/operator-in-JavaScript/node_modules/@dot-i/k8s-operator/dist/operator.js:203:16)
at async CompletionOperator.resourceModified (/home/oleg/Programming/main/openshift-copilot-poc/operator-in-JavaScript/dist/operator.js:82:13)
at async Object.onEvent (/home/oleg/Programming/main/openshift-copilot-poc/operator-in-JavaScript/dist/operator.js:40:21)
at async /home/oleg/Programming/main/openshift-copilot-poc/operator-in-JavaScript/node_modules/@dot-i/k8s-operator/dist/operator.js:96:55
The code throwing this error is the call to this.setResourceStatus
in my resourceModified
method:
await this.setResourceStatus(e.meta, {
observedGeneration: object.metadata.generation,
completion: completion,
}).catch((err) => {
console.log(err);
});
It would be nice if the logger property would be protected
instead of private
; that would allow its use in the init
function.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.