[英]ansible module mongodb_user produces “not authorized for insert on dname.system.users”
[英]How ansible mongodb_user,mongodb_replicaset modules working?
我正在嘗試通過 ansible 自動安裝 MongoDB 以及復制設置。 因此,作為其中的一部分,我想利用 ansible 模塊 mongodb_user,mongodb_replicaset。 使用此模塊時,我遇到了一些問題。 所以需要對此有所了解
問題 - 1:當我使用 mongodb_user 創建管理員用戶時,出現以下錯誤
- name: Create MongoDB root user admin
mongodb_user:
login_port: "{{ mongod_port }}"
database: "{{ mongodb_db_name }}"
name: "{{ mongodb_admin_user }}"
password: "{{ mongodb_admin_password }}"
roles: "root"
得到如下錯誤
"msg": "Unable to add or update user: not master, full error: {'topologyVersion': {'processId': ObjectId('60c0f9ebe9bf9941528836df'), 'counter': 0}, 'ok': 0.0, 'errmsg': 'not master', 'code': 10107, 'codeName': 'NotWritablePrimary', '$gleStats': {'lastOpTime': Timestamp(0, 0), 'electionId': ObjectId('000000000000000000000000')}, 'lastCommittedOpTime': Timestamp(0, 0)}"
}
從錯誤中,我可以理解它只有在 MongoDB 初始化后才能工作
所以我做了如下
- name: Initiate the Replicaset
command: "mongo --host 127.0.0.1 --port {{mongod_port}} --eval 'printjson(rs.initiate())'"
之后我就可以成功創建用戶了
現在我正在嘗試使用下面的模塊添加副本集,但不幸的是,它沒有被添加,也沒有拋出任何錯誤。沒有發生任何變化
- name: Ensure replicaset Shard_0 exists
mongodb_replicaset:
login_host: localhost
login_user: xxxxx
login_password: yyyyy
replica_set: configRS
#members: "{{ groups['MongoC'] }}"
members: "{{ groups['MongoC'] | map('extract', hostvars, ['ansible_host']) | join(':27017,') }}:27017"
when: (groups['MongoC']|sort())[0] == inventory_hostname
output:
ok: [MongoC-1] => {
"changed": false,
"invocation": {
"module_args": {
"arbiter_at_index": null,
"auth_mechanism": null,
"chaining_allowed": true,
"connection_options": null,
"election_timeout_millis": 10000,
"heartbeat_timeout_secs": 10,
"login_database": "admin",
"login_host": "localhost",
"login_password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"login_port": 27017,
"login_user": "xxxxx",
"members": [
"10.0.1.141:27017",
"10.0.2.229:27017",
"10.0.3.30:27017"
],
"protocol_version": 1,
"replica_set": "configRS",
"ssl": false,
"ssl_ca_certs": null,
"ssl_cert_reqs": "CERT_REQUIRED",
"ssl_certfile": null,
"ssl_crlfile": null,
"ssl_keyfile": null,
"ssl_pem_passphrase": null,
"validate": true
}
},
"replica_set": "configRS"
}
我是否以正確的方式使用這些模塊?
嘗試 rs.initiate 代替 ansible 模塊,如下所示
復制集.js
rs.initiate({
_id: "configRS",
configsvr: true,
members: [
{ _id: 1, host : "10.0.1.73:27017" },
{ _id: 2, host : "10.0.2.144:27017" },
{ _id: 3, host : "10.0.3.18:27017" },
]
}
);
命令:
"mongo --port 27017 replicaset.js"
得到如下錯誤:
\t\"errmsg\" : \"not authorized on admin to execute command { replSetGetConfig: 1.0, lsid: { id: UUID(\\\"788e7cff-218c-4605-ab68-b3b6751634ca\\\") }, $db: \\\"admin\\\" }\",",
"\t\"code\" : 13,",
"\t\"codeName\" : \"Unauthorized\",",
而不是printjson(rs.initiate())
嘗試
rs.initiate(
{
_id: "configRS",
configsvr: true,
members: [
{ _id: 0, host: "10.0.1.141:27017" },
{ _id: 1, host: "10.0.2.229:27017" },
{ _id: 2, host: "10.0.3.30:27017" }
]
}
);
rs.status();
while (! db.isMaster().ismaster ) { sleep(1000) }
然后你不需要添加任何成員。
對於 CSRS,我使用這樣的劇本:
- hosts: config
tasks:
- name: Compose variables
set_fact:
rs_initiate: |
{% set members = [] %}
{% for host in groups['config'] | sort %}
{% set m = {'_id': loop.index0 } %}
{% set _ = m.update({'host': host + '.' + ansible_domain + ':' + ports.config | string }) %}
{% set _ = members.append(m) %}
{% endfor %}
{% set init = {'_id': replica_set.conf} %}
{% set _ = init.update({'members': members}) %}
{% set _ = init.update({'configsvr': true}) %}
{{ init }}
rs_members: |
{% set members = [] %}
{% for host in groups['config'] | sort %}
{% set _ = members.append(host + '.' + ansible_domain + ':' + ports.config | string) %}
{% endfor %}
{{ members }}
replicaSetURI: "mongodb://{{ groups['config'] | product([ports.config]) | map('join', ':') | join(',') }}/admin?authSource=admin&replicaSet={{ replica_set.conf }}"
- name: Check if Config Replicaset is initiated
shell:
cmd: "/usr/bin/mongo --norc --quiet localhost:{{ ports.config }}"
executable: /bin/bash
stdin: "rs.status().codeName"
register: result
changed_when: false
check_mode: no
- set_fact:
# Needed to ensure that the Config Server Replica Set (CSRS) is initiated only once
rs: |
{% set i = (result.stdout == 'NotYetInitialized') %}
{% for host in ansible_play_hosts %}
{% set i = i and (hostvars[host].result.stdout == 'NotYetInitialized') %}
{% endfor %}
{{ {'NotYetInitialized': i} }}
- name: Initiate Config Replicaset
shell:
cmd: "/usr/bin/mongo --norc --quiet localhost:{{ ports.config }}"
executable: /bin/bash
stdin: |
var i = rs.initiate({{ rs_initiate | to_json }})
if (i.ok != 1) print(i.errmsg)
var _ = rs.status()
while (! db.isMaster().ismaster ) sleep(1000)
rs.status().members.map(x => x.name)
if (i.ok == 1) {print(rs.status().ok)} else {print(0)}
register: ret
failed_when: ret.stdout_lines | last != "1"
when: rs.NotYetInitialized and inventory_hostname_short == groups['config'] | sort | first)
- debug:
msg: "{{ ret.stdout_lines }}"
when: not ansible_check_mode and rs.NotYetInitialized and inventory_hostname_short == (groups['config'] | sort | first) and ret.stdout != ''
為了將主機添加到現有的 CSRS,我使用了這個:
- hosts: config
tasks:
- meta: end_play
when: ansible_check_mode or rs.NotYetInitialized | default(false)
- name: Check current Config Server Replica Set members
shell:
cmd: "/usr/bin/mongo -u admin -p {{ password.admin }} --authenticationDatabase admin --norc --quiet localhost:{{ ports.config }}"
executable: /bin/bash
stdin: "rs.status().members.map(x => x.name)"
register: result
changed_when: false
when: inventory_hostname_short == (groups['config'] | sort | first)
- set_fact:
current_members: "{{ result.stdout | from_json }}"
when: inventory_hostname_short == (groups['config'] | sort | first)
- name: Add host to Config Server Replica Set
shell:
cmd: "/usr/bin/mongo -u admin -p {{ password.admin }} --authenticationDatabase admin --norc --quiet localhost:{{ ports.config }}"
executable: /bin/bash
stdin: "rs.add('{{ item }}')"
when: inventory_hostname_short == (groups['config'] | sort | first)
loop: "{{ rs_members | difference(current_members) | sort }}"
register: ret
failed_when: ret.stdout != ""
我用這個劇本創建的用戶
- hosts: application
tasks:
- name: Check if authentication is enabled
shell:
cmd: "/usr/bin/mongo -u admin -p {{ password.admin }} --authenticationDatabase admin --norc --quiet localhost:{{ ports.router }}"
executable: /bin/bash
stdin: exit
register: authenticate
failed_when: false
changed_when: false
check_mode: no
when: inventory_hostname_short == (groups['application'] | sort | first)
- name: Create admin user
shell:
cmd: "/usr/bin/mongo {{ (authenticate.rc == 0) | ternary('-u admin -p ' + password.admin + ' --authenticationDatabase admin', '') }} --norc --quiet localhost:{{ ports.router }}"
executable: /bin/bash
stdin: |
const admin = db.getSiblingDB("admin")
{% if authenticate.rc != 0 %}
admin.createUser({ user: "admin", pwd: "{{ password.admin }}", roles: ["root"] })
var _ = admin.auth("admin", "{{ password.admin }}")
{% endif %}
// Create more users if needed
when: inventory_hostname_short == (groups['application'] | sort | first)
register: ret_createUser
changed_when: ret_createUser.stdout != ''
- debug:
msg: "{{ ret_createUser.stdout.split('\n') }}"
when: not ansible_check_mode and inventory_hostname_short == (groups['application'] | sort | first) and ret_createUser.stdout != ''
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.