Ambari中的custom_actions应用实例分析

Ambari中的custom_actions应用实例分析,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

创新互联网站建设公司,提供成都做网站、网站设计,网页设计,建网站,PHP网站建设等专业做网站服务;可快速的进行网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,是专业的做网站团队,希望更多企业前来合作!

1. custom_actions简单介绍

假如我们要在ambari的所有主机执行某个脚本,要在每个主机创建一个用户或者查询所有主机用户,我们可以怎么做呢?

在ambari的安装路径/var/lib/ambari-server/resources/custom_actions/scripts/有各种已有脚本如下:

$ ll /var/lib/ambari-server/resources/custom_actions/scripts/*.py
-rwxr-xr-x 1 root root 25331 Jul 27 21:44 check_host.py
-rwxr-xr-x 1 root root  2221 Jul 27 21:44 clear_repocache.py
-rwxr-xr-x 1 root root 21891 Jul 27 21:44 install_packages.py
-rwxr-xr-x 1 root root  2370 Jul 27 21:44 remove_bits.py
-rwxr-xr-x 1 root root  4891 Jul 27 21:44 remove_previous_stacks.py
-rwxr-xr-x 1 root root  5947 Jul 27 21:44 ru_execute_tasks.py
-rwxr-xr-x 1 root root  4592 Jul 27 21:44 stack_select_set_all.py
-rwxr-xr-x 1 root root  2777 Jul 27 21:44 update_repo.py
-rwxr-xr-x 1 root root 12374 Jul 27 21:44 validate_configs.py

我们同样可以添加一个custom_action来为我们执行某些特定操作

custom_action scritpts结构如下:

  • 定义一个类,任意命名

  • 类要继续Script

  • 类中重写方法actionexecute,方法中是我们可以自定义的操作

#!/usr/bin/env python

class CheckHost(Script):
  def actionexecute(self, env):
    pass
    
    
if __name__ == "__main__":
  CheckHost().execute()

2. 案例: custom_actions实现所有主机用户管理

2.1 custom_action脚本实现

实现脚本并添加至路径/var/lib/ambari-server/resources/custom_actions/scripts/

注意脚本需要执行权限chmod a+x populate_user.py

populate_user.py

#!/usr/bin/python

from resource_management import Script, format
from resource_management.core import shell
from resource_management.core.logger import Logger


class UserManager(Script):
    originalUserList = ""
    requestUserList = ""


    def actionexecute(self, env):
        Logger.info("UserManager invoked to processing account request")
        config = Script.get_config()

        structured_output = {}
        request_info = config['roleParams']

        Logger.debug("request details:" + str(request_info))
        code, cmd = self.assemble_cmd(request_info)
        if 0 != code:
            print "invalid request info", cmd
            Logger.error(str(code) + " " + cmd)
            structured_output["user_manager"] = {"exit_code": code, "message": str(request_info), "output": format(cmd)}
            self.put_structured_out(structured_output)
            return
        Logger.info("to execute:" + cmd)
        code, output = shell.call(cmd, sudo=False)

        print code, output
        if 0 == code:
            structured_output["user_manager"] = {"exit_code": 0, "message": format("populate user account successfully"),
                                                 "output": format(output)}
        else:
            Logger.error(str(code) + " " + output)
            structured_output["user_manager"] = {"exit_code": code, "message": format("populate user account failed"),
                                                 "output": format(output)}
        self.put_structured_out(structured_output)


    def is_user_existed(self, uname):
        # retrieveUser = "cat /etc/passwd | grep /bin/bash| cut -d: -f1"
        uexisted = 'id ' + uname
        code, resp = shell.call(uexisted, sudo=False)
        if 0 != code:
            Logger.error(str(code) + " " + resp)
            return False
        else:
            return True


    def is_group_existed(self, group):
        check_group_cmd = "cat /etc/group|cut -d : -f1"
        code, resp = shell.call(check_group_cmd, sudo=False)
        groupls = group.split(",")
        respls = []
        if code == 0:
            grps = resp.split("\n")
            # Logger.info("/etc/group:"+",".join(grps))
            for g in groupls:
                if g not in grps:
                    respls.append(g)
        else:
            Logger.error(str(code) + " " + resp)
            return False, "cmd execute error:" + resp
        if len(respls) > 0:
            return False, "groups:" + ",".join(respls) + " not existed"
        else:
            return True, "groups has existed"


    def assemble_cmd(self, req):
        """
        Json example for create user/group, delete user/group
        {"action":"create","type":"group","group":"hdp1"}
        {"action":"delete","type":"group","group":"hdp1"}
        {"action":"search","type":"group"}
        {"action":"create","type":"user","group":"hdp1","name":"user1","password":"passwd"}
        {"action":"delete","type":"user","group":"hdp1","name":"user1"}
        {"action":"search","type":"user"}
        {"action":"search","type":"user_groups"}
        parse json data to assemble instruction
        """

        type = req['type']
        action = req['action']

        # search
        if action == "search" and type == "user":
            return self.search_user()
        if action == "search" and type == "group":
            return self.search_group()
        if action == "search" and type == "user_groups":
            return self.search_user_groups()
        # check user or group
        if type == 'group':
            gname = req['group']
            if gname is None or gname == '':
                code = 1
                cmd = "group name missed"
                return code, cmd
        elif type == 'user':
            uname = req['name']
            if uname is None or uname == '':
                code = 1
                cmd = "user name missed"
                return code, cmd
        else:
            code = 1
            cmd = "unsupported type"
            return code, cmd

        # create/delete/edit
        if action == "create" and type == "user":
            return self.create_user(req['name'], req['group'])
        if action == "delete" and type == "user":
            return self.delete_user(req['name'])
        if action == "edit" and type == "user":
            return self.edit_user(req['name'], req['group'])
        if action == "create" and type == "group":
            return self.create_group(req['group'])
        if action == "delete" and type == "group":
            return self.delete_group(req['group'])
        if action == "edit" and type == "group":
            self.edit_group(req['new_group'], req['group'])

        # unknown
        return 1, "unknown operation request"


    def create_user(self, uname, gname):
        code = 0
        # need to determine whether user existed already
        if self.is_user_existed(uname):
            code = 2
            cmd = "user already existed"
            return code, cmd

        if gname is None or gname == '':
            code = 1
            cmd = "group name missed when creating user"
            return code, cmd
        is_grp_existed, grp_resp = self.is_group_existed(gname)
        if not is_grp_existed:
            code = 1
            cmd = grp_resp
            return code, cmd
        cmd = 'useradd -m -g ' + gname + " -s /bin/bash " + uname
        return code, cmd


    def delete_user(self, uname):
        code = 0
        # check whether user existed
        if not self.is_user_existed(uname):
            code = 3
            cmd = "user not existed"
            return code, cmd
        cmd = 'userdel -r ' + uname
        return code, cmd


    def edit_user(self, uname, gname):
        code = 0
        if not self.is_user_existed(uname):
            code = 3
            cmd = "user not existed"
            return code, cmd
        is_grp_existed, grp_resp = self.is_group_existed(gname)
        if not is_grp_existed:
            code = 1
            cmd = grp_resp
            return code, cmd
        cmd = 'usermod -G ' + gname + ' ' + uname
        return code, cmd


    def search_user(self):
        # search all users
        cmd = 'compgen -u'
        return 0, cmd


    def create_group(self, gname):
        cmd = 'groupadd ' + gname
        return 0, cmd


    def delete_group(self, gname):
        cmd = 'groupdel ' + gname
        return 0, cmd


    def edit_group(self, new_gname, old_gname):
        cmd = 'groupmod -n ' + new_gname + ' ' + old_gname
        return 0, cmd


    def search_group(self):
        # search all groups
        cmd = 'compgen -g'
        return 0, cmd


    def search_user_groups(self):
        """
        search all users and user_groups
        :return: hbase : hbase hadoop
        """
        cmd = "for u in `compgen -u`;do groups $u; done"
        return 0, cmd


if __name__ == "__main__":
    UserManager().execute()

2.2 添加定义到system_action_definitions.xml

/var/lib/ambari-server/resources/custom_action_definitions/system_action_definitions.xml中添加custom_action的定义

 
    populate_user
    SYSTEM
    
    
    
    Populate user account
    ALL
    HOST.ADD_DELETE_COMPONENTS, HOST.ADD_DELETE_HOSTS, SERVICE.ADD_DELETE_SERVICES
  

2.3 重启ambari-server并测试

$ ambari-server restart

2.3.1 查看action是否添加成功

可以看到已经有了我们添加的populate_user

$ curl -X GET -u admin:admin 'http://10.1.255.11:8080/api/v1/actions

{
  "href" : "http://10.1.255.11:8080/api/v1/actions",
  "items" : [
    {
      "href" : "http://10.1.255.11:8080/api/v1/actions/check_host",
      "Actions" : {
        "action_name" : "check_host"
      }
    },
    {
      "href" : "http://10.1.255.11:8080/api/v1/actions/clear_repocache",
      "Actions" : {
        "action_name" : "clear_repocache"
      }
    },
    {
      "href" : "http://10.1.255.11:8080/api/v1/actions/install_packages",
      "Actions" : {
        "action_name" : "install_packages"
      }
    },
    {
      "href" : "http://10.1.255.11:8080/api/v1/actions/populate_user",
      "Actions" : {
        "action_name" : "populate_user"
      }
    },
    {
      "href" : "http://10.1.255.11:8080/api/v1/actions/remove_previous_stacks",
      "Actions" : {
        "action_name" : "remove_previous_stacks"
      }
    },
    {
      "href" : "http://10.1.255.11:8080/api/v1/actions/ru_execute_tasks",
      "Actions" : {
        "action_name" : "ru_execute_tasks"
      }
    },
    {
      "href" : "http://10.1.255.11:8080/api/v1/actions/update_repo",
      "Actions" : {
        "action_name" : "update_repo"
      }
    },
    {
      "href" : "http://10.1.255.11:8080/api/v1/actions/validate_configs",
      "Actions" : {
        "action_name" : "validate_configs"
      }
    }
  ]
}

2.3.2 通过自定义脚本查询所有主机用户

请求执行populate_user

$ curl -X POST 'http://10.1.255.11:8080/api/v1/clusters/dp147/requests/' \
 -u admin:admin \
 -H 'x-requested-by: ambari' \
 --data '{
     "RequestInfo": {
         "context": "UserManager 2020.12.23 13:45:14",
         "action": "populate_user",
         "parameters/type": "user",
         "parameters/action": "search"
     }
 }'
 # 响应
 {
  "href" : "http://10.1.255.11:8080/api/v1/clusters/dp147/requests/968",
  "Requests" : {
    "id" : 968,
    "status" : "Accepted"
  }
}

查看populate_user执行结果

# curl -X GET -u admin:admin 'http://10.1.255.11:8080/api/v1/clusters/dp147/requests/968'
{
  "href" : "http://10.1.255.11:8080/api/v1/clusters/dp147/requests/968",
  "Requests" : {
    "aborted_task_count" : 1,
    "cluster_host_info" : "{}",
    "cluster_name" : "dp147",
    "completed_task_count" : 3,
    "create_time" : 1608732220935,
    "end_time" : 1608732221608,
    "exclusive" : false,
    "failed_task_count" : 0,
    "id" : 968,
    "inputs" : "{\"action\":\"search\",\"type\":\"user\"}",
    "operation_level" : null,
    "progress_percent" : 100.0,
    "queued_task_count" : 0,
    "request_context" : "UserManager 2020.12.23 13:45:14",
    "request_schedule" : null,
    "request_status" : "ABORTED",
    "resource_filters" : [ ],
    "start_time" : 1608732220999,
    "task_count" : 3,
    "timed_out_task_count" : 0,
    "type" : "ACTION",
    "user_name" : "admin"
  },
  "stages" : [
    {
      "href" : "http://10.1.255.11:8080/api/v1/clusters/dp147/requests/968/stages/0",
      "Stage" : {
        "cluster_name" : "dp147",
        "request_id" : 968,
        "stage_id" : 0
      }
    }
  ],
  "tasks" : [
    {
      "href" : "http://10.1.255.11:8080/api/v1/clusters/dp147/requests/968/tasks/2943",
      "Tasks" : {
        "cluster_name" : "dp147",
        "id" : 2943,
        "request_id" : 968,
        "stage_id" : 0
      }
    },
    {
      "href" : "http://10.1.255.11:8080/api/v1/clusters/dp147/requests/968/tasks/2944",
      "Tasks" : {
        "cluster_name" : "dp147",
        "id" : 2944,
        "request_id" : 968,
        "stage_id" : 0
      }
    },
    {
      "href" : "http://10.1.255.11:8080/api/v1/clusters/dp147/requests/968/tasks/2945",
      "Tasks" : {
        "cluster_name" : "dp147",
        "id" : 2945,
        "request_id" : 968,
        "stage_id" : 0
      }
    }
  ]
}

查看populate_user在某台主机执行结果

$ curl -X GET -u admin:admin 'http://10.1.255.11:8080/api/v1/clusters/dp147/requests/968/tasks/2945'
{
  "href" : "http://10.1.255.11:8080/api/v1/clusters/dp147/requests/968/tasks/2945",
  "Tasks" : {
    "attempt_cnt" : 1,
    "cluster_name" : "dp147",
    "command" : "ACTIONEXECUTE",
    "command_detail" : "populate_user ACTIONEXECUTE",
    "end_time" : 1608732221597,
    "error_log" : "/var/lib/ambari-agent/data/errors-2945.txt",
    "exit_code" : 0,
    "host_name" : "host-10-1-236-147",
    "id" : 2945,
    "ops_display_name" : null,
    "output_log" : "/var/lib/ambari-agent/data/output-2945.txt",
    "request_id" : 968,
    "role" : "populate_user",
    "stage_id" : 0,
    "start_time" : 1608732221032,
    "status" : "COMPLETED",
    "stderr" : "None",
    "stdout" : "2020-12-23 22:03:41,453 - UserManager invoked to processing account request\n2020-12-23 22:03:41,453 - to execute:compgen -u\n2020-12-23 22:03:41,454 - call['compgen -u'] {'sudo': False}\n2020-12-23 22:03:41,532 - call returned (0, 'root\\nbin\\ndaemon\\nadm\\nlp\\nsync\\nshutdown\\nhalt\\nmail\\noperator\\ngames\\nftp\\nnobody\\navahi-autoipd\\nsystemd-bus-proxy\\nsystemd-network\\ndbus\\npolkitd\\nabrt\\nlibstoragemgmt\\npostfix\\npcp\\ntss\\nchrony\\nsshd\\nntp\\ntcpdump\\noprofile\\npuaiuc\\npostgres\\nyarn-ats\\nlivy\\nMySQL\\nhive\\nzookeeper\\nams\\nambari-qa\\ntez\\nhdfs\\nyarn\\nmapred\\nhbase\\nttt\\ngaokang123\\nlibai\\nhunter\\nsongwukong\\nwwww\\njiazz')\n0 root\nbin\ndaemon\nadm\nlp\nsync\nshutdown\nhalt\nmail\noperator\ngames\nftp\nnobody\navahi-autoipd\nsystemd-bus-proxy\nsystemd-network\ndbus\npolkitd\nabrt\nlibstoragemgmt\npostfix\npcp\ntss\nchrony\nsshd\nntp\ntcpdump\noprofile\npuaiuc\npostgres\nyarn-ats\nlivy\nmysql\nhive\nzookeeper\nams\nambari-qa\ntez\nhdfs\nyarn\nmapred\nhbase\nttt\ngaokang123\nlibai\nhunter\nsongwukong\nwwww\njiazz\n\nCommand completed successfully!\n",
    "structured_out" : {
      "user_manager" : {
        "exit_code" : 0,
        "message" : "populate user account successfully",
        "output" : "root\nbin\ndaemon\nadm\nlp\nsync\nshutdown\nhalt\nmail\noperator\ngames\nftp\nnobody\navahi-autoipd\nsystemd-bus-proxy\nsystemd-network\ndbus\npolkitd\nabrt\nlibstoragemgmt\npostfix\npcp\ntss\nchrony\nsshd\nntp\ntcpdump\noprofile\npuaiuc\npostgres\nyarn-![](https://oscimg.oschina.net/oscnet/up-b681776f23021da1bbf507e1f383dfab715.png)\ngaokang123\nlibai\nhunter\nsongwukong\nwwww\njiazz"
      }
    }
  }
}

在ambari界面查看查看action运行进度如下:

Ambari中的custom_actions应用实例分析

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注创新互联行业资讯频道,感谢您对创新互联的支持。


分享文章:Ambari中的custom_actions应用实例分析
当前链接:http://myzitong.com/article/gcjjgp.html