You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwhisk.apache.org by vv...@apache.org on 2018/07/23 09:41:01 UTC

[incubator-openwhisk] branch master updated: Use separate credentials for controller and invoker. (#3876)

This is an automated email from the ASF dual-hosted git repository.

vvraskin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk.git


The following commit(s) were added to refs/heads/master by this push:
     new 02660b4  Use separate credentials for controller and invoker. (#3876)
02660b4 is described below

commit 02660b48359dc9633e534d5ce4afa745bc30c943
Author: Christian Bickel <gi...@cbickel.de>
AuthorDate: Mon Jul 23 11:40:57 2018 +0200

    Use separate credentials for controller and invoker. (#3876)
---
 ansible/group_vars/all                    |  6 ++++
 ansible/roles/controller/tasks/deploy.yml |  6 ++--
 ansible/roles/invoker/tasks/deploy.yml    |  6 ++--
 ansible/tasks/db/checkDb.yml              |  6 ++--
 ansible/tasks/db/createUsers.yml          | 25 ++++++++++++++
 ansible/tasks/db/grantPermissions.yml     | 55 +++++++++++++++++++++++++++++++
 ansible/tasks/initdb.yml                  |  7 ++++
 ansible/tasks/recreateViews.yml           |  1 -
 ansible/tasks/wipeDatabase.yml            | 21 +++++++++++-
 ansible/templates/db_local.ini.j2         |  8 +++++
 10 files changed, 133 insertions(+), 8 deletions(-)

diff --git a/ansible/group_vars/all b/ansible/group_vars/all
index 19a7c9f..b95e3de 100644
--- a/ansible/group_vars/all
+++ b/ansible/group_vars/all
@@ -237,6 +237,12 @@ db:
     admin:
       user: "{{ db_username | default(lookup('ini', 'db_username section=db_creds file={{ playbook_dir }}/db_local.ini')) }}"
       pass: "{{ db_password | default(lookup('ini', 'db_password section=db_creds file={{ playbook_dir }}/db_local.ini')) }}"
+    controller:
+      user: "{{ db_controller_user | default(lookup('ini', 'db_username section=controller file={{ playbook_dir }}/db_local.ini')) }}"
+      pass: "{{ db_controller_pass | default(lookup('ini', 'db_password section=controller file={{ playbook_dir }}/db_local.ini')) }}"
+    invoker:
+      user: "{{ db_invoker_user | default(lookup('ini', 'db_username section=invoker file={{ playbook_dir }}/db_local.ini')) }}"
+      pass: "{{ db_invoker_pass | default(lookup('ini', 'db_password section=invoker file={{ playbook_dir }}/db_local.ini')) }}"
 
 apigateway:
   port:
diff --git a/ansible/roles/controller/tasks/deploy.yml b/ansible/roles/controller/tasks/deploy.yml
index 990c18c..80c6a23 100644
--- a/ansible/roles/controller/tasks/deploy.yml
+++ b/ansible/roles/controller/tasks/deploy.yml
@@ -78,6 +78,8 @@
   include_tasks: "{{ openwhisk_home }}/ansible/tasks/db/checkDb.yml"
   vars:
     dbName: "{{ item }}"
+    dbUser: "{{ db.credentials.controller.user }}"
+    dbPass: "{{ db.credentials.controller.pass }}"
   with_items:
     - "{{ db.whisk.actions }}"
     - "{{ db.whisk.auth }}"
@@ -162,8 +164,8 @@
       "CONFIG_whisk_couchdb_protocol": "{{ db.protocol }}"
       "CONFIG_whisk_couchdb_host": "{{ db.host }}"
       "CONFIG_whisk_couchdb_port": "{{ db.port }}"
-      "CONFIG_whisk_couchdb_username": "{{ db.credentials.admin.user }}"
-      "CONFIG_whisk_couchdb_password": "{{ db.credentials.admin.pass }}"
+      "CONFIG_whisk_couchdb_username": "{{ db.credentials.controller.user }}"
+      "CONFIG_whisk_couchdb_password": "{{ db.credentials.controller.pass }}"
       "CONFIG_whisk_couchdb_provider": "{{ db.provider }}"
       "CONFIG_whisk_couchdb_databases_WhiskAuth": "{{ db.whisk.auth }}"
       "CONFIG_whisk_couchdb_databases_WhiskEntity": "{{ db.whisk.actions }}"
diff --git a/ansible/roles/invoker/tasks/deploy.yml b/ansible/roles/invoker/tasks/deploy.yml
index edfde37..40b4b7c 100644
--- a/ansible/roles/invoker/tasks/deploy.yml
+++ b/ansible/roles/invoker/tasks/deploy.yml
@@ -90,6 +90,8 @@
   include_tasks: "{{ openwhisk_home }}/ansible/tasks/db/checkDb.yml"
   vars:
     dbName: "{{ item }}"
+    dbUser: "{{ db.credentials.invoker.user }}"
+    dbPass: "{{ db.credentials.invoker.pass }}"
   with_items:
   - "{{ db.whisk.actions }}"
   - "{{ db.whisk.activations }}"
@@ -182,8 +184,8 @@
       "CONFIG_whisk_couchdb_protocol": "{{ db.protocol }}"
       "CONFIG_whisk_couchdb_host": "{{ db.host }}"
       "CONFIG_whisk_couchdb_port": "{{ db.port }}"
-      "CONFIG_whisk_couchdb_username": "{{ db.credentials.admin.user }}"
-      "CONFIG_whisk_couchdb_password": "{{ db.credentials.admin.pass }}"
+      "CONFIG_whisk_couchdb_username": "{{ db.credentials.invoker.user }}"
+      "CONFIG_whisk_couchdb_password": "{{ db.credentials.invoker.pass }}"
       "CONFIG_whisk_couchdb_provider": "{{ db.provider }}"
       "CONFIG_whisk_couchdb_databases_WhiskAuth": "{{ db.whisk.auth }}"
       "CONFIG_whisk_couchdb_databases_WhiskEntity": "{{ db.whisk.actions }}"
diff --git a/ansible/tasks/db/checkDb.yml b/ansible/tasks/db/checkDb.yml
index 728e60a..809d5e5 100644
--- a/ansible/tasks/db/checkDb.yml
+++ b/ansible/tasks/db/checkDb.yml
@@ -3,12 +3,14 @@
 ---
 # Checks, that the Database exists
 # dbName - name of the database to check
+# dbUser - name of the user which should have access rights
+# dbPass - password of the user which should have access
 
 - name: check if {{ dbName }} with {{ db.provider }} exists
   uri:
     url: "{{ db.protocol }}://{{ db.host }}:{{ db.port }}/{{ dbName }}"
     method: HEAD
     status_code: 200
-    user: "{{ db.credentials.admin.user }}"
-    password: "{{ db.credentials.admin.pass }}"
+    user: "{{ dbUser }}"
+    password: "{{ dbPass }}"
     force_basic_auth: yes
diff --git a/ansible/tasks/db/createUsers.yml b/ansible/tasks/db/createUsers.yml
new file mode 100644
index 0000000..2f2b2c0
--- /dev/null
+++ b/ansible/tasks/db/createUsers.yml
@@ -0,0 +1,25 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more contributor
+# license agreements; and to You under the Apache License, Version 2.0.
+---
+# Create all required users in _users-database
+# http://docs.couchdb.org/en/2.0.0/intro/security.html#users-documents
+
+- name: create required users
+  uri:
+    url: "{{ db.protocol }}://{{ db.host }}:{{ db.port }}/_users/org.couchdb.user:{{ item.value.user }}"
+    method: PUT
+    status_code: 201,409
+    body_format: json
+    body: |
+      {
+        "name": "{{ item.value.user }}",
+        "password": "{{ item.value.pass }}",
+        "roles": [],
+        "type": "user"
+      }
+    user: "{{ db.credentials.admin.user }}"
+    password: "{{ db.credentials.admin.pass }}"
+    force_basic_auth: yes
+  with_dict: "{{ db.credentials }}"
+  # Don't create the admin user again, if a component is using admin access.
+  when: item.value.user != db.credentials.admin.user
diff --git a/ansible/tasks/db/grantPermissions.yml b/ansible/tasks/db/grantPermissions.yml
new file mode 100644
index 0000000..11c7f11
--- /dev/null
+++ b/ansible/tasks/db/grantPermissions.yml
@@ -0,0 +1,55 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more contributor
+# license agreements; and to You under the Apache License, Version 2.0.
+---
+# Grant the specified users permissions to the specified database.
+# dbName - name of the database
+# admins - all users with admin access
+# readers - all users that have read access on the database
+# writers - all users that have write access on the database
+
+# If a component uses admin credentials, the admin user will not be added to the list (as it already has all access rights).
+- set_fact:
+    readerList: "{{ readers | default([]) | difference([db.credentials.admin.user]) }}"
+    writerList: "{{ writers | default([]) | difference([db.credentials.admin.user]) }}"
+    adminList: "{{ admins | default([]) | difference([db.credentials.admin.user]) }}"
+
+# http://docs.couchdb.org/en/2.0.0/api/database/security.html
+- name: grant permissions for CouchDB
+  uri:
+    url: "{{ db.protocol }}://{{ db.host }}:{{ db.port }}/{{ dbName }}/_security"
+    method: PUT
+    status_code: 200
+    body_format: json
+    body: |
+      {
+        "admins": {
+          "names": [ {{ adminList | join('", "') }} ],
+          "roles": []
+        },
+        "members": {
+          "names": [ "{{ readerList | union(writerList) | join('", "') }}" ],
+          "roles": []
+        }
+      }
+    user: "{{ db.credentials.admin.user }}"
+    password: "{{ db.credentials.admin.pass }}"
+    force_basic_auth: yes
+  when: db.provider == 'CouchDB'
+
+# https://console.bluemix.net/docs/services/Cloudant/api/authorization.html#authorization
+- name: grant permissions for Cloudant
+  uri:
+    url: "{{ db.protocol }}://{{ db.host }}:{{ db.port }}/{{ dbName }}/_security"
+    method: PUT
+    status_code: 200
+    body_format: json
+    body: |
+      {
+        "cloudant": {
+          {% for item in readerList | union(writerList) | union(adminList) %}"{{ item }}": [ {% if item in readerList %}"_reader"{% if item in writerList %}, "_writer"{% if item in adminList %}, "_admin"{% endif %}{% endif %}{% endif %} ], {% endfor %}
+        }
+      }
+    user: "{{ db.credentials.admin.user }}"
+    password: "{{ db.credentials.admin.pass }}"
+    force_basic_auth: yes
+  when: db.provider == 'Cloudant'
diff --git a/ansible/tasks/initdb.yml b/ansible/tasks/initdb.yml
index 7e19d7d..16608ae 100644
--- a/ansible/tasks/initdb.yml
+++ b/ansible/tasks/initdb.yml
@@ -9,6 +9,13 @@
     dbName: "{{ db.whisk.auth }}"
     forceRecreation: False
 
+- include_tasks: db/grantPermissions.yml
+  vars:
+    dbName: "{{ db.whisk.auth }}"
+    readers:
+    - "{{ db.credentials.controller.user }}"
+    - "{{ db.credentials.invoker.user }}"
+
 - include_tasks: db/recreateDoc.yml
   vars:
     dbName: "{{ db.whisk.auth }}"
diff --git a/ansible/tasks/recreateViews.yml b/ansible/tasks/recreateViews.yml
index f4f3906..0c9d428 100644
--- a/ansible/tasks/recreateViews.yml
+++ b/ansible/tasks/recreateViews.yml
@@ -21,4 +21,3 @@
     - "{{ openwhisk_home }}/ansible/files/filter_design_document.json"
     - "{{ openwhisk_home }}/ansible/files/activations_design_document_for_activations_db.json"
     - "{{ openwhisk_home }}/ansible/files/logCleanup_design_document_for_activations_db.json"
-  when: db.whisk.activations != db.whisk.actions
diff --git a/ansible/tasks/wipeDatabase.yml b/ansible/tasks/wipeDatabase.yml
index 2e85e64..bfdbd49 100644
--- a/ansible/tasks/wipeDatabase.yml
+++ b/ansible/tasks/wipeDatabase.yml
@@ -4,15 +4,34 @@
 # Wipe transient databases. You should know what you are doing here.
 # withViews: True or False. Says, if the views have to be recreated.
 
+- include_tasks: db/createUsers.yml
+
 - include_tasks: db/recreateDb.yml
   vars:
     dbName: "{{ db.whisk.actions }}"
     forceRecreation: True
+- include_tasks: db/grantPermissions.yml
+  vars:
+    dbName: "{{ db.whisk.actions }}"
+    readers:
+    - "{{ db.credentials.controller.user }}"
+    - "{{ db.credentials.invoker.user }}"
+    writers:
+    - "{{ db.credentials.controller.user }}"
+
 - include_tasks: db/recreateDb.yml
   vars:
     dbName: "{{ db.whisk.activations }}"
     forceRecreation: True
-  when: db.whisk.activations != db.whisk.actions
+- include_tasks: db/grantPermissions.yml
+  vars:
+    dbName: "{{ db.whisk.activations }}"
+    readers:
+    - "{{ db.credentials.controller.user }}"
+    - "{{ db.credentials.invoker.user }}"
+    writers:
+    - "{{ db.credentials.controller.user }}"
+    - "{{ db.credentials.invoker.user }}"
 
 - include_tasks: recreateViews.yml
   when: withViews == True
diff --git a/ansible/templates/db_local.ini.j2 b/ansible/templates/db_local.ini.j2
index 6287155..c94ab63 100644
--- a/ansible/templates/db_local.ini.j2
+++ b/ansible/templates/db_local.ini.j2
@@ -5,3 +5,11 @@ db_password={{ lookup('env', 'OW_DB_PASSWORD')|default('some_passw0rd', true) }}
 db_protocol={{ lookup('env', 'OW_DB_PROTOCOL')|default('http', true) }}
 db_host={{ lookup('env', 'OW_DB_HOST')|default(groups['db']|first, true) }}
 db_port={{ lookup('env', 'OW_DB_PORT')|default('5984', true) }}
+
+[controller]
+db_username={{ lookup('env', 'OW_DB_CONTROLLER_USERNAME') | default(db_prefix + 'controller0', true) }}
+db_password={{ lookup('env', 'OW_DB_CONTROLLER_PASSWORD') | default('some_controller_passw0rd', true) }}
+
+[invoker]
+db_username={{ lookup('env', 'OW_DB_INVOKER_USERNAME') | default(db_prefix + 'invoker0', true) }}
+db_password={{ lookup('env', 'OW_DB_INVOKER_PASSWORD') | default('some_invoker_passw0rd', true) }}