I can't create services account via python - kubernetes

I try to create a service account via kubernetes client of Python, but in the post return the dict with the manifest, but do not create the service account.
My code is :
import kubernetes.client
from kubernetes import client, config
from kubernetes.client.rest import ApiException
from pprint import pprint
from kubernetes import config
config.load_kube_config()
client.configuration.debug = True
v1 = client.CoreV1Api()
# create an instance of the API class
namespace = 'users' # str | object name and auth scope, such as for teams and projects
body = {'metadata': {'name': 'test.david'} }
pretty = 'true'
dry_run = 'All' # str | When present, indicates that modifications should not be persisted.
An invalid or unrecognized dryRun directive will result in an error response and no further
processing of the request. Valid values are: - All: all dry run stages will be processed
(optional)
try:
api_response = v1.create_namespaced_service_account(namespace,body,dry_run=dry_run,
pretty=pretty)
pprint(api_response)
except ApiException as e:
print("Exception when calling CoreV1Api->create_namespaced_service_account: %s\n" % e)
The response :
{'api_version': 'v1',
'automount_service_account_token': None,
'image_pull_secrets': None,
'kind': 'ServiceAccount',
'metadata': {'annotations': None,
'cluster_name': None,
'creation_timestamp': datetime.datetime(2020, 5, 25, 23, 30, 26, tzinfo=tzutc()),
'deletion_grace_period_seconds': None,
'deletion_timestamp': None,
'finalizers': None,
'generate_name': None,
'generation': None,
'initializers': None,
'labels': None,
'managed_fields': None,
'name': 'test.david',
'namespace': 'users',
'owner_references': None,
'resource_version': None,
'self_link': '/api/v1/namespaces/users/serviceaccounts/test.david',
'uid': 'b64cff7c-9edf-11ea-8b22-0a714f906f03'},
'secrets': None}
what am I doing wrong?

Need to set
dry_run = ''
As when dry_run present, indicates that modifications should not be persisted.

Related

zeep.exceptions.Fault: Server was unable to process request. ---> Object reference not set to an instance of an object

I'm trying to send request and receive the response of a soap service using the python package zeep.
But I can't do this, I get this error message:
Traceback (most recent call last):
File "/home/oussama/PycharmProjects/pythonProject/main.py", line 44, in <module>
res = client.service.addShip(**data)
File "/usr/local/lib/python3.6/dist-packages/zeep/proxy.py", line 51, in __call__
kwargs,
File "/usr/local/lib/python3.6/dist-packages/zeep/wsdl/bindings/soap.py", line 135, in send
return self.process_reply(client, operation_obj, response)
File "/usr/local/lib/python3.6/dist-packages/zeep/wsdl/bindings/soap.py", line 229, in process_reply
return self.process_error(doc, operation)
File "/usr/local/lib/python3.6/dist-packages/zeep/wsdl/bindings/soap.py", line 333, in process_error
detail=fault_node.find("detail"),
zeep.exceptions.Fault: Server was unable to process request. ---> Object reference not set to an instance of an object.
Here is my code:
import zeep
client = zeep.Client(wsdl='http://track.smsaexpress.com/SECOM/SMSAwebService.asmx?WSDL')
data = {
'passKey': 'xxxxxxx',
'refNo': None,
'sentDate': None,
'idNo': None,
'cName': None,
'cntry': None,
'cCity': None,
'cZip': None,
'cPOBox': None,
'cMobile': None,
'cTel1': None,
'cTel2': None,
'cAddr1': None,
'cAddr2': None,
'shipType': None,
'PCs': 1,
'cEmail': None,
'carrValue': None,
'carrCurr': None,
'codAmt': None,
'weight': None,
'custVal': None,
'custCurr': None,
'insrAmt': None,
'insrCurr': None,
'itemDesc': None,
'sName': None,
'sContact': None,
'sAddr1': None,
'sAddr2': None,
'sCity': None,
'sPhone': None,
'sCntry': None,
'prefDelvDate': None,
'gpsPoints': None,
}
res = client.service.addShip(**data)
print(res)
Here (Link) you can find some info about the service
The zeep Client object is looking for a string and does not like the None keyword. Change the None to "" or '' (i.e. string space) and you should be good to go.
import zeep
client = zeep.Client(wsdl='http://track.smsaexpress.com/SECOM/SMSAwebService.asmx?WSDL')
data = {
'passKey': 'xxxxxxx',
'refNo': "",
'sentDate': "",
'idNo': "",
'cName': "",
'cntry': "",
'cCity': "",
'cZip': "",
'cPOBox': "",
'cMobile': "",
'cTel1': "",
'cTel2': "",
'cAddr1': "",
'cAddr2': "",
'shipType': "",
'PCs': 1,
'cEmail': "",
'carrValue': "",
'carrCurr': "",
'codAmt': "",
'weight': "",
'custVal': "",
'custCurr': "",
'insrAmt': "",
'insrCurr': "",
'itemDesc': "",
'sName': "",
'sContact': "",
'sAddr1': "",
'sAddr2': "",
'sCity': "",
'sPhone': "",
'sCntry': "",
'prefDelvDate': "",
'gpsPoints': "",
}
res = client.service.addShip(**data)
print(res)
I think the definition from the wsdl differs from the implementation on the server side. if you change the request that all optional fields contain a valid value it will return a result stating that the passKey is incorrect.
If you use a mock tool like SoapUI that mocks the server side it is perfectly fine to send a request with the dictionary looking like this
data = {'PCs' : 1}
In a side node the wsdl has both soap1.1 and soap1.2 implemented if you mock it make sure you use the correct endpoint url otherwise you keep sending data to the original server.

Correct way to invoke the copy module with module param 'content'

I have a custom action plugin and I need to write out returned variable data on the controller to a file. I'm trying this locally right now.
copy_module_args = dict()
copy_module_args["content"] = 'test'
copy_module_args["dest"] = dest
copy_module_args["owner"] = owner
copy_module_args["group"] = group
copy_module_args["mode"] = mode
try:
result = merge_hash(result, self._execute_module(
module_name="copy",
module_args=copy_module_args,
task_vars=task_vars))
except (AnsibleError, TypeError) as err:
err_msg = "Failed to do stuff"
raise AnsibleActionFail(to_text(err_msg), to_text(err))
The result of ._execute_module is
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Source None not found"}
The vaule of result is
{'msg': 'Source None not found', 'failed': True, 'invocation': {'module_args': {'content': 'VALUE_SPECIFIED_IN_NO_LOG_PARAMETER', 'dest': '/home/me/testfile', 'owner': 'me', 'group': 'me', 'mode': None, 'backup': False, 'force': True, 'follow': False, 'src': None, '_original_basename': None, 'validate': None, 'directory_mode': None, 'remote_src': None, 'local_follow': None, 'checksum': None, 'seuser': None, 'serole': None, 'selevel': None, 'setype': None, 'attributes': None, 'regexp': None, 'delimiter': None, 'unsafe_writes': None}}, '_ansible_parsed': True}
This invocation is trying to use the "src" param even though I'm only passing the "content" param. I know this because when I add "src" the failure message changes. I excepted, from the docs and from reading the copy module and template module source that at a bare minimum my implementation would result in:
- name: Copy using inline content
copy:
content: 'test'
dest: /home/me/testfile
Does anyone know what I'm missing or why "src" is being preferred over "content" even though it's not being specified?
The content: argument is just syntatic sugar for writing it to a tempfile, so I would guess you will need to take charge of that, or find a way to invoke the copy action, which apparently runs before the copy module.
I was able to see that "content" was being handled in the action plugin, not the module. I've adapted what I found to fit my needs. I call the action plugin, instead of the module directly.
copy_module_args = dict()
copy_module_args["content"] = 'test'
copy_module_args["dest"] = dest
copy_module_args["owner"] = owner
copy_module_args["group"] = group
copy_module_args["mode"] = mode
copy_module_args["follow"] = True
copy_module_args["force"] = False
copy_action = self._task.copy()
copy_action.args.update(copy_module_args)
# Removing args passed in via the playbook that aren't meant for
# the copy module
for remove in ("arg1", "arg2", "arg3", "arg4"):
copy_action.args.pop(remove, None)
try:
copy_action = self._shared_loader_obj.action_loader.get('copy',
task=copy_action,
connection=self._connection,
play_context=self._play_context,
loader=self._loader,
templar=self._templar,
shared_loader_obj=self._shared_loader_obj)
result = merge_hash(result, copy_action.run(task_vars=task_vars))
This allows me to leverage copy how I originally intended, by utilising its idempotency and checksumming without having to write my own.
changed: [localhost] => {"changed": true, "checksum": "00830d74b4975d59049f6e0e7ce551477a3d9425", "dest": "/home/me/testfile", "gid": 1617705057, "group": "me", "md5sum": "6f007f4188a0d35835f4bb84a2548b66", "mode": "0644", "owner": "me", "size": 9, "src": "/home/me/.ansible/tmp/ansible-tmp-1560715301.737494-249856394953357/source", "state": "file", "uid": 1300225668}
And running it again,
ok: [localhost] => {"changed": false, "dest": "/home/me/testfile", "src": "/home/me/testfile/.ansible/tmp/ansible-local-9531902t7jt3/tmp_nq34zm5"}

Airflow task not running on schedule with PrestoDB Query

I have defined a Airflow sample task where I wanted to run a PrestoDB Query followed by a Spark job to perform a simple word count example. Here is the DAG I defined:
from pandas import DataFrame
import logging
from datetime import timedelta
from operator import add
import airflow
from airflow import DAG
from airflow.operators.python_operator import PythonOperator
from airflow.hooks.presto_hook import PrestoHook
default_args = {
'owner': 'airflow',
'start_date': airflow.utils.dates.days_ago(1),
'depends_on_past': False,
'email': ['airflow#example.com'],
'email_on_failure': False,
'email_on_retry': False,
'retries': 1,
'retry_delay': timedelta(minutes=5),
}
dag = DAG(
'presto_dag',
default_args=default_args,
description='A simple tutorial DAG with PrestoDB and Spark',
# Continue to run DAG once per hour
schedule_interval='#daily',
)
def talk_to_presto():
ph = PrestoHook(host='presto.myhost.com', port=9988)
# Query PrestoDB
query = "show catalogs"
# Fetch Data
data = ph.get_records(query)
logging.info(data)
return data
def submit_to_spark():
# conf = SparkConf().setAppName("PySpark App").setMaster("http://sparkhost.com:18080/")
# sc = SparkContext(conf)
# data = sc.parallelize(list("Hello World"))
# counts = data.map(lambda x: (x, 1)).reduceByKey(add).sortBy(lambda x: x[1], ascending=False).collect()
# for (word, count) in counts:
# print("{}: {}".format(word, count))
# sc.stop()
return "Hello"
presto_task = PythonOperator(
task_id='talk_to_presto',
provide_context=True,
python_callable=talk_to_presto,
dag=dag,
)
spark_task = PythonOperator(
task_id='submit_to_spark',
provide_context=True,
python_callable=submit_to_spark,
dag=dag,
)
presto_task >> spark_task
When I submit the task, about 20 DAG instances stay in the running state:
But it never completes and no logs are generated, at least for the PrestoDB Query. I am able to run the same PrestoDB Query from the Airflow's Data Profiling > Ad-Hoc Query section correctly.
I have intentionally commented out the PySpark code as it wasn't running and not of focus in the question.
I have two questions:
Why aren't the tasks completed and stays in the running state?
What am I doing wrong with the PrestoHook as the query isn't running?

How to run the getRole command using pymongo?

I want to check whether a role exists in a mongodb, before I create a new one . I tried to do it the following way:
result = self.client[database].command("getRole", name=app_name)
Unfortunately I get the following error:
msg = msg or "%s"
raise OperationFailure(msg % errmsg, code, response)
pymongo.errors.OperationFailure: no such command: 'getRole', bad cmd: '{ getRole: 1, name: "test" }'
I am referring to this database command: https://docs.mongodb.com/manual/reference/method/db.getRole/
For createRole I can execute the command: https://docs.mongodb.com/manual/reference/method/db.createRole/#db.createRole
Shell methods db.* are different from Database commands.
Using the roleInfo command you can get information for a particular role.
db.command({
'rolesInfo': {'role': 'noremove','db': 'test'},
'showPrivileges': True, 'showBuiltinRoles': True
})
The above command returns a result in this form when there is a matching role:
{'ok': 1.0,
'roles': [{'db': 'test',
'inheritedPrivileges': [{'actions': ['find', 'insert', 'update'],
'resource': {'collection': 'test', 'db': 'test'}}],
'inheritedRoles': [],
'isBuiltin': False,
'privileges': [{'actions': ['find', 'insert', 'update'],
'resource': {'collection': 'test', 'db': 'test'}}],
'role': 'noremove',
'roles': []}]}
When there is no matching role, you get this result:
{'ok': 1.0, 'roles': []}
Checking that a role exists falls to checking for the length of the "roles" list in the returned result as follow:
noremove_role = db.command({
'rolesInfo': {'role': 'noremove','db': 'test'},
'showPrivileges': True, 'showBuiltinRoles': True
})
if not len(noremove_role['roles']):
# create role
pass
Is there a better way?
Yes, in keeping with ask forgiveness not permission philosophy, create the role and handle the resulting exception from trying to add an existing role.
from pymongo.errors import DuplicateKeyError
import logging
logger = logging.getLogger()
try:
db.command(
'createRole', 'noremove',
privileges=[{
'actions': ['insert', 'update', 'find'],
'resource': {'db': 'test', 'collection': 'test'}
}],
roles=[])
except DuplicateKeyError:
logger.error('Role already exists.')
pass

Showing KeyError: 'schedules.tasks.run' while running the django celery for periodic tasks

I've created a classes based periodic task using djcelery to send emails to the client. Task is performing the action and sending email when it is called from shell but while using the crontab, I am getting KeyError as "Schedule.tasks.run". I have added the following setting and created the tasks:
settings.py
import os
import djcelery
djcelery.setup_loader()
BROKER_URL = 'django://'
BROKER_HOST = "localhost"
BROKER_PORT = 5672
BROKER_USER = "guest"
BROKER_PASSWORD = "guest"
BROKER_VHOST = "/"
CELERYBEAT_SCHEDULER = 'djcelery.schedulers.DatabaseScheduler'
CELERY_RESULT_BACKEND = 'djcelery.backends.database:DatabaseBackend'
CELERYBEAT_SCHEDULE = {
"runs-every-30-seconds": {
"task": "schedules.tasks.EndingDrawslotScheduler.run",
"schedule": timedelta(seconds=30),
"args": (16, 16)
},
}
app.conf.timezone = 'UTC'
INSTALLED_APPS = ('djcelery',
'kombu.transport.django',)
Error-Info:
The full contents of the message body was:
{'utc': True, 'callbacks': None, 'id': '6ad19ff8-9825-4d54-a8b2-0a8322fc9fb1',
'args': [], 'taskset': None, 'retries': 0, 'timelimit': (None, None),
'kwargs': {}, 'expires': None, 'errbacks': None, 'chord': None, 'task':
'schedules.tasks.run', 'eta': None} (262b)
Traceback (most recent call last):
File "/home/s/proj/env/lib/python3.5/site-packages/celery/worker/consumer.py", line 465, in on_task_received strategies[type_](message, body,
KeyError: 'schedules.tasks.run'