Why there is an error when uploading a file [closed] - rundeck

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
{
'error': True,
'apiversion': 35,
'errorCode': 'api.error.job-upload.invalid',
'message': 'Job does not have file options’
}

You need an option defined as a file type instead of a "text" type option. I leave a job definition example (check the "type" attribute on "option" section):
<joblist>
<job>
<context>
<options preserveOrder='true'>
<option name='file1' type='file' />
</options>
</context>
<defaultTab>nodes</defaultTab>
<description></description>
<executionEnabled>true</executionEnabled>
<id>36eac4c7-a421-43b8-9b71-2b07530912ec</id>
<loglevel>INFO</loglevel>
<name>Example</name>
<nodeFilterEditable>false</nodeFilterEditable>
<plugins />
<scheduleEnabled>true</scheduleEnabled>
<sequence keepgoing='false' strategy='node-first'>
<command>
<exec>cat ${file.file1}</exec>
</command>
</sequence>
<uuid>36eac4c7-a421-43b8-9b71-2b07530912ec</uuid>
</job>
</joblist>
Following the API documentation, you need to "load" the file first and later run the job with the file id on your file option. I have used jq tool to extract the file id to pass later:
#!/bin/sh
# first, load the file and store the id on $fileid bash variable (the file is loaded on --data-binary section).
fileid=$(curl -s --location --request POST 'http://localhost:4440/api/36/job/36eac4c7-a421-43b8-9b71-2b07530912ec/input/file?optionName=file1&fileName=file.txt' \
--header 'Accept: application/json' \
--header 'X-Rundeck-Auth-Token: UkGOtMIUWjpNGcEsza9KoDZ94A9hRGKV' \
--header 'Content-Type: octet/stream' \
--data-binary "#/path/to/your/file" | jq -r '.options[]')
# now run the job passing the id saved at $fileid variable (check the argString section).
curl -s --location --request POST "http://localhost:4440/api/36/job/36eac4c7-a421-43b8-9b71-2b07530912ec/run" \
--header "Accept: application/json" \
--header "X-Rundeck-Auth-Token: UkGOtMIUWjpNGcEsza9KoDZ94A9hRGKV" \
--header "Content-Type: application/json" \
--data "{ \"argString\":\"-file1 $fileid \" }" | jq
The output is (using jq too to "beautify"):
{
"id": 28,
"href": "http://localhost:4440/api/36/execution/28",
"permalink": "http://localhost:4440/project/ProjectEXAMPLE/execution/show/28",
"status": "running",
"project": "ProjectEXAMPLE",
"executionType": "user",
"user": "admin",
"date-started": {
"unixtime": 1603198748079,
"date": "2020-10-20T12:59:08Z"
},
"job": {
"id": "36eac4c7-a421-43b8-9b71-2b07530912ec",
"averageDuration": 354,
"name": "Example",
"group": "",
"project": "ProjectEXAMPLE",
"description": "",
"options": {
"file1": "50bb60fc-7b4d-4322-b00f-7ee4f79f1502"
},
"href": "http://localhost:4440/api/36/job/36eac4c7-a421-43b8-9b71-2b07530912ec",
"permalink": "http://localhost:4440/project/ProjectEXAMPLE/job/show/36eac4c7-a421-43b8-9b71-2b07530912ec"
},
"description": "cat ${file.file1}",
"argstring": "-file1 50bb60fc-7b4d-4322-b00f-7ee4f79f1502",
"serverUUID": "d547091d-acf3-4437-bbba-2b093612a813"
}
And now the job can print the file content (it's just an example).
Another option is to do the same process using RD CLI tool, easiest I think.

Related

When creating entity with keyValue options, Orion auto data type detection does not infer location attribute correctly

When creating an entity you could do it like this :
curl --location --request POST 'https://my.api/v2/entities/?options=keyValues' --header 'Content-Type: application/json' --data-raw '{
"id":"vehicle:WasteManagement:1",
"type":"WasteManagement",
"vehicleType":"lorry"
}'
Or without the options=KeyValues parameter :
curl --location --request POST 'https://my.api/v2/entities/' --header 'Content-Type: application/json' --data-raw '{
"id":"vehicle:WasteManagement:2",
"type":"WasteManagement",
"vehicleType":{
"value": "lorry"
}
}'
And in both case the entity is the same.
But I don't manage to create an entity with a options=keyValues parameter with an entity that has a 'location' attribute : when doing
curl --location --request POST 'https://my.api/v2/entities/' --header 'Content-Type: application/json' --data-raw '{
"id":"vehicle:WasteManagement:3",
"type":"WasteManagement",
"vehicleType":"lorry",
"location": {
"type": "Point",
"coordinates": [
-0.56832066,
47.49576
]
}
}'
In this case, the result from curl --location --request GET https://my.api/v2/entities/vehicle:WasteManagement:2'
Would be
"location": {
"type": "StructuredValue",
"value": {
"type": "Point",
"coordinates": [
-3.164485592,
40.627851337
]
},
"metadata": {}
},
And the type of location is StructuredValue
My expectation would be geo:point or other geo:XXX depending of the type of the GeoJSON which allow the entity to be geolocalized and filter by location.
According to the NGSIv2 specification section "Partial Representations":
Attribute/metadata type may be omitted in requests. When omitted in attribute/metadata creation or in update operations, a default is used for the type depending on the value:
...
If value is an object or array, then StructuredValue is used.
In the case of request
curl --location --request POST 'https://my.api/v2/entities/?options=keyValue' --header 'Content-Type: application/json' --data-raw '{
"id":"vehicle:WasteManagement:3",
"type":"WasteManagement",
"vehicleType":"lorry",
"location": {
"type": "Point",
"coordinates": [
-0.56832066,
47.49576
]
}
}'
the location attribute fulfills with the "when [attribute type] omitted in attribute/metadata creation or in update operations" of the NGSIv2 spec. In addition, value is an object so "If value is an object or array, then StructuredValue is used" applys. Thus, it is correct that the attribute is created/updated with type StructuredValue.
The workaround is pretty easy: don't use the keyValues mode if you need attributes with a special type (as the ones for a location or DateTime) and use the normalized mode instead.
Note that the keyValues mode has been designed as a helper not as a replacement of the normalized mode. The keyValues mode covers a great degree of the normalized mode functionality, but not fully.

How to create a folder & a project under it with Deployment Manager (Google Cloud Platform)

In a single Deployment Manager template, how do I create a new folder and a new project underneath it? The problem is that the reference to the folder includes a name in the format folders/123456, but the project requires a parent field in the format {'type': 'folder', 'id': 123456}. Using a $(ref.new-folder.name) won't work for the ID field in the parent record for the new project.
It feels like I need to do string manipulation on the $(ref.new-folder.name) like this:
# DOES NOT WORK
# but if it did, I could extract the numeric id from 'folders/123456'
parent_id = '$(ref.new-folder.name)'.replace('folders/', '')
But, of course, that won't work.
Here is my (non-working) attempt:
# Template for new folder & new project
folder_resource = {
'name': 'new-folder',
'type': 'gcp-types/cloudresourcemanager-v2:folders',
'properties': {
'parent': 'organizations/99999',
'displayName': 'new-folder'
}
}
project_resource = {
'name': 'new-project',
'type': 'clouresourcemanager.v1.project',
'metadata': { 'dependsOn': ['new-folder'] },
'properties': {
'name': 'new-project',
'parent': {
'type': 'folder',
# HERE it is -- the problem!
'id': '$(ref.new-folder.name)'
}
}
}
return { 'resources': [folder_resource, project_resource] }
So, to reiterate, I'm getting hung-up on extracting the numeric folder id from the reference to the folder's name. The name is in the format folders/123456 but I just need the 123456 part to use in the parent field for the new project.
This question is specific to folder & project creation, but a more generalized question would be: is there a way to do string-manipulation on the value of references?
For creating and managing folders document [a] might be helpful and folder name must meet the following requirements:
The name may contain letters, digits, spaces, hyphens and underscores.
The folder's display name must start and end with a letter or digit.
The name must be 30 characters or less.
The name must be distinct from all other folders that share its parent.
To create a folder:
Folders can be created with an API request.
The request JSON:
request_json= '{
display_name: "[DISPLAY_NAME]"
}'
The Create Folder curl request:
curl -X POST -H "Content-Type: application/json" \
-H "Authorization: Bearer ${bearer_token}" \
-d "$request_json" \
https://cloudresourcemanager.googleapis.com/v2/folders?parent=[ORGANIZATION_NAME]
Where:
-[DISPLAY_NAME] is the new folder's display name, for example "My Awesome Folder."
-[ORGANIZATION_NAME] is the name of the organization under which you're creating the
folder, for example organizations/123.
The Create Folder response:
{
"name": "operations/fc.123456789",
"metadata": {
"#type": "type.googleapis.com/google.cloud.resourcemanager.v2.FolderOperation",
"displayName": "[DISPLAY_NAME]",
"operationType": "CREATE"
}
}
The Get Operation curl request:
curl -H "Authorization: Bearer ${bearer_token}" \
https://cloudresourcemanager.googleapis.com/v1/operations/fc.123456789
The Get Operation response:
{
"name": "operations/fc.123456789",
"metadata": {
"#type": "type.googleapis.com/google.cloud.resourcemanager.v2.FolderOperation",
"displayName": "[DISPLAY_NAME]",
"operationType": "CREATE"
},
"done": true,
"response": {
"#type": "type.googleapis.com/google.cloud.resourcemanager.v2.Folder",
"name": "folders/12345",
"parent": "organizations/123",
"displayName": "[DISPLAY_NAME]",
"lifecycleState": "ACTIVE",
"createTime": "2017-07-19T23:29:26.018Z",
"updateTime": "2017-07-19T23:29:26.046Z"
}
}
Configuring access to folders
SetsIamPolicy sets the access control policy on a folder, replacing any existing policy. The resource field should be the folder's resource name, for example, folders/1234.
request_json= '{
policy: {
version: "1",
bindings: [
{
role: "roles/resourcemanager.folderEditor",
members: [
"user:email1#example.com",
"user:email2#example.com",
]
}
]
}
}'
The curl request:
curl -X POST -H "Content-Type: application/json" \
-H "Authorization: Bearer ${bearer_token}" \
-d "$request_json" \
https://cloudresourcemanager.googleapis.com/v2/[FOLDER_NAME]:setIamPolicy
Where:
-[FOLDER_NAME] is the name of the folder whose IAM policy is being set, for example folders/123.
Creating a project in a folder
request_json= ‘{
name: “[DISPLAY_NAME]”, projectId: “[PROJECT_ID]”, parent: {id: [PARENT_ID], type: [PARENT_TYPE] }
}’
The curl request:
curl -X POST -H "Content-Type: application/json" \
-H "Authorization: Bearer ${bearer_token}" \
-d "$request_json" \
https://cloudresourcemanager.googleapis.com/v1/projects
Where:
-[PROJECT_ID] is id of the project being created, for e.g., my-awesome-proj-123.
-[DISPLAY_NAME] is the display name of the project being created.
-[PARENT_ID] is the id of the parent being created under, for e.g. 123
-[PARENT_TYPE] is the type of the parent, like “folder” or “Organization”
When we create a reference to a resource, we also create a dependency between resources, document [b] might be helpful for this.
[a]-https://cloud.google.com/resource-manager/docs/creating-managing-folders
[b]-https://cloud.google.com/deployment-manager/docs/configuration/use-references

Why does DESCRIBE EXTENDED in Kafka KSQL return error ShowColumns not supported?

I have a simple KTABLE in KSQL called DIMAGE
When I run the following code
{
"ksql": "DESCRIBE EXTENDED DIMAGE ;"
}
I receive the following error
{
"#type": "generic_error",
"error_code": 40000,
"message": "Statement type `io.confluent.ksql.parser.tree.ShowColumns' not supported for this resource",
"stackTrace": []
}
I also receive a similar error message trying to describe a stream. I also receive the same error message if I remove the EXTENDED attribute.
You're using the wrong REST endpoint. If you use query endpoint query you'll get your error:
$ curl -s -X "POST" "http://localhost:8088/query" \
-H "Content-Type: application/vnd.ksql.v1+json; charset=utf-8" \
-d '{
"ksql": "DESCRIBE EXTENDED COMPUTER_T;"
}'
{"#type":"generic_error","error_code":40000,"message":"Statement type `io.confluent.ksql.parser.tree.ShowColumns' not supported for this resource","stackTrace":[]}⏎
If you use the statement endpoint ksql it works fine:
$ curl -s -X "POST" "http://localhost:8088/ksql" \
-H "Content-Type: application/vnd.ksql.v1+json; charset=utf-8" \
-d '{
"ksql": "DESCRIBE EXTENDED COMPUTER_T;"
}'|jq '.'
[
{
"#type": "sourceDescription",
"statementText": "DESCRIBE EXTENDED COMPUTER_T;",
"sourceDescription": {
"name": "COMPUTER_T",
"readQueries": [
{
"sinks": [
"COMP_WATCH_BY_EMP_ID_T"
],
"id": "CTAS_COMP_WATCH_BY_EMP_ID_T_0",
[...]
I've logged #2362 so that we can improve the UX of this.

Parse: Creating a New Class Programmatically

Is it possible to create a new Class programmatically (i.e. not from the dashboard) via any of the API's or the Parse CLI?
The REST API appears to have functionality to fetch, modify and delete individual Schemas (classes) but not to add them. (https://parse.com/docs/rest/guide#schemas).
Hoping for something like the following:
curl -X ADD \
-H "X-Parse-Application-Id: XXXXXX" \
-H "X-Parse-Master-Key: XXXXXXXX" \
-H "Content-Type: application/json" \
https://api.parse.com/1/schemas/City
You seem to have skipped the part which deals with adding schema in the documentation. To create a new class, according to documentation, You use following method in cURL:
curl -X POST \
-H "X-Parse-Application-Id: Your APP Id" \
-H "X-Parse-Master-Key: Your master key" \
-H "Content-Type: application/json" \
-d '
{
"className": "Your Class name goes here",
"fields": {
"Your field name here": {
"type": "Your field's data type e.g. String, Int etc. Add multiple fields if you want"
}
}
}' \
https://api.parse.com/1/schemas/[Your class name]
Or in Python:
import json,httplib
connection = httplib.HTTPSConnection('api.parse.com', 443)
connection.connect()
connection.request('POST', '/1/schemas/Game', json.dumps({
"className":"[Your class name]","fields":{"Your field name":{"type":"your field's data type"} }
}), {
"X-Parse-Application-Id": "7Lo3U5Ei75dragCphTineRMoCfwD7UJjd1apkPKX",
"X-Parse-Master-Key": "ssOXw9z1ni1unx8tW5iuaHCmhIObOn4nSW9GHj5W",
"Content-Type": "application/json"
})
result = json.loads(connection.getresponse().read())
print result

Index parameterization in Cypher REST query

I have this query which works well but without parametrization in index. emp is an index, and NUM_OFC_CA is an emp number (key in emp index), to simplify i want to return NME_CA.
curl -X POST http://xyzhost:7474/db/data/ext/CypherPlugin/graphdb/execute_query -H "Content-Type: application/json" --data-binary '{
"query": "START ca=node:emp(\"NUM_OFC_CA: 997015\") RETURN distinct ca.NME_CA as `CA Name`",
"params": {
}
}'
How can i parametrize above REST query, i have tried something like this:
curl -X POST http://xyzhost:7474/db/data/ext/CypherPlugin/graphdb/execute_query -H "Content-Type: application/json" --data-binary '{
"query": "START ca=node:emp(\"NUM_OFC_CA: {num_ofc_ca}\") RETURN distinct ca.NME_CA as `CAName`",
"params": {
"num_ofc_ca": "997015"
}
}'
I am getting this error:
{
"message" : "org.apache.lucene.queryParser.ParseException: Cannot parse 'NUM_OFC_CA: {num_ofc_ca}': Encountered \" \"}\" \"} \"\" at line 1, column 23.\nWas expecting one of:\n \"TO\" ...\n <RANGEEX_QUOTED> ...\n <RANGEEX_GOOP> ...\n ",
"exception" : "BadInputException",
"stacktrace" : [ "org.neo4j.server.plugin.cypher.CypherPlugin.executeScript(CypherPlugin.java:61)", "java.lang.reflect.Method.invoke(Method.java:597)", "org.neo4j.server.plugins.PluginMethod.invoke(PluginMethod.java:57)", "org.neo4j.server.plugins.PluginManager.invoke(PluginManager.java:168)", "org.neo4j.server.rest.web.ExtensionService.invokeGraphDatabaseExtension(ExtensionService.java:300)", "org.neo4j.server.rest.web.ExtensionService.invokeGraphDatabaseExtension(ExtensionService.java:122)", "java.lang.reflect.Method.invoke(Method.java:597)" ]
}
Need help to resolve this issue.
Thanks!
If you need a plain index query, the syntax is as follows:
curl -X POST http://<host>:7474/db/data/ext/CypherPlugin/graphdb/execute_query -H "Content-Type: application/json" --databinary '{
"query": ca=node:emp(NUM_OFC_CA = {num_ofc_ca}) RETURN distinct ca.NME_CA as `CAName`",
"params": {
"num_ofc_ca": "997015"
}
}'
For a general lucene index query, you need to parametrize the full query:
curl -X POST http://<host>:7474/db/data/ext/CypherPlugin/graphdb/execute_query -H "Content-Type: application/json" --databinary '{
"query": ca=node:emp({num_ofc_ca_query}) RETURN distinct ca.NME_CA as `CAName`",
"params": {
"num_ofc_ca_query": "NUM_OFC_CA:997015"
}
}'