溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Ambari中的custom_actions應(yīng)用實例分析

發(fā)布時間:2022-01-06 17:26:18 來源:億速云 閱讀:128 作者:柒染 欄目:大數(shù)據(jù)

Ambari中的custom_actions應(yīng)用實例分析,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

1. custom_actions簡單介紹

假如我們要在ambari的所有主機執(zhí)行某個腳本,要在每個主機創(chuàng)建一個用戶或者查詢所有主機用戶,我們可以怎么做呢?

在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來為我們執(zhí)行某些特定操作

custom_action scritpts結(jié)構(gòu)如下:

  • 定義一個類,任意命名

  • 類要繼續(xù)Script

  • 類中重寫方法actionexecute,方法中是我們可以自定義的操作

#!/usr/bin/env python

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

2. 案例: custom_actions實現(xiàn)所有主機用戶管理

2.1 custom_action腳本實現(xiàn)

實現(xiàn)腳本并添加至路徑/var/lib/ambari-server/resources/custom_actions/scripts/

注意腳本需要執(zhí)行權(quán)限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的定義

 <actionDefinition>
    <actionName>populate_user</actionName>
    <actionType>SYSTEM</actionType>
    <inputs></inputs>
    <targetService/>
    <targetComponent/>
    <description>Populate user account</description>
    <targetType>ALL</targetType>
    <permissions>HOST.ADD_DELETE_COMPONENTS, HOST.ADD_DELETE_HOSTS, SERVICE.ADD_DELETE_SERVICES</permissions>
  </actionDefinition>

2.3 重啟ambari-server并測試

$ ambari-server restart

2.3.1 查看action是否添加成功

<font >可以看到已經(jīng)有了我們添加的populate_user</font>

$ 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 通過自定義腳本查詢所有主機用戶

<font color=red>請求執(zhí)行populate_user</font>

$ 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"
     }
 }'
 # 響應(yīng)
 {
  "href" : "http://10.1.255.11:8080/api/v1/clusters/dp147/requests/968",
  "Requests" : {
    "id" : 968,
    "status" : "Accepted"
  }
}

<font color=red>查看populate_user執(zhí)行結(jié)果</font>

# 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
      }
    }
  ]
}

<font color=red>查看populate_user在某臺主機執(zhí)行結(jié)果</font>

$ 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應(yīng)用實例分析

看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進一步的了解或閱讀更多相關(guān)文章,請關(guān)注億速云行業(yè)資訊頻道,感謝您對億速云的支持。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI