我正在使用Ansible部署MongoDB。我有逻辑来设置副本集成员的优先级和投票数。
添加逻辑:
- name: Create rs.add() script
template:
src: rs.add.js.j2
dest: /opt/rs.add.js
owner: root
group: root
mode: 0644
- name: add secondaries to replica set
shell: mongo --host {{ mongodb_replicaset_name }}/{{ mongodb_hosts }} -u {{ mongodb_clustermanager_user }} -p {{ mongodb_clustermanager_pwd }} --authenticationDatabase admin --quiet /opt/rs.add.js
register: rs_add_status
when: inventory_hostname not in rs_members
failed_when: "rs_add_status.rc != 0 or 'code' in rs_add_status.stdout_lines[-2]"
rs.add.js.j2:
rs.add( {
host: "{{ inventory_hostname }}:27017",
priority: "{{ mongodb_host_priority }}",
votes: "{{ mongodb_host_votes }}"
} )
更新逻辑:
- name: Create rs.reconfig() script
template:
src: rs.reconfig.js.j2
dest: /opt/rs.reconfig.js
owner: root
group: root
mode: 0644
- name: set priority and votes
shell: mongo --host {{ mongodb_replicaset_name }}/{{ mongodb_hosts }} -u {{ mongodb_clustermanager_user }} -p {{ mongodb_clustermanager_pwd }} --authenticationDatabase admin --quiet /opt/rs.reconfig.js
register: rs_reconfig_status
when: inventory_hostname in rs_members
failed_when: "rs_reconfig_status.rc != 0 or 'code' in rs_reconfig_status.stdout_lines[-2]"
rs.reconfig.js.j2:
cfg = rs.config();
cfg.members.forEach(
function(item, i) {
if ( item.host == "{{ inventory_hostname }}" )
{
cfg.members[i].priority = {{ mongodb_host_priority }};
cfg.members[i].votes = {{ mongodb_host_votes }};
rs.reconfig(cfg);
}
}
)
上面的代码适用于我需要做的事情。它根据hostvars和我设置的默认值设置优先级和投票数。
问题,我面临的问题是,剧本每次执行时,都会将更新记录为更改。我无法设置changed_when或有条件地运行更新任务(重新配置),因为我没有什么可与当前主机变量进行比较。
我想添加逻辑以检测当前的stock_host的投票数和优先级,并将它们存储在var中,以便可以有条件地执行更新(重新配置)逻辑。我不知道该怎么做。
我知道我可以执行rs.conf()或db.getSiblingDB(“ local”)。system.replset.find()来获取副本集信息。
rs.conf():
rs0:PRIMARY> rs.conf()
{
"_id" : "rs0",
"version" : 3,
"protocolVersion" : NumberLong(1),
"members" : [
{
"_id" : 0,
"host" : "mongotest2:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 1,
"host" : "mongotest3:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 2,
"host" : "mongotest1:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
}
],
"settings" : {
...
该信息包含一组成员,每个成员(如果已设置)将具有投票和优先级属性,如果从未设置,则两个属性均将默认值设置为1,则会丢失该信息。
我尝试运行shell任务,但是我不知道如何从主机解析投票和优先级,因为host属性在数组中处于同一级别。我什至编写了一个汇总查询,该查询将隔离要检查的一台主机的投票,但我不知道如何在Ansible中解析输出:
db.getSiblingDB("local").system.replset.aggregate([
{ $match: { "members.host": "mongotest1:27017"} }
, { $project: {
_id: 0
, member: { $arrayElemAt: [{
$filter: {
input: "$members"
, as: "member"
, cond: { $eq: ["$$member.host", "mongotest1:27017"]}
}
}, 0]
}
}}
, { $project: {
votes: "$member.votes"
}}
]).pretty()
我想要以下逻辑:找到在MongoDB中为当前stockertain_host设置的投票数,如果缺少该属性,则默认值为1,并将该投票数存储在变量中(然后可以稍后将相同的逻辑应用于优先级)
我已经为此苦苦挣扎了2天,但无济于事。我找到了以下链接,但对于我的具体情况,我似乎无法将它们的示例变成一个可行的示例: