oc / kubernetes: deployment returns "unrecognized type: string" while adding environment variables - kubernetes

We are deploying with Ansible scripts to Openshift 3 using oc apply. When we change template to add more environment variables, we receive a very vague error: "unrecognized type: string" and status code 500.
Setting --loglevel 10 leads to no more details:
$ /usr/local/bin/oc_v3.11.715 apply -f \"/tmp/ansible.YtEqVm_deploy/app.yml.json\" -n test-env --loglevel 10 2&> log.log
(several GET to get secret, deploymentconfigs, etc.)
...
I0127 11:49:05.455217 605 request.go:897] Request Body: {xxxxxxxx}
I0127 11:49:05.455280 605 round_trippers.go:386] curl -k -v -XPATCH -H "User-Agent: oc_v3.11.715/v1.11.0+d4cacc0 (linux/amd64) kubernetes/d4cacc0" -H "Authorization: Bearer xxxxxx" -H "Accept: application/json" -H "Content-Type: application/strategic-merge-patch+json" 'https://test-env:8443/apis/apps.openshift.io/v1/namespaces/test-app/deploymentconfigs/app'
I0127 11:49:05.466278 605 round_trippers.go:405] PATCH https://test-env:8443/apis/apps.openshift.io/v1/namespaces/test-env-app/deploymentconfigs/app 500 Internal Server Error in 10 milliseconds
I0127 11:49:05.466287 605 round_trippers.go:411] Response Headers:
I0127 11:49:05.466291 605 round_trippers.go:414] Content-Length: 118
I0127 11:49:05.466294 605 round_trippers.go:414] Date: Fri, 27 Jan 2023 09:49:05 GMT
I0127 11:49:05.466297 605 round_trippers.go:414] Audit-Id: 1d3f3398-14fc-4bfa-854b-6faf9b105680
I0127 11:49:05.466302 605 round_trippers.go:414] Cache-Control: no-store
I0127 11:49:05.466307 605 round_trippers.go:414] Content-Type: application/json
I0127 11:49:05.466321 605 request.go:897] Response Body: {"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"unrecognized type: string","code":500}
I0127 11:49:05.466603 605 helpers.go:201] server response object: [{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Failure",
"message": "unrecognized type: string",
"code": 500
}]
F0127 11:49:05.466618 605 helpers.go:119] Error from server: unrecognized type: string
The request body is like:
{
"metadata": {
"annotations": {
"kubectl.kubernetes.io/last-applied-configuration": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
},
"spec": {
"template": {
"spec": {
"$setElementOrder/containers": [{
"name": "app"
}],
"containers": [{
"$setElementOrder/env": [{
"name": "OLD_VAR_1"
}, {
"name": "OLD_VAR_2"
}, {
"name": "OLD_VAR_3"
}, {
"name": "OLD_VAR_4"
}, {
"name": "NEW_VAR_1"
}, {
"name": "NEW_VAR_2"
}, {
"name": "NEW_VAR_3"
}],
"dnsPolicy": "ClusterFirst",
"env": [{
"name": "OLD_VAR_4",
"value": false
}, {
"name": "NEW_VAR_1",
"value": 10
}, {
"name": "NEW_VAR_2",
"value": 20
}, {
"name": "NEW_VAR_3",
"value": 6
}],
"name": "app",
"restartPolicy": "Always",
"terminationGracePeriodSeconds": 300
}]
}
}
}
}
OLD_VAR_x are old environment variables; we want to add NEW_VAR_[1-3]. Notice strangely that not all old vars are in env, only OLD_VAR_4, but all new vars are in env.
This also happens when we use oc patch with the same request body. Same error response.
What is wrong?
A workaround is first, deployment, fail, and add new vars in Openshift manually, and deploy in Openshift webconsole on top of the last, failed deployment. It works.

Solved by quoting the var values in the template, like:
- name: NEW_VAR_X
value: "${NEW_VAR_VALUE_X}"
No errors ever since.

Related

Patch through Kuberentes rest API

I am trying to patch horizontal pod autoscaler by setting minimum replica through kubernetes api
Here is the curl which I am using
curl -k \
--request PATCH \
--header "Authorization: Bearer $KUBE_TOKEN" \
--header "Content-Type: application/strategic-merge-patch+json" \
--data '{
"apiVersion": "autoscaling/v1",
"kind": "HorizontalPodAutoscaler",
"metadata": {
"labels": {
"app.kubernetes.io/instance": "test"
},
"name": "test",
"namespace": "default"
},
"spec": {
"maxReplicas": 2,
"minReplicas": 1,
"scaleTargetRef": {
"apiVersion": "apps/v1",
"kind": "Deployment",
"name": "test"
},
"targetCPUUtilizationPercentage": 60
}
}' \
https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_PORT_443_TCP_PORT/apis/autoscaling/v1/namespaces/default/horizontalpodautoscalers
I receive following response
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {
},
"status": "Failure",
"message": "the server does not allow this method on the requested resource",
"reason": "MethodNotAllowed",
"details": {
},
"code": 405
}
Can anyone know where am I missing?
Thanks
The URL path must contain the name:
/apis/autoscaling/v1/namespaces/{namespace}/horizontalpodautoscalers/{name}
Its documented on this page https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#horizontalpodautoscaler-v1-autoscaling

Can I change a Cloud SQL instance's number of CPUs and memory via API or programmatically?

I would like to edit a PostgreSQL instance's number of CPUs and Memory to custom values such as 2 vCPUs and 5 GB of memory each, via the API, but haven't found a way to do so.
The Instance settings page shows Cores and Memory as options, but when I try setting a simple JSON with the curl example given here,
{
"settings": {
"cores": 2,
"memory": 5
}
}
nothing happens.
I found a way to get existing settings, via curl -X GET -H "Authorization: Bearer "$(gcloud auth print-access-token) -H "Content-Type: application/json; charset=utf-8" "https://sqladmin.googleapis.com/v1/projects/MYPROJECT/instances/MYINSTANCE"
The returned JSON has dataDiskSizeGb, but nothing related to CPUs or memory that is obvious to me.
{
"kind": "sql#instance",
"state": "RUNNABLE",
"databaseVersion": "POSTGRES_12",
"settings": {
"authorizedGaeApplications": [],
"tier": "db-custom-1-3840",
"kind": "sql#settings",
"availabilityType": "ZONAL",
"pricingPlan": "PER_USE",
"replicationType": "SYNCHRONOUS",
"activationPolicy": "ALWAYS",
"ipConfiguration": {
"privateNetwork": "projects/MYPROJECT/global/networks/default",
"authorizedNetworks": [],
"ipv4Enabled": true
},
"locationPreference": {
"zone": "southamerica-east1-c",
"kind": "sql#locationPreference"
},
"dataDiskType": "PD_SSD",
"maintenanceWindow": {
"kind": "sql#maintenanceWindow",
"hour": 0,
"day": 0
},
"backupConfiguration": {
"startTime": "08:00",
"kind": "sql#backupConfiguration",
"location": "us",
"backupRetentionSettings": {
"retentionUnit": "COUNT",
"retainedBackups": 7
},
"enabled": true,
"replicationLogArchivingEnabled": false,
"pointInTimeRecoveryEnabled": false,
"transactionLogRetentionDays": 7
},
"settingsVersion": "4",
"storageAutoResizeLimit": "0",
"storageAutoResize": false,
"dataDiskSizeGb": "10"
},
"etag": "079...039",
"ipAddresses": [
{
"type": "PRIMARY",
"ipAddress": "xx.xxx.x.xxx"
},
{
"type": "OUTGOING",
"ipAddress": "xx.xx.xxx.xx"
},
{
"type": "PRIVATE",
"ipAddress": "xx.xx.xxx.xx"
}
],
"serverCaCert": {
"kind": "sql#sslCert",
"certSerialNumber": "0",
"cert": "-----BEGIN CERTIFICATE-----\nMII......c=\n-----END CERTIFICATE-----",
"commonName": "C=US,O=Google\\, Inc,CN=Google Cloud SQL Server CA,dnQualifier=9f7...e0c",
"sha1Fingerprint": "fff...8fb",
"instance": "MYINSTANCE",
"createTime": "2021-10-05T17:59:18.971Z",
"expirationTime": "2031-10-03T18:00:18.971Z"
},
"instanceType": "CLOUD_SQL_INSTANCE",
"project": "MYPROJECT",
"serviceAccountEmailAddress": "abc...#gcp-sa-cloud-sql.iam.gserviceaccount.com",
"backendType": "SECOND_GEN",
"selfLink": "https://sqladmin.googleapis.com/v1/projects/MYPROJECT/instances/MYINSTANCE",
"connectionName": "MYPROJECT:southamerica-east1:MYINSTANCE",
"name": "MYINSTANCE",
"region": "southamerica-east1",
"gceZone": "southamerica-east1-c",
"createTime": "2021-10-05T17:57:47.539Z"
}
To update the number of CPUs and Memory, on the "settings" REST reference there is a field "tier" that represents the CPU and Memory of the instance. In your example it is "db-custom-1-3840", the values represents the CPU and Memory (db-custom-[CPU]-[Memory]) this means that it has 1 CPU and 3840 memory. To change the machine to 2vCPU and and 5GB memory "tier" should have a value of "db-custom-2-5120".
For testing purposes I initially created a 4 vCPU with 26 GB memory.
For reference see initial instance configuration:
To change CPU and memory see steps below:
request.json:
{
"settings": {
"tier": "db-custom-2-5120"
}
}
NOTE: The value of the memory should be a mutiple of 256MB thus the value 5120.
Curl command:
curl -X PATCH \
-H "Authorization: Bearer "$(gcloud auth print-access-token) \
-H "Content-Type: application/json; charset=utf-8" \
-d #request.json \
"https://sqladmin.googleapis.com/v1/projects/your-project-name/instances/your-instance-name"
This will return a long running operation:
When I run GET curl -X GET -H "Content-Type: application/json" -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) https://sqladmin.googleapis.com/v1/projects/your-project-name/instances/your-instance-name the change is reflected.
See GET response snippet:
See new instance information at Cloud Console > SQL > Edit:

Having trouble to patch a job in kubernetes using postman

Created a job in kubernetes using post method using postman, now trying to patch the same job using patch method using postman and i am getting 400 bad request.
Headers for post: Content-type application/yaml
post method body:
---
apiVersion: batch/v1
kind: Job
metadata:
name: pi
labels:
app: dev
spec:
template:
spec:
containers:
- name: pi
image: perl
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4
Headers for patch : Content-type application/strategic-merge-patch+json
Content-Type in Headers
patch request body:
{
"apiVersion": "batch/v1",
"kind": "Job",
"metadata": {
"name": "pi"
},
"spec": {
"template": {
"spec": {
"containers": [
{
"name": "pi",
"image": "perl",
"command": [
"perl",
"-Mbignum=bpi",
"-wle",
"print bpi(2000)"
]
}
],
"restartPolicy": "Never"
}
},
"backoffLimit": 5
}
}
Changed body please check the link.
body of the patch request
Modification i did was changed backofflimit to 5.
I was able to post and patch other resources like services and deployments but i am stuck at patching a job, I followed exactly same steps for others as well.
error i am getting error
With 'strategic-merge-patch+json' type you should use in the Request body just this json patch:
{"spec":{"backoffLimit": 7}}
As your intent is to merge/replace existing object's value based on backoffLimit key.
Check documentation for example usage of strategic-merge-patch to update resources.
Update
Please try yourself with curl:
Start local Kubernetes proxy server: kubectl proxy
curl -k -v -XPATCH -H "Content-Type: application/strategic-merge-patch+json" --data '{"spe":{"backoffLimit": 9}}' http://localhost:8001/apis/batch/v1/namespaces/default/jobs/pi
Output:
< HTTP/1.1 200 OK <-patch succeeded
< Audit-Id: 02d97d05-2bfb-4500-ac34-c8eb04ff8503
< Content-Length: 1795
< Content-Type: application/json
< Date: Fri, 12 Jul 2019 13:54:37 GMT
<
{
"kind": "Job",
"apiVersion": "batch/v1",
"metadata": {
"name": "pi",
"namespace": "default",
"selfLink": "/apis/batch/v1/namespaces/default/jobs/pi",
"uid": "5ac61d6d-a4a0-11e9-abc7-42010a80012c",
"resourceVersion": "4339038",
"creationTimestamp": "2019-07-12T12:27:03Z",
"labels": {
"app": "dev"
}
},
"spec": {
"parallelism": 1,
"completions": 1,
"backoffLimit": 9 <-patch succeeded
,
With Content-Type as application/strategic-merge-patch+json
and with body
{ "spec": { "backoffLimit": 7 }}
I have recreated the request and it worked fine.
Things that went wrong first time is that even though "content-type" is mentioned in headers correctly as "application/strategic-merge-patch+json" postman is taking a wrong Content-type, so i deleted the request and recreated the patch request with same body and headers it worked perfectly.

how can i use RestApi to update deployment in k8s?

I want to use the RestApi to update the deployment.
and I test it with postman, but always got 415 back.
the info is as follows:
type:
PATCH
url: https://k8sClusterUrl:6443/apis/extensions/v1beta1/namespaces/ns/deployments/peer0
header:
Authorization: bearer token
Content-Type:application/json
body:
{
"kind": "Deployment",
"spec":
{
"template":
{
"spec":
{
"containers":[
{
"$setElementOrder/volumeMounts":[{"mountPath":"/host/var/run/"},{"mountPath":"/mnt"}],
"name":"peer0",
"image":"hyperledger/fabric-peer:x86_64-1.1.0"}
]
}
}
}
}
response:
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Failure",
"message": "the server responded with the status code 415 but did not return more information",
"details": {},
"code": 415
}
I have muti-containers in this pod, and only want to apply for the specific container: peer0.
Any different for the $setElementOrder var?
415 is invalid media type.
In this case, you should be setting the media type as application/json+patch+json (you can see this in the documentation here)
You can try using body and using Content-Type to application/json-patch+json, method PATCH:
[{
"op" : "replace",
"path" : "/spec/template/spec/container/0/$setElementOrder/volumeMounts",
"value" : "<value you want to replace>"
}]

curl command in Matlab

I am trying to replicate a curl command which works fine on a unix machine:
curl -X POST --insecure <ENDPOINT> -H "Content-Type: application/json" -H "<OTHER HEADERS>" -d #<PATH TO JSON FILE>
What Matlab command can I use to replicate this command on a Windows machine? I'm struggling to find a way to add the --insecure option
Many thanks
Let's use an example, I'm using resclient for emacs, but do no get scary for that
My goal is to amke this call with matlab:
#
# Request
#
:auth-token = abcd1234
:number := (+ 1 2 3 4)
:text := (concat "This is " ":num" "ber")
#
# Multiline variable referencing another variable
#
:common-headers = <<
Authentication: :auth-token
User-Agent: MyApp/1.0
Content-type: application/json
#
# ...and another one
:common-body = <<
{ "number": :number, "text": ":text" }
#
# Now, use them both in request
#
POST http://httpbin.org/post?q=1
:common-headers
:common-body
which result is:
{
"args": {
"q": "1"
},
"data": "{ \"number\": 10, \"text\": \"This is 10\" }",
"files": null,
"form": null,
"headers": {
"Accept": "*/*",
"Accept-Charset": "utf-8;q=1, gb2312;q=0.5, iso-8859-1;q=0.5, big5;q=0.5, iso-2022-jp;q=0.5, shift_jis;q=0.5, euc-tw;q=0.5, euc-jp;q=0.5, euc-jis-2004;q=0.5, euc-kr;q=0.5, us-ascii;q=0.5, utf-7;q=0.5, hz-gb-2312;q=0.5, big5-hkscs;q=0.5, gbk;q=0.5, gb18030;q=0.5, iso-8859-5;q=0.5, koi8-r;q=0.5, koi8-u;q=0.5, cp866;q=0.5, koi8-t;q=0.5, windows-1251;q=0.5, cp855;q=0.5, iso-8859-2;q=0.5, iso-8859-3;q=0.5, iso-8859-4;q=0.5, iso-8859-9;q=0.5, iso-8859-10;q=0.5, iso-8859-13;q=0.5, iso-8859-14;q=0.5, iso-8859-15;q=0.5, windows-1250;q=0.5, windows-1252;q=0.5, windows-1254;q=0.5, windows-1257;q=0.5, cp775;q=0.5, cp850;q=0.5, cp852;q=0.5, cp857;q=0.5, cp858;q=0.5, cp860;q=0.5, cp861;q=0.5, cp863;q=0.5, cp865;q=0.5, cp437;q=0.5, macintosh;q=0.5, next;q=0.5, hp-roman8;q=0.5, adobe-standard-encoding;q=0.5, iso-8859-16;q=0.5, iso-8859-7;q=0.5, windows-1253;q=0.5, cp737;q=0.5, cp851;q=0.5, cp869;q=0.5, iso-8859-8;q=0.5, windows-1255;q=0.5, cp862;q=0.5, iso-2022-jp-2004;q=0.5, cp874;q=0.5, iso-8859-11;q=0.5, viscii;q=0.5, windows-1258;q=0.5, iso-8859-6;q=0.5, windows-1256;q=0.5, iso-2022-cn;q=0.5, iso-2022-cn-ext;q=0.5, iso-2022-jp-2;q=0.5, iso-2022-kr;q=0.5, utf-16le;q=0.5, utf-16be;q=0.5, utf-16;q=0.5, x-ctext;q=0.5",
"Authentication": "abcd1234",
"Content-Length": "38",
"Content-Type": "application/json",
"Extension": "Security/Digest Security/SSL",
"Host": "httpbin.org",
"Mime-Version": "1.0",
"User-Agent": "MyApp/1.0"
},
"json": {
"number": 10,
"text": "This is 10"
},
"origin": "46.222.44.201",
"url": "http://httpbin.org/post?q=1"
}
// POST http://httpbin.org/post?q=1
// HTTP/1.1 200 OK
// Server: nginx
// Date: Mon, 13 Feb 2017 10:29:40 GMT
// Content-Type: application/json
// Content-Length: 1768
// Connection: keep-alive
// Access-Control-Allow-Origin: *
// Access-Control-Allow-Credentials: true
// Request duration: 0.613051s
Let's transform it to a curl:
curl -i -H 'Content-type: application/json' -H 'User-Agent: MyApp/1.0' -H 'Authentication: abcd1234' -XPOST 'http://httpbin.org/post?q=1' -d '{ "number": 10, "text": "This is 10" }'
and finally translate it to matlab I recommend you to use urlread2 this is a matlab program from matlab fileexchange you only to register and you can dowload it. it was made by Jim Hokason, for recent matlab versions (2016) you can try this
So with urlread2 from here
the above request could be this:
>> %% Create the headers
>> hct = http_createHeader('Content-Type','application/json');
>> hua = http_createHeader('User-Agent','matlab');
>> ha = http_createHeader('Authentication','abcd1234');
>> %% method
>> method = 'POST';
>> body = '{"number":10, "text: "this is 10"}';
>> x = urlread2('http://httpbin.org/post?q=', method, body, [hct hua ha])
x =
{
"args": {
"q": ""
},
"data": "{\"number\":10, \"text: \"this is 10\"}",
"files": {},
"form": {},
"headers": {
"Accept": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2",
"Authentication": "abcd1234",
"Content-Length": "34",
"Content-Type": "application/json",
"Host": "httpbin.org",
"User-Agent": "matlab"
},
"json": null,
"origin": "46.222.44.201",
"url": "http://httpbin.org/post?q="
}
For the insecure option, I do not think that this verify ssl certifiactes