如何在Ansible中检查MongoDB副本集成员属性?

时间:2018-11-01 16:48:20

标签: mongodb ansible

我正在使用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天,但无济于事。我找到了以下链接,但对于我的具体情况,我似乎无法将它们的示例变成一个可行的示例:

0 个答案:

没有答案