Getting node-config related typescript error when compiling - node-config

I have a expressjs project running Typescript and also using the node-config package.
When i try and compile my typescript with:
./node_modules/.bin/tsc --project ./server/tsconfig.json
I get the following type error:
server/index.ts(15,33): error TS2345: Argument of type '{ name: {}; dialect: string; host: {}; port: {}; username: {}; password: {}; validateOnly: false; }' is not assignable to parameter of type 'ISequelizeConfig | ISequelizeValidationOnlyConfig'.
Type '{ name: {}; dialect: string; host: {}; port: {}; username: {}; password: {}; validateOnly: false; }' is not assignable to type 'ISequelizeConfig'.
Types of property 'name' are incompatible.
Type '{}' is not assignable to type 'string'.
Can anyone help me to see why this is failing?
Thanks

Related

Parse YAML using shell

I have a yaml something of this sort and need to parse and get the value of 'url' here.
name: Yaml_Test
servers:
- name: host_ip
host: host_name
port: 443
scheme: https
variables:
- constant:
name: url
value: https://url_here
With the current versions of both kislyuk/yq and mikefarah/yq, use select to filter the array items:
.variables[].constant | select(.name == "url").value
https://url_here
Using kislyuk/yq, you may want to add the -r option to output raw text:
yq -r '…' file.yaml
Using an older version of mikefarah/yq, you need to specify the command e or eval:
yq e '…' file.yaml
Edit: Although not recommended, here's as requested in a comment a grep-only solution which heavily relies on how the YAML document is represented textually, based on the sample provided (i.e. no other occurrence of name: url etc.):
grep -A1 'name: url' file.yaml | grep -o 'http.*'
https://url_here

OpenAPI v3 / Swagger - calling a function and sending json dictionary to it

I'm trying to use OpenAPI/Swagger to run an endpoint capable of consuming a json dictionary, sending to a function and getting a response.
I'm using operationId to refer to the function that I want to call, but can't work out how to send the dictionary that's received by the endpoint.
controllers.get_options is called, but no parameters are sent to it with my current approach.
I think I'm missing something obvious, but it's not apparent!
I would call the endpoint like this:
curl -X 'POST' \
'http://localhost:8080/getoptions' \
-H 'accept: */*' \
-H 'Content-Type: application/json' \
-d '{
"product_area": "Main",
"product_type": "New"
}'
This is the openapi config file (./openapi.yaml)
EDIT: adding x-body-name: DiscussionResult below solved the issue as per Helen's comment
openapi: 3.0.0
info:
title: Test
version: '1.0'
paths:
/getoptions:
post:
description: Return product options from product type and area
operationId: controllers.get_options
requestBody:
required: true
content:
application/json:
x-body-name: DiscussionResult
schema:
$ref: '#/components/schemas/DiscussionResult'
responses:
200:
description: "success"
components:
schemas:
DiscussionResult:
type: object
discriminator:
propertyName: product_type
properties:
product_type:
type: string
example: "New"
product_area:
type: string
example: "Main"
I'm running it using connexion as shown here:
main.py
import connexion
import logging
def create_app():
logging.basicConfig(level=logging.DEBUG)
connex_app = connexion.FlaskApp(__name__, specification_dir="./openapi/")
connex_app.add_api("./openapi.yaml", resolver_error=501)
return connex_app
if __name__ == "__main__":
app = create_app()
app.run(host="0.0.0.0", port=8080)
requirements.txt
connexion[swagger-ui]
connexion>=2.2.0
python-jose[cryptography]
six>=1.9
Flask>=0.10.1
sqlathanor
and this is the function that I want to call
def get_options(DiscussionResult):
msg = "{} {}".format(DiscussionResult['product_area'], DiscussionResult['product_type'])
return jsonify(message=msg), 200
Connexion docs on Request Handling include the following note:
In the OpenAPI 3.x.x spec, the requestBody does not have a name. By default it will be passed in as ‘body’. You can optionally provide the x-body-name parameter in your requestBody schema to override the name of the parameter that will be passed to your handler function.
Looks like you need to add x-body-name: DiscussionResult to the DiscussionResult schema that is used in the requestBody:
components:
schemas:
DiscussionResult:
x-body-name: DiscussionResult # <---------
type: object
...
or
requestBody:
required: true
content:
application/json:
schema:
x-body-name: DiscussionResult # <---------
$ref: '#/components/schemas/DiscussionResult'
I'd very much recommend FastApi as I already said in the comments earlier. Here is a little bit of a working code.
main.py
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class DetailsModel(BaseModel):
product_area: str
product_type: str
#app.post("/get_details")
async def _(
input_json: DetailsModel
):
return {"returns": input_json.dict()}
Run uvicorn main:app --reload from root directory
Then check http://127.0.0.1:8000/docs
Then you can call:
curl -X 'POST' \
'http://127.0.0.1:8000/get_details' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"product_area": "Main",
"product_type": "New"
}'
Fastapi checks for any unprocessable entities with Pydantic which helps a lot with any requests that doesn't fit the model.
Check the official and very detailed documentation too https://fastapi.tiangolo.com/.

Ansible, jenkins_script module and problem with args

I am using this module: https://docs.ansible.com/ansible/latest/collections/community/general/jenkins_script_module.html
And I want to pass arguments(dictionary: jenkins_username_password_credentials) to my Groovy script that can change credentials on Jenkins:
#! / usr / bin / env groovy
import jenkins.model.Jenkins
import com.cloudbees.plugins.credentials.domains.Domain
import org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl
import com.cloudbees.plugins.credentials.CredentialsScope
import hudson.util.Secret
import com.cloudbees.jenkins.plugins.sshcredentials.impl.BasicSSHUserPrivateKey
import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl
instance = Jenkins.instance
domain = Domain.global ()
store = instance.getExtensionList (
"com.cloudbees.plugins.credentials.SystemCredentialsProvider") [0] .getStore ()
{% for credential in jenkins_username_password_credentials%}
usernameAndPassword = new UsernamePasswordCredentialsImpl (
CredentialsScope.GLOBAL,
"{{credential ['name']}}",
"{{credential ['description']}}",
"{{credential ['username']}}",
"{{credential ['password']}}"
)
store.addCredentials (domain, usernameAndPassword)
{% endfor%}
I do it through the given code:
- name: Upload Nexus credentials
jenkins_script:
url: "{{jenkins_url}}"
script: '{{lookup ("template", "templates / jenkins_groovy / credentials / secret_password.groovy")}}'
args:
jenkins_username_password_credentials:
- name: Nexus
description: Credentials for Nexus Server
username: Nexus
password: 25447
user: '{{jenkins_username}}'
password: '{{jenkins_password}}'
validate_certs: false
timeout: "120"
But I have an error that my variable jenkins_username_password_credentials is undefined until I add it to the defaults file in my role.
fatal: [jenkins_linux]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'jenkins_username_password_credentials' is undefined \ n \ nThe error appears to be in' / home / tbaburin / Ansible / roles / jenkins / tasks / main.yml ': line 3, column 3, but may \ nbe elsewhere in the file depending on the exact syntax problem. \ n \ nThe offending line appears to be: \ n \ n \ n- name: Upload Nexus credentials \ n ^ here \ n "}
My questions are:
Can I declare a dictionary directly in the "args" field of the jenkins_script module like in the example? https://docs.ansible.com/ansible/latest/collections/community/general/jenkins_script_module.html
If I can't, how can I change the dictionary in the "args" field so that the modified dictionary with the data I need is loaded into the script?
I just don't want to always go into the default file and change the dictionary data there to load different credentials and I want just to pass some j2 variables into args just to loop this, if I want to upload a lot of credentials.

How to install PostGIS within a Nix environment

I have the following shell.nix (to setup my development environment, no NixOS):
with import <nixpkgs> {};
stdenv.mkDerivation {
name = "my-shiny-project";
buildInputs = [
jq
nodejs-6_x
#postgis {version="2.3.1";}
#postgis ("2.3.1")
#postgis "2.3.1"
postgresql96
zsh
];
shellHook = ''
export SHELL=zsh
export PATH="$PWD/node_modules/.bin/:$PATH"
'';
}
PostGIS expects a version parameter. I'm not sure how to pass that parameter along. Whether I use postgis{version="2.3.1";}, postgis("2.3.1") or postgis "2.3.1", I receive the following error:
error: cannot coerce a set to a string, at /nix/store/0rj9y7gvzzahp93cvdmrwc2v2aznh61p-nixpkgs-18.03pre118061.69607d7662/nixpkgs/pkgs/stdenv/generic/make-derivation.nix:98:11
In the Nameless and single parameter section of functions and imports Nix pill, I see the syntax for calling a function is simply NAME PARAM.
What do I have to add to buildInputs to get PostGIS installed for that specific version of PostgreSQL?
Recently it became possible to use postgresql.withPackages:
with import <nixpkgs> {};
mkShell {
buildInputs = [
jq
nodejs
( postgresql11.withPackages (p: [ p.postgis ]) )
zsh
];
shellHook = ''
export SHELL=${zsh}/bin/zsh
export PATH="${builtins.toPath ./.}/node_modules/.bin/:$PATH"
export PGDATA=${builtins.toPath ./.}/pg
export PGHOST=$PGDATA
pg_ctl initdb
pg_ctl -o "-p 5555 -k $PGDATA" start
psql -p 5555 postgres -c 'create extension postgis' || true
'';
}
This is truly a stab in the dark given that postgresql is designed to be used as a service, but it's only available to you as a package since you're not on NixOS. But try this:
with import <nixpkgs> {};
stdenv.mkDerivation {
name = "my-shiny-project";
buildInputs = [
jq
nodejs-6_x
postgis.v_2_3_1
postgresql96
zsh
];
shellHook = ''
export SHELL=zsh
export PATH="$PWD/node_modules/.bin/:$PATH"
'';
}
Explanation
The postgis package doesn't produce a derivation, so it's output cannot be used directly. Instead it produces a set with attributes for two versions: 2.3.1 and 2.4.0.
Caveat
The above may not work at all. The issue is that postgis is normally provided to postgresql via the extraPlugins attribute like so:
services.postgresql.extraPlugins = [ (pkgs.postgis.override { postgresql = pkgs.postgresql95; }).v_2_3_1 ];
This causes postgresql to be installed in such a way that it can see the postgis library. However, this is done at the service level, not the package leve, and services are only available to NixOS. So if the above doesn't work, try this hunk of code:
with import <nixpkgs> {};
let
pg = postgresql96;
postgresqlWithPlugins =
buildEnv {
name = "postgresql-and-plugins-${(builtins.parseDrvName pg.name).version}";
paths = [ pg pg.lib (postgis.override { postgresql = pg; }).v_2_3_1) ];
buildInputs = [ makeWrapper ];
postBuild =
''
mkdir -p $out/bin
rm $out/bin/{pg_config,postgres,pg_ctl}
cp --target-directory=$out/bin ${pg}/bin/{postgres,pg_config,pg_ctl}
wrapProgram $out/bin/postgres --set NIX_PGLIBDIR $out/lib
'';
};
in
stdenv.mkDerivation {
name = "my-shiny-project";
buildInputs = [
jq
nodejs-6_x
postgresqlWithPlugins
zsh
];
shellHook = ''
export SHELL=zsh
export PATH="$PWD/node_modules/.bin/:$PATH"
'';
}
Basically, this is an untested port of the extraPlugins implementation.

How to get "name" field out of nix expression?

Given following default.nix,
{ stdenv, fetchurl, perl }:
stdenv.mkDerivation {
name = "hello-2.1.1";
builder = ./builder.sh;
src = fetchurl {
url = ftp://ftp.nluug.nl/pub/gnu/hello/hello-2.1.1.tar.gz;
md5 = "70c9ccf9fac07f762c24f2df2290784d";
};
inherit perl;
}
How can I get the value hello-2.1.1 from name field using nix-instantiate ?
$ nix-instantiate --eval -E 'name' default.nix
error: undefined variable ‘name’ at (string):1:1
What your nix-instantiate invocation is doing, is trying to retrieve name from a mostly empty scope. What's missing here is a piece of functionality that is implemented in NixPkgs provides the arguments to your function in default.nix.
Let's get the callPackage function from your current <nixpkgs>:
(import <nixpkgs> {}).callPackage
callPackage requires two arguments, a function that defines the package and an attribute set of overrides. Instead of providing the function directly, you can provide a file reference instead.
(import <nixpkgs> {}).callPackage ./. {}
Now let's get the name
((import <nixpkgs> {}).callPackage ./. {}).name
And run it
$ nix-instantiate --eval -E '((import <nixpkgs> {}).callPackage ./. {}).name'
"hello-2.1.1"
To experiment with Nix, I prefer to use nix-repl though. It is easier to use and has tab completion.
$ nix-env -iA nixpkgs.nix-repl
$ nix-repl
nix-repl> ((import <nixpkgs> {}).callPackage ./. {}).name
"hello-2.1.1"

Resources