skip to Main Content

I am trying to run a series of commands to create and add the same type of user to multiple mongodbs.
Currently I make a connection to the pod I want: connect = os.system("kubectl exec -n epic-dev zerodtmongo-0 -it -- /bin/sh"

but my python script ends there and the new shell for that pod opens within the python terminal.

I would like to continue the python script to execute this block of code within multiple pods I have stored in a list.

    # Create roles to create roles 'listDatabase' & 'readChangeStream'
mongo -u admin -p admin localhost:27017/admin <<-EOF
  db.runCommand(
  {
    createRole: "listDatabases", 
    privileges: [
      { 
        resource: {cluster : true}, 
        actions: ["listDatabases"]
      }
    ],
    roles: []
  }
);

  db.runCommand(
  {
    createRole: "readChangeStream",
    privileges: [
      { 
        resource: { db: "", collection: ""}, 
        actions: [ "find", "changeStream" ] 
      }
    ],
    roles: []
   });
EOF


# Create a debezium user
mongo -u admin -p admin localhost:27017/admin <<-EOF
  db.createUser(
  {
    user: 'foo',
    pwd: 'bar',
    roles: [
      { role: "read", db: "admin" }
    ]
  });
EOF

Something like:

for pods in list:
    connect(pod)
    add user
    close connection

2

Answers


  1. you should use the python Kubernetes client to leverage the maximum benefit.

    kubernetes-client-python

    Here is the working example that expects the Kube config already set up.

    helm install my-release bitnami/mongodb
    
    
    from click import command
    from kubernetes import client, config
    from kubernetes.stream import stream
    
    def pod_exec(name, namespace, command, api_instance):
        exec_command = ["/bin/sh", "-c", command]
    
        resp = stream(api_instance.connect_get_namespaced_pod_exec,
                      name,
                      namespace,
                      command=exec_command,
                      stderr=True, stdin=False,
                      stdout=True, tty=False,
                      _preload_content=False)
    
        while resp.is_open():
            resp.update(timeout=1)
            if resp.peek_stdout():
                print(f"STDOUT: n{resp.read_stdout()}")
            if resp.peek_stderr():
                print(f"STDERR: n{resp.read_stderr()}")
    
        resp.close()
    
        if resp.returncode != 0:
            raise Exception("Script failed")
    
    command = """mongo -u root -p $MONGODB_ROOT_PASSWORD localhost:27017/admin <<-EOF
      db.runCommand(
      {
        createRole: "listDatabases", 
        privileges: [
          { 
            resource: {cluster : true}, 
            actions: ["listDatabases"]
          }
        ],
        roles: []
      }
    );
    
      db.runCommand(
      {
        createRole: "readChangeStream",
        privileges: [
          { 
            resource: { db: "", collection: ""}, 
            actions: [ "find", "changeStream" ] 
          }
        ],
        roles: []
       });
    EOF"""
    print (command)
    pod = "my-release-mongodb-7bcd6b847-qzjxz"
    config.load_kube_config()
    
    v1 = client.CoreV1Api()
    
    pod_exec(pod, "mongodb", command, v1)
    

    python3 k8_create_db.py

    enter image description here

    Login or Signup to reply.
  2. Using official K8s client,

    Ref : https://github.com/kubernetes-client/python/blob/master/examples/pod_exec.py

    import time
    
    from kubernetes import config
    from kubernetes.client import Configuration
    from kubernetes.client.api import core_v1_api
    from kubernetes.client.rest import ApiException
    from kubernetes.stream import stream
    
    
    def exec_commands(api_instance):
        name = 'busybox-test'
        resp = None
        try:
            resp = api_instance.read_namespaced_pod(name=name,
                                                    namespace='default')
        except ApiException as e:
            if e.status != 404:
                print("Unknown error: %s" % e)
                exit(1)
    
        exec_command = ['/bin/sh']
        resp = stream(api_instance.connect_get_namespaced_pod_exec,
                      name,
                      'default',
                      command=exec_command,
                      stderr=True, stdin=True,
                      stdout=True, tty=False,
                      _preload_content=False)
        commands = [
            "echo This message goes to stdout",
            "echo "This message goes to stderr" >&2",
        ]
    
        while resp.is_open():
            resp.update(timeout=1)
            if resp.peek_stdout():
                print("STDOUT: %s" % resp.read_stdout())
            if resp.peek_stderr():
                print("STDERR: %s" % resp.read_stderr())
            if commands:
                c = commands.pop(0)
                print("Running command... %sn" % c)
                resp.write_stdin(c + "n")
            else:
                break
    
        resp.write_stdin("daten")
        sdate = resp.readline_stdout(timeout=3)
        print("Server date command returns: %s" % sdate)
        resp.write_stdin("whoamin")
        user = resp.readline_stdout(timeout=3)
        print("Server user is: %s" % user)
        resp.close()
    
    
    def main():
        config.load_kube_config()
        try:
            c = Configuration().get_default_copy()
        except AttributeError:
            c = Configuration()
            c.assert_hostname = False
        Configuration.set_default(c)
        core_v1 = core_v1_api.CoreV1Api()
    
        exec_commands(core_v1)
    
    
    if __name__ == '__main__':
        main()
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search