vmware-archive / runtimes

Kubeless function runtimes: https://kubeless.io/docs/runtimes/
Apache License 2.0
81 stars 89 forks source link

Missing PATH on kubeless.js runtime #62

Open juanxhos opened 4 years ago

juanxhos commented 4 years ago

Is this a BUG REPORT or FEATURE REQUEST?: BUG REPORT

What happened: When I send request with path ping using kubeless.js middleware it send / instead of the path

What you expected to happen: to send the path requested

How to reproduce it (as minimally and precisely as possible): curl --header "Host: kubernetes.docker.internal.nip.io" localhost/ping and logs says

  'event-type': undefined,
  'event-id': undefined,
  'event-time': undefined,
  'event-namespace': undefined,
  data: {},
  extensions: {
    request: IncomingMessage {
      _readableState: [ReadableState],
      readable: true,
      _events: [Object: null prototype],
      _eventsCount: 1,
      _maxListeners: undefined,
      socket: [Socket],
      connection: [Socket],
      httpVersionMajor: 1,
      httpVersionMinor: 1,
      httpVersion: '1.1',
      complete: false,
      headers: [Object],
      rawHeaders: [Array],
      trailers: {},
      rawTrailers: [],
      aborted: false,
      upgrade: false,
      url: '/',
      method: 'GET',
      statusCode: null,
      statusMessage: null,
      client: [Socket],
      _consuming: false,
      _dumped: false,
      next: [Function: next],
      baseUrl: '',
      originalUrl: '/',
      _parsedUrl: [Url],
      params: [Object],
      query: {},
      res: [ServerResponse],
      _startAt: [Array],
      _startTime: 2020-03-04T15:48:55.191Z,
      _remoteAddress: '::ffff:10.1.0.162',
      body: {},
      route: [Route]
    },
    response: ServerResponse {
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      outputData: [],
      outputSize: 0,
      writable: true,
      _last: false,
      chunkedEncoding: false,
      shouldKeepAlive: true,
      useChunkedEncodingByDefault: true,
      sendDate: true,
      _removedConnection: false,
      _removedContLen: false,
      _removedTE: false,
      _contentLength: null,
      _hasBody: true,
      _trailer: '',
      finished: false,
      _headerSent: false,
      socket: [Socket],
      connection: [Socket],
      _header: null,
      _onPendingData: [Function: bound updateOutgoingData],
      _sent100: false,
      _expect_continue: false,
      req: [IncomingMessage],
      locals: [Object: null prototype] {},
      _startAt: undefined,
      _startTime: undefined,
      writeHead: [Function: writeHead],
      __onFinished: [Function],
      [Symbol(isCorked)]: false,
      [Symbol(outHeadersKey)]: [Object: null prototype]
    }
  }
}
::ffff:10.1.0.162 - - [04/Mar/2020:15:48:55 +0000] "GET / HTTP/1.1" 200 421 "-" "PostmanRuntime/7.20.1"

on AWS, works fine: because there is path sending...

  "message": "Go Serverless v1.0! Your function executed successfully!",
  "input": {
    "resource": "/users/create",
    "path": "/users/create",
    "httpMethod": "GET",
    "headers": {
      "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
      "Accept-Encoding": "gzip, deflate, br",
      "Accept-Language": "es-ES,es;q=0.9,en;q=0.8",
      "CloudFront-Forwarded-Proto": "https",
      "CloudFront-Is-Desktop-Viewer": "true",
      "CloudFront-Is-Mobile-Viewer": "false",
      "CloudFront-Is-SmartTV-Viewer": "false",
      "CloudFront-Is-Tablet-Viewer": "false",
      "CloudFront-Viewer-Country": "CL",
      "dnt": "1",
      "Host": "u5m2ln50ff.execute-api.us-east-1.amazonaws.com",
      "sec-fetch-dest": "document",
      "sec-fetch-mode": "navigate",
      "sec-fetch-site": "none",
      "upgrade-insecure-requests": "1",
      "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36",
      "Via": "2.0 1ddeacce24f5e91d497c9d8a72218fd2.cloudfront.net (CloudFront)",
      "X-Amz-Cf-Id": "l0OoCHP16-AiD4mWWZTppe3U1wRp1_nvKf4SAv2a11VpLJ4SxSW7ZA==",
      "X-Amzn-Trace-Id": "Root=1-5e5fb4f8-ef67231d936e9b9f5229f781",
      "X-Forwarded-For": "186.10.254.186, 130.176.40.155",
      "X-Forwarded-Port": "443",
      "X-Forwarded-Proto": "https"
    },
    "multiValueHeaders": {
      "Accept": [
        "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
      ],
      "Accept-Encoding": [
        "gzip, deflate, br"
      ],
      "Accept-Language": [
        "es-ES,es;q=0.9,en;q=0.8"
      ],
      "CloudFront-Forwarded-Proto": [
        "https"
      ],
      "CloudFront-Is-Desktop-Viewer": [
        "true"
      ],
      "CloudFront-Is-Mobile-Viewer": [
        "false"
      ],
      "CloudFront-Is-SmartTV-Viewer": [
        "false"
      ],
      "CloudFront-Is-Tablet-Viewer": [
        "false"
      ],
      "CloudFront-Viewer-Country": [
        "CL"
      ],
      "dnt": [
        "1"
      ],
      "Host": [
        "u5m2ln50ff.execute-api.us-east-1.amazonaws.com"
      ],
      "sec-fetch-dest": [
        "document"
      ],
      "sec-fetch-mode": [
        "navigate"
      ],
      "sec-fetch-site": [
        "none"
      ],
      "upgrade-insecure-requests": [
        "1"
      ],
      "User-Agent": [
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36"
      ],
      "Via": [
        "2.0 1ddeacce24f5e91d497c9d8a72218fd2.cloudfront.net (CloudFront)"
      ],
      "X-Amz-Cf-Id": [
        "l0OoCHP16-AiD4mWWZTppe3U1wRp1_nvKf4SAv2a11VpLJ4SxSW7ZA=="
      ],
      "X-Amzn-Trace-Id": [
        "Root=1-5e5fb4f8-ef67231d936e9b9f5229f781"
      ],
      "X-Forwarded-For": [
        "186.10.254.186, 130.176.40.155"
      ],
      "X-Forwarded-Port": [
        "443"
      ],
      "X-Forwarded-Proto": [
        "https"
      ]
    },
    "queryStringParameters": null,
    "multiValueQueryStringParameters": null,
    "pathParameters": null,
    "stageVariables": null,
    "requestContext": {
      "resourceId": "j246vp",
      "resourcePath": "/users/create",
      "httpMethod": "GET",
      "extendedRequestId": "I3k21EGcIAMFePA=",
      "requestTime": "04/Mar/2020:14:02:32 +0000",
      "path": "/dev/users/create",
      "accountId": "081356250805",
      "protocol": "HTTP/1.1",
      "stage": "dev",
      "domainPrefix": "u5m2ln50ff",
      "requestTimeEpoch": 1583330552468,
      "requestId": "65f053c2-cd2b-4ecf-a272-d6015ab24bad",
      "identity": {
        "cognitoIdentityPoolId": null,
        "accountId": null,
        "cognitoIdentityId": null,
        "caller": null,
        "sourceIp": "186.10.254.186",
        "principalOrgId": null,
        "accessKey": null,
        "cognitoAuthenticationType": null,
        "cognitoAuthenticationProvider": null,
        "userArn": null,
        "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36",
        "user": null
      },
      "domainName": "u5m2ln50ff.execute-api.us-east-1.amazonaws.com",
      "apiId": "u5m2ln50ff"
    },
    "body": null,
    "isBase64Encoded": false
  }
}

Anything else we need to know?:

I found out in runtime: https://github.com/kubeless/runtimes/blob/master/stable/nodejs/lib/helper.js#L38-L50 there no funtion for * I would expect something like:

function routeAll(expressApp, promClient) {
  expressApp.get('/*', (req, res) => {
    return {req, res}
  });
}

I do not know if it works

Environment:

juanxhos commented 4 years ago

My test escenario https://github.com/jcalonsoh/test-kubeless

andresmgot commented 4 years ago

mm, I am not able to reproduce your issue, are you using an HTTP trigger?

In my case, I have deployed the sample nodejs function and a simple HTTP trigger:

▶ kubeless function deploy get-nodejs --runtime nodejs6 --handler helloget.foo --from-file nodejs/helloget.js
▶ kubeless trigger http create get-nodejs --function-name get-nodejs

I can see the path logged when I am doing requests:

▶ curl -H "Host: get-nodejs.127.0.0.1.nip.io" localhost:30080/foobar
hello world!%                                                                                                                  
▶ kubectl logs get-nodejs-5bd7c8848b-hz5pf | grep foobar            
        url: '/foobar',
        originalUrl: '/foobar',
     url: '/foobar',
     originalUrl: '/foobar',
        pathname: '/foobar',
        path: '/foobar',
        href: '/foobar',
        _raw: '/foobar' },
     params: { '0': '/foobar' },
        url: '/foobar',
        originalUrl: '/foobar',
::ffff:10.244.0.5 - - [05/Mar/2020:10:48:42 +0000] "GET /foobar HTTP/1.1" 200 - "-" "curl/7.58.0"
juanxhos commented 4 years ago

mm, I am not able to reproduce your issue, are you using an HTTP trigger?

In my case, I have deployed the sample nodejs function and a simple HTTP trigger:

▶ kubeless function deploy get-nodejs --runtime nodejs6 --handler helloget.foo --from-file nodejs/helloget.js
▶ kubeless trigger http create get-nodejs --function-name get-nodejs

I can see the path logged when I am doing requests:

▶ curl -H "Host: get-nodejs.127.0.0.1.nip.io" localhost:30080/foobar
hello world!%                                                                                                                  
▶ kubectl logs get-nodejs-5bd7c8848b-hz5pf | grep foobar            
        url: '/foobar',
        originalUrl: '/foobar',
     url: '/foobar',
     originalUrl: '/foobar',
        pathname: '/foobar',
        path: '/foobar',
        href: '/foobar',
        _raw: '/foobar' },
     params: { '0': '/foobar' },
        url: '/foobar',
        originalUrl: '/foobar',
::ffff:10.244.0.5 - - [05/Mar/2020:10:48:42 +0000] "GET /foobar HTTP/1.1" 200 - "-" "curl/7.58.0"

can you share your repo, please and what version are you using ??

andresmgot commented 4 years ago

I am using the helloget example from this repo (I only added a console.log of the request to print more info):

https://github.com/kubeless/runtimes/blob/master/stable/nodejs/examples/helloget.js

I am using kubeless 1.0.6.

In your case, I believe it's an issue with the HTTP trigger/ingress configuration. How did you create it? What ingress controller are you using?

juanxhos commented 4 years ago

Thanks I found out the problem, it's on plugin serverless-kubeless

https://github.com/serverless/serverless-kubeless/blob/master/lib/deploy.js#L533

looks like there is no definition function to create HTTPTrigger

apiVersion: kubeless.io/v1beta1
kind: HTTPTrigger
metadata:
 name: cors-trigger
 annotations:
  nginx.ingress.kubernetes.io/enable-cors: "true"
  nginx.ingress.kubernetes.io/cors-allow-methods: "GET"
spec:
 function-name: get-python
 host-name: example.com
 path: echo

I know there are 3 types of httptrigger, but at least can do something for at least nginx default type ?

andresmgot commented 4 years ago

Ah, yes, the serverless-kubeless creates an Ingress resource directly rather than creating an HTTP Trigger (which is the Kubeless abstraction). I recommend you to use the kubeless CLI to create the HTTP trigger since the serverless plugin is a bit behind regarding functionality.

In any case we are open to contributions for any project in case anyone wants to fix the issue there.

juanxhos commented 4 years ago

Nice... I am looking forward. Better if you have a Doc to setup an dev env for help on issues.

andresmgot commented 4 years ago

We have a bit of documentation for the Kubeless main project (https://kubeless.io/docs/dev-guide/) but unfortunately not here