mirror of
				https://github.com/limosek/zaf.git
				synced 2025-10-31 09:37:37 +01:00 
			
		
		
		
	Compare commits
	
		
			98 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 6913033874 | ||
|   | 8b81fea72c | ||
|   | eaf83df311 | ||
|   | 52386a624f | ||
|   | 4489b9cafe | ||
|   | 80ee4b6903 | ||
|   | 8ad7841525 | ||
|   | c4abfe9ea6 | ||
|   | 2977958dd5 | ||
|   | 211d2fca39 | ||
|   | 6174a043bc | ||
|   | 56763de3fc | ||
|   | c1f5eddb5d | ||
|   | e826283c85 | ||
|   | e8be02436c | ||
|   | 7f774f409d | ||
|   | 6204eacd6a | ||
|   | 2b41fc57a5 | ||
|   | a9a0ff9528 | ||
|   | 63b00e70aa | ||
|   | 2ffc186d68 | ||
|   | cfa056065b | ||
|   | 38927897dc | ||
|   | 2e8a27e6ac | ||
|   | 25d47e6ba8 | ||
|   | 71a79ed57f | ||
|   | 9ac7bd34d4 | ||
|   | 0ef05853a4 | ||
|   | 3e2f1502d1 | ||
|   | 407fb2f77f | ||
|   | bc1cbaf144 | ||
|   | 4842cdaee1 | ||
|   | 336d120bb5 | ||
|   | b535eb58e2 | ||
|   | 6697df6519 | ||
|   | 92b3b626aa | ||
|   | 79c1992f56 | ||
|   | 0d6fd293a3 | ||
|   | 1c876c756c | ||
|   | 8e8e1b9dfc | ||
|   | 375f805b6a | ||
|   | ce843ddd55 | ||
|   | 5838292856 | ||
|   | cc244ef791 | ||
|   | 006a9fc99b | ||
|   | 72ef383146 | ||
|   | b80fd5ce7f | ||
|   | f72488708b | ||
|   | f110e9aec7 | ||
|   | b9551fb2f2 | ||
|   | 8e9d950411 | ||
|   | 93b482dc69 | ||
|   | 3ad71262e2 | ||
|   | c2316d2341 | ||
|   | 7b07643be9 | ||
|   | 658496e7cc | ||
|   | ca4f170ca3 | ||
|   | 4bdeaf9f9a | ||
|   | 7af97e2a13 | ||
|   | 276aef1689 | ||
|   | f5b88cc4d9 | ||
|   | b18919362a | ||
|   | 2bb33dc105 | ||
|   | efd52abc62 | ||
|   | 1ea7d93cd8 | ||
|   | 2d9c2059fe | ||
|   | c96a7a17dc | ||
|   | 185438225c | ||
|   | b017f0d982 | ||
|   | 957c53958c | ||
|   | 76ba5b9ad9 | ||
|   | 76352d7d12 | ||
|   | c0b57ea7be | ||
|   | 14d78f1b15 | ||
|   | ca3962ba05 | ||
|   | c5df621461 | ||
|   | 941a96208c | ||
|   | b892cb067d | ||
|   | 122c6fc831 | ||
|   | 8578dba950 | ||
|   | 79b98bf661 | ||
|   | ddbdff55d9 | ||
|   | 84f7e55078 | ||
|   | 8ad723f45c | ||
|   | da87113b47 | ||
|   | a320c33d44 | ||
|   | f9584ff673 | ||
|   | 4af2464120 | ||
|   | e097408377 | ||
|   | 83b4af050c | ||
|   | 60009d71e6 | ||
|   | 2f00b55838 | ||
|   | 93ab7c3c65 | ||
|   | fbd2fb57de | ||
|   | 844193fd23 | ||
|   | 9c6cd711ee | ||
|   | ac0a75b934 | ||
|   | fef2bf5ac0 | 
							
								
								
									
										92
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										92
									
								
								Makefile
									
									
									
									
									
								
							| @@ -1,10 +1,22 @@ | ||||
| # Zabbix agent framework makefile | ||||
|  | ||||
| all: help | ||||
|  | ||||
| help: | ||||
| 	@echo make '{deb|arch|ipk|rpm}' '[PLUGINS="/dir/plg1 [/dir2]...] [IPLUGINS="plg1 [plg2]..."] [ZAF_OPTIONS="ZAF_cfg=val ..."] [AGENT_OPTIONS="Z_Server=host ..."]' | ||||
| 	@echo PLUGINS are embedded into package. Has to be local directories accessible during build. | ||||
| 	@echo IPLUGINS will be downloaded and installed after package is installed. Can be name or url accessible after package installation. | ||||
| 	@echo | ||||
|  | ||||
| include deb.mk | ||||
| include arch.mk | ||||
| include ipk.mk | ||||
| include rpm.mk | ||||
| include tgz.mk | ||||
|  | ||||
| CONTROLFILES=$(foreach p,$(PLUGINS),$(p)/control.zaf) | ||||
| ZAF_EXPORT_OPTS=$(foreach o,$(ZAF_OPTIONS),$(shell echo $(o)|cut -d '=' -f 1)) | ||||
| DEBIAN_DIR=tmp/deb | ||||
| DEBIAN_CTRL=$(DEBIAN_DIR)/DEBIAN | ||||
| DEBIAN_PKG=$(shell . lib/zaf.lib.sh; echo out/zaf-$$ZAF_VERSION.deb) | ||||
|  | ||||
| ifeq ($(ZAF_DEBUG),) | ||||
|  ZAF_DEBUG=0 | ||||
| endif | ||||
| @@ -16,76 +28,18 @@ ifeq ($(IPLUGINS),) | ||||
|  IPLUGINS = zaf | ||||
| endif | ||||
|  | ||||
| all: help | ||||
|  | ||||
| help: | ||||
| 	@echo make '{deb|ipk|rpm}' '[PLUGINS="/dir/plg1 [/dir2]...] [IPLUGINS="plg1 [plg2]..."] [ZAF_OPTIONS="ZAF_cfg=val ..."] [AGENT_OPTIONS="Z_Server=host ..."]' | ||||
| 	@echo PLUGINS are embedded into package. Has to be local directories accessible during build. | ||||
| 	@echo IPLUGINS will be downloaded and installed after package is installed. Can be name or url accessible after package installation. | ||||
| 	@echo | ||||
|  | ||||
| deb:	$(DEBIAN_PKG) | ||||
|  | ||||
| $(DEBIAN_PKG): deb-clean deb-init deb-deps deb-control deb-scripts deb-cp deb-package | ||||
| arch:	$(ARCH_PKG) | ||||
|  | ||||
| rpm:	$(RPM_PKG) | ||||
|  | ||||
| ipk:	$(IPK_PKG) | ||||
|  | ||||
| tar:	tgz | ||||
| tgz:	$(TGZ_PKG) | ||||
|  | ||||
| clean: | ||||
| 	@rm -rf tmp/* out/* | ||||
|  | ||||
| deb-clean: | ||||
| 	@rm -rf $(DEBIAN_DIR) $(DEBIAN_PKG) | ||||
|  | ||||
| deb-init: | ||||
| 	@mkdir -p tmp out $(DEBIAN_DIR) | ||||
|  | ||||
| deb-deps: $(CONTROLFILES) | ||||
| 	@which dpkg >/dev/null && which dpkg-buildpackage >/dev/null && which dch >/dev/null || { echo "You need essential debian developer tools. Please install them:\nsudo apt-get install build-essential devscripts debhelper"; exit 2; } | ||||
|  | ||||
| deb-control: | ||||
| 	@mkdir -p $(DEBIAN_CTRL) | ||||
| 	@. lib/zaf.lib.sh; \ | ||||
| 	. lib/ctrl.lib.sh; \ | ||||
| 	for p in $(PLUGINS); do \ | ||||
| 	  	DEPENDS="$$DEPENDS,$$(zaf_ctrl_get_global_option $$p/control.zaf Depends-dpkg | tr ' ' ',')"; \ | ||||
| 	done; \ | ||||
| 	[ "$$ZAF_GITBRANCH" = "master" ] && master=master; \ | ||||
| 	zaf_far '{ZAF_VERSION}' "$${ZAF_VERSION}$$master" <files/control.template | zaf_far '{ZAF_DEPENDS}' "$$DEPENDS" >$(DEBIAN_CTRL)/control | ||||
|  | ||||
| deb-scripts: | ||||
| 	@. lib/zaf.lib.sh; \ | ||||
| 	. lib/ctrl.lib.sh; \ | ||||
| 	cat files/postinst.template | zaf_far '{PLUGINS}' "$(PLUGINS)"  | zaf_far "{IPLUGINS}" "$(IPLUGINS)" | zaf_far '{ZAF_LIB_DIR}' "/usr/lib/zaf" >$(DEBIAN_CTRL)/postinst | ||||
| 	@chmod +x $(DEBIAN_CTRL)/postinst | ||||
| 	@cp files/preinst.template $(DEBIAN_CTRL)/preinst | ||||
| 	@chmod +x $(DEBIAN_CTRL)/preinst | ||||
| 	@cp files/prerm.template $(DEBIAN_CTRL)/prerm | ||||
| 	@chmod +x $(DEBIAN_CTRL)/prerm | ||||
|  | ||||
| deb-cp: | ||||
| 	@mkdir -p $(DEBIAN_DIR) | ||||
| 	@set -e; INSTALL_PREFIX=$(DEBIAN_DIR) ZAF_DEBUG=$(ZAF_DEBUG) ./install.sh auto $(ZAF_OPTIONS) $(AGENT_OPTIONS) | ||||
| 	@. lib/zaf.lib.sh; \ | ||||
| 	. lib/ctrl.lib.sh; \ | ||||
| 	for p in $(PLUGINS); do \ | ||||
| 		plugin=$$(zaf_ctrl_get_global_option $$p/control.zaf Plugin) ; \ | ||||
| 		mkdir -p $(DEBIAN_DIR)/usr/lib/zaf/prepackaged/$$plugin/; \ | ||||
| 	  	cp -R $$p/* $(DEBIAN_DIR)/usr/lib/zaf/prepackaged/$$plugin/; \ | ||||
| 	done | ||||
| 	@cat lib/*lib.sh install.sh >$(DEBIAN_DIR)/usr/lib/zaf/install.sh | ||||
| 	@chmod +x $(DEBIAN_DIR)/usr/lib/zaf/install.sh | ||||
| 	@rm -rf $(DEBIAN_DIR)/tmp | ||||
| 	@cp $(DEBIAN_DIR)/etc/zaf.conf tmp/zaf.conf | ||||
| 	@grep -E "$$(echo $(ZAF_EXPORT_OPTS) | tr ' ' '|')=" tmp/zaf.conf  >$(DEBIAN_DIR)/etc/zaf.conf | ||||
| 	@echo "ZAF_PREPACKAGED_DIR=\"/usr/lib/zaf/prepackaged\"" >>$(DEBIAN_DIR)/etc/zaf.conf | ||||
| ifneq ($(AGENT_OPTIONS),) | ||||
| 	@echo "ZAF_AGENT_OPTIONS=\"$(AGENT_OPTIONS)\"" >>$(DEBIAN_DIR)/etc/zaf.conf | ||||
| endif | ||||
|  | ||||
| deb-package: | ||||
| 	@dpkg-deb -b $(DEBIAN_DIR) $(DEBIAN_PKG) | ||||
| 	@echo "\nCheck configuration:" | ||||
| 	@cat $(DEBIAN_DIR)/etc/zaf.conf | ||||
| 	@echo PLUGINS embedded: $(PLUGINS) | ||||
| 	@echo PLUGINS in postinst: $(IPLUGINS) | ||||
| 	@echo | ||||
|  | ||||
| 	 | ||||
|   | ||||
							
								
								
									
										228
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										228
									
								
								README.md
									
									
									
									
									
								
							| @@ -1,13 +1,15 @@ | ||||
| # Zabbix Agent Framework | ||||
| # Zabbix (Agent) Framework | ||||
|  | ||||
| This tool is used to maintain external zabbix checks in *one place*. There are lot of places where it is possible to download many external checks.  | ||||
| But there is problem with installation, update and centralised management. This tool should do all of this in easy steps. In future it can be *starting point* to | ||||
| install and configure zabbix agent on systems with one step. Primary goal is not to make all plugins available here but to be able to use any plugin and decentralized development. | ||||
| If you are maintainer of some external check, it is enough to create zaf file in  your repo and use zaf installer everywhere. | ||||
| If you are maintainer of some external check, it is enough to create zaf file in  your repo and use zaf installer everywhere.  | ||||
|  | ||||
| Next to this, this tool can even communicate with Zabbix API with *NO dependencies* to high level languages. Shell, sed and awk only. | ||||
|  | ||||
| ## Motivation | ||||
|  | ||||
| Did you install lot of zabbix agents and try to setup similar common user parameters? Do you want to setup them all? Do you want to change some zabbix agent options on lot of system? Do you want to write your own simple check or discovery rule for zabbix and it is nightmare to deploy same script on more zabbix agents? Are you tired searching some system specific agent check and setup them individualy? | ||||
| Did you install lot of zabbix agents and try to setup similar common user parameters? Do you want to setup them all? Do you want to change some zabbix agent options on lot of system? Do you want to write your own simple check or discovery rule for zabbix and it is nightmare to deploy same script on more zabbix agents? Are you tired searching some system specific agent check and setup them individualy? Do you want to auto simple backup all hosts in your zabbix to xml files? Or do you want to do some scripting on host depending on Zabbix server configuration? | ||||
| So zaf is here for you :) | ||||
|  | ||||
| ## Features | ||||
| @@ -21,56 +23,114 @@ So zaf is here for you :) | ||||
| * Zabbix discovery simplification. Creating zabbix item for discovery is not so easy in shell based system and result is not nice. But you can use framework function to do so. | ||||
| * Zabbix agent autoinstallation and autoconfiguration suitable to use in puppet or another tool  | ||||
| * OS packaging support | ||||
| * Zabbix API support | ||||
| * Zabbix host autoregistration automation | ||||
| * Zabbix sender and agent glue (send results of agent checks to zabbix sender) | ||||
| * Zabbix backup support using [zaf](https://macura.cz/node/34) | ||||
| * Support for wireless neighbours, clients with autodiscovery [iwx module](https://github.com/limosek/zaf-plugins/tree/master/iwx) | ||||
| * Support for automated import of hosts and items from [CSV](https://github.com/limosek/zaf-plugins/tree/master/csv) | ||||
| * Support for fail2ban monitoring [fail2ban](https://github.com/limosek/zaf-plugins/tree/master/fail2ban) | ||||
| * Supoort for booked [booked](https://github.com/limosek/zaf-plugins/tree/master/booked) | ||||
|  | ||||
| ## Roadmap | ||||
|  | ||||
| * External items support with automatic configuration of server | ||||
|  | ||||
| ## How it works | ||||
| Zaf installer will do most of actions needed to monitor some specific plugin items. Configuration of plugin is very simple and text readable. Anybody can write its own plugin or make its plugin "zafable". It is enough to create *control.zaf" file. For example, look into https://github.com/limosek/zaf-plugins repository. This is default repository for zaf.  | ||||
|  | ||||
| ## I want to make my own plugin! | ||||
| Great! Look into https://github.com/limosek/zaf-plugins repository, look to control files and try to create your own. It is easy! You can contact me for help. | ||||
|  | ||||
| ## I want to help with zaf! | ||||
| Great! I have no time for testing on systems and writing system specific hacks. Next to this, templates should be optimized and tested for basic plugins.  | ||||
|  | ||||
| ## I love this tool | ||||
| OK, great, if you love this tool, you can support new development on paypal account *lukas@macura.cz* or Bitcoin address **19Wbr729vei35gUQLcH2ZJGKb8oTVLz44K**.  | ||||
|  | ||||
| ## Installing Zaf | ||||
|  | ||||
| **Note**: this instructions are for *trunk* version of zaf. For *stable* version, see https://github.com/limosek/zaf/tree/1.3 | ||||
|  | ||||
| **Note**: You can find more examples on [my site](https://macura.cz/search/node?keys=zaf) | ||||
|  | ||||
| You need to be root and you must have curl installed on your system. Depending on your system, github certificates may not be available so you have to use *-k* option for curl (insecure). Default installation type is silent. So there will be no questions and everything will be autodetected. This simple command should be used on most systems: | ||||
| ``` | ||||
| curl -k https://raw.githubusercontent.com/limosek/zaf/1.1/install.sh | sh | ||||
| curl -k https://raw.githubusercontent.com/limosek/zaf/master/install.sh | sh | ||||
| ``` | ||||
| If you have only wget installed: | ||||
| ``` | ||||
| wget --no-check-certificate -O - https://raw.githubusercontent.com/limosek/zaf/master/install.sh | sh | ||||
| ``` | ||||
| If you do not have https support (like openwrt), I made small http mirror of github files which is synchronized each day: | ||||
| ``` | ||||
| wget -O - http://github.macura.cz/zaf/install.sh| ZAF_RAW_URL=http://github.macura.cz/zaf/ ZAF_URL=http://github.macura.cz/zaf/ ZAF_REPO_URL=http://github.macura.cz/zaf-plugins/ sh  | ||||
| ``` | ||||
|  | ||||
| ### Install options and autoconfiguration | ||||
| General parameters for install.sh on any system (simplest way how to install) | ||||
| ``` | ||||
| curl -k https://raw.githubusercontent.com/limosek/zaf/1.1/install.sh | \ | ||||
|    sh -s {auto|interactive|debug-auto|debug-interactive} [Agent-Options] [Zaf-Options] | ||||
| curl -k https://raw.githubusercontent.com/limosek/zaf/master/install.sh | \ | ||||
|    sh -s {auto|interactive|debug-auto|debug-interactive} [Agent-Options] [Server-Options] [Zaf-Options] | ||||
| ``` | ||||
| or use git version: | ||||
| ``` | ||||
| git clone https://github.com/limosek/zaf.git; cd zaf; git checkout 1.1 | ||||
| ./install.sh {auto|interactive|debug-auto|debug-interactive} [Agent-Options] [Zaf-Options] | ||||
| git clone https://github.com/limosek/zaf.git; cd zaf; git checkout master | ||||
|  | ||||
| ./install.sh {auto|interactive|debug-auto|debug-interactive} [Agent-Options] [Server-Options] [Zaf-Options] | ||||
|  Agent-Options: Z_Option=value [...] | ||||
|  Server-Options: S_Option=value [...] | ||||
|  Zaf-Options: ZAF_OPT=value [...] | ||||
|  To unset Agent-Option use Z_Option='' | ||||
| ``` | ||||
|  | ||||
| So you can pass ANY configuration of your zabbix agent directly to installer prefixing it with *Z_*. Please note that options are *Case Sensitive*!  | ||||
| Next to this, you can pass ANY zaf config options by *ZAF_* prefix. Interresting ZAF options: | ||||
| ``` | ||||
|  # If we want to use GIT and local GIT repository | ||||
|  ZAF_GIT='1'# Default | ||||
| Next to this, you can pass ANY zaf config options by *ZAF_* prefix. You can see all interesting ZAF options if you use install interactive command. | ||||
| Interresting ZAF options: | ||||
|  | ||||
|  # Git repository. Can be your local version | ||||
|  ZAF_REPO_GITURL='https://github.com/limosek/zaf-plugins.git' | ||||
|  | ||||
|  # Where to install plugins | ||||
|  ZAF_PLUGINS_DIR='/usr/lib/zaf/plugins' | ||||
|  | ||||
|  # Plugins can be downloaded from http[s] too | ||||
|  ZAF_REPO_URL='https://raw.githubusercontent.com/limosek/zaf-plugins/master/' | ||||
|  | ||||
| ``` | ||||
| Option|Info|Default | ||||
| ------|----|------- | ||||
| ZAF_PKG|Packaging system to use|detect | ||||
| ZAF_OS|Operating system to use|detect | ||||
| ZAF_OS_CODENAME|Operating system codename|detect | ||||
| ZAF_AGENT_PKG|Zabbix agent package|detect | ||||
| ZAF_AGENT_OPTIONS|Zabbix options to set in cfg|empty | ||||
| ZAF_GIT|Git is installed|detect | ||||
| ZAF_CURL_INSECURE|Insecure curl (accept all certificates)|1 | ||||
| ZAF_TMP_DIR|Tmp directory|/tmp/ | ||||
| ZAF_CACHE_DIR|Cache directory|/tmp/zafc | ||||
| ZAF_LIB_DIR|Libraries directory|/usr/lib/zaf | ||||
| ZAF_PLUGINS_DIR|Plugins directory|${ZAF_LIB_DIR}/plugins | ||||
| ZAF_PROXY|http[s] and ftp proxy used by zaf|empty	 | ||||
| ZAF_REPO_URL|Plugins http[s] repository|https://raw.githubusercontent.com/limosek/zaf-plugins/master/ | ||||
| ZAF_REPO_DIR|Plugins directory|${ZAF_LIB_DIR}/repo | ||||
| ZAF_AGENT_CONFIG|Zabbix agent config|/etc/zabbix/zabbix_agentd.conf | ||||
| ZAF_AGENT_CONFIGD|Zabbix agent config.d|/etc/zabbix/zabbix_agentd.conf.d/ | ||||
| ZAF_AGENT_BIN|Zabbix agent binary|/usr/sbin/zabbix_agentd | ||||
| ZAF_AGENT_RESTART|Zabbix agent restart cmd|detect | ||||
| ZAF_SERVER_CONFIG|Zabbix server config|/etc/zabbix/zabbix_server.conf | ||||
| ZAF_SERVER_CONFIGD|Zabbix server config.d|/etc/zabbix/zabbix_server.conf.d/ | ||||
| ZAF_SERVER_BIN|Zabbix server binary|/usr/sbin/zabbix_server | ||||
| ZAF_SUDOERSD|Sudo sudoers.d directory|/etc/sudoers.d | ||||
| ZAF_CROND|Cron.d directory|/etc/cron.d | ||||
| ZAF_ZBXAPI_URL|Zabbix API url|http://localhost/zabbix/api_jsonrpc.php | ||||
| ZAF_ZBXAPI_USER|Zabbix API user|zaf | ||||
| ZAF_ZBXAPI_PASS|Zabbix API password|empty | ||||
| ZAF_ZBXAPI_AUTHTYPE|Zabbix API authentication type|internal | ||||
| ZAF_PLUGINS|Plugins to autoinstall|empty | ||||
| ZAF_ZBXSRV_HOST|Zabbix server hostname|zabbix | ||||
| ZAF_ZBXSRV_PORT|Zabbix server port|10051 | ||||
| ZAF_HOSTNAME|Hostname of this machine|automatic | ||||
|  | ||||
| Installer will try to autoguess suitable config options for your system. | ||||
| Now everything was tested on Debian and OpenWrt. If somebody is interrested in, you can help and test with some rpm specific functions. Remember that on some systems, default zabbix agent config is empty so you *need to* enter essential config options as parameters. | ||||
|  | ||||
| ### Example | ||||
| Suppose you want to autoinstall agent on clean system. You need only curl installed. Everything else is one-cmd process. | ||||
| This command will install zaf, install zabbix-agent if necessary and sets zabbix variables on agent to reach server. This command can be automatized by puppet or another deploying system. | ||||
| This command will install zaf, install zabbix-agent if necessary and sets zabbix variables on agent to reach server (Server and ServerActive to zabbix.server.local). This command can be automatized by puppet or another deploying system. | ||||
| ``` | ||||
| curl -k https://raw.githubusercontent.com/limosek/zaf/1.1/install.sh | sh -s auto \ | ||||
|   Z_Server=zabbix.server.local \ | ||||
|   Z_ServerActive=zabbix.server.local \ | ||||
|   Z_HostnameItem=system.hostname Z_RefreshActiveChecks=60 \ | ||||
| curl -k https://raw.githubusercontent.com/limosek/zaf/master/install.sh | sh -s auto \ | ||||
|   ZAF_ZBXSRV_HOST=zabbix.server.local \ | ||||
|   ZAF_REPO_GITURL="git://gitserver.local" | ||||
| ``` | ||||
|  | ||||
| @@ -79,16 +139,15 @@ You can make your own deb package with preconfigured option. It is up to you to | ||||
| ``` | ||||
| git clone https://github.com/limosek/zaf.git \ | ||||
|  && cd zaf \ | ||||
|  && git checkout 1.1 \ | ||||
|  && git checkout master \ | ||||
|  && git clone https://github.com/limosek/zaf-plugins.git \ | ||||
|  && make deb PLUGINS="./zaf-plugins/fsx" IPLUGINS="zaf" ZAF_OPTIONS="ZAF_GIT=0" AGENT_OPTIONS="Z_Server=zabbix.server Z_ServerActive=zabbix.server Z_StartAgents=8" | ||||
| sudo dpkg -i out/zaf-1.1.deb | ||||
|  && make deb PLUGINS="./zaf-plugins/fsx" ZAF_PLUGINS="zaf" ZAF_OPTIONS="ZAF_GIT=0 ZAF_ZBXSRV_HOST=zabbix.server.local" AGENT_OPTIONS="Z_StartAgents=8" | ||||
| sudo dpkg -i out/zaf-1.4master.deb | ||||
| ``` | ||||
| General usage: | ||||
| ``` | ||||
| make {deb|ipk|rpm} [PLUGINS="/dir/plg1 [/dir2]...] [IPLUGINS="plg1 [plg2]..."] [ZAF_OPTIONS="ZAF_cfg=val ..."] [AGENT_OPTIONS="Z_Server=host ..."] | ||||
| PLUGINS are embedded into package. Has to be local directories accessible during build. | ||||
| IPLUGINS will be downloaded and installed after package is installed. Can be name or url accessible after package installation. | ||||
| make {deb|ipk|rpm} [ZAF_PLUGINS="plg1 [plg2]" [ZAF_OPTIONS="ZAF_cfg=val ..."] [AGENT_OPTIONS="..."] | ||||
| ZAF_PLUGINS are embedded into package. Has to be local directories accessible during build. | ||||
| ``` | ||||
|  | ||||
| ## Zaf plugin | ||||
| @@ -121,24 +180,51 @@ Cmd: sudo fail2ban-client status $1 | grep "Currently banned:" | grep -o -E "[0- | ||||
| During plugin installation, zaf will check all dependencies, do install binaries and generates apropriate zabbix.conf.d entries.  Look into https://github.com/limosek/zaf-plugins repository for more examples. | ||||
|  | ||||
| ## Zaf utility | ||||
| Zaf binary can be installed on any system from openwrt to big system. It has minimal dependencies and is shell based. Is has minimal size (up to 50kb of code). It can be used for installing, removing and testing zaf plugin items. Zaf should be run as root. | ||||
| Zaf binary can be installed on any system from openwrt to big system. It has minimal dependencies and is shell based. Is has minimal size (up to 50kb of code). It can be used for installing, removing and testing zaf plugin items. Zaf has to be configured and installed by root but it can be invoked as regular user. | ||||
| ``` | ||||
| zaf | ||||
| zaf Version 1.1. Please use some of this commands: | ||||
| zaf update			To update repo | ||||
| zaf plugins			To list installed plugins | ||||
| zaf show [plugin]		To show installed plugins or plugin info | ||||
| zaf items [plugin]		To list all suported items [for plugin] | ||||
| zaf test [plugin[.item]]	To test [all] suported items by zabbix_agentd [for plugin] | ||||
| zaf get [plugin[.item]]		To test [all] suported items by zabbix_get [for plugin] | ||||
| zaf install plugin		To install plugin | ||||
| zaf remove plugin		To remove plugin | ||||
| zaf self-upgrade		To self-upgrade zaf | ||||
| zaf self-remove			To self-remove zaf and its config | ||||
| ./zaf Version 1.4. Please use some of this commands: | ||||
| ./zaf Cmd [ZAF_OPTION=value] [ZAF_CTRL_Option=value] [ZAF_CTRLI_Item_Option=value] ... | ||||
| Plugin manipulation commands: | ||||
| ./zaf update                            To update repo (not plugins, similar to apt-get update)                          | ||||
| ./zaf upgrade                           To upgrade installed plugins from repo                                           | ||||
| ./zaf install plugin                    To install plugin                                                                | ||||
| ./zaf remove plugin                     To remove plugin                                                                 | ||||
|  | ||||
| Plugin info commands: | ||||
| ./zaf plugins                           To list installed plugins                                                        | ||||
| ./zaf show [plugin]                     To show installed plugins or plugin info                                         | ||||
| ./zaf items [plugin]                    To list all suported items [for plugin]                                          | ||||
|  | ||||
| Plugin diagnostic commands: | ||||
| ./zaf test [plugin[.item]]              To test [all] suported items by zabbix_agentd [for plugin]                       | ||||
| ./zaf get [plugin[.item]]               To test [all] suported items by zabbix_get [for plugin]                          | ||||
| ./zaf run [plugin[.item]]               To test [all] suported items by directly runing command [for plugin]             | ||||
| ./zaf precache [plugin[.item]]          To precache [all] suported items                                                 | ||||
| ./zaf itemsh plugin.item                To spawn interactive shell in item context (same as UserParameter).              | ||||
|  | ||||
| Zabbix API commands: | ||||
| ./zaf api                               To zabbix API functions. See ./zaf api for more info.                            | ||||
|  | ||||
| Zabbix trapper commands: | ||||
| ./zaf send plugin.item                  To send result of agent param directly to Zabbix server by zabbix_server.        | ||||
| Zabbix agent registration: | ||||
| ./zaf register [hostname] [metadata]    To register hostname on Zabbix server (autoregistration).                        | ||||
|  | ||||
| Agent config info commands: | ||||
| ./zaf userparms                         See userparms generated from zaf on stdout                                       | ||||
| ./zaf agent-config [force]              Reconfigure zabbix userparms in /etc/zabbix/zabbix_agentd.d                      | ||||
|  | ||||
| Zaf related commands: | ||||
| ./zaf self-upgrade                      To self-upgrade zaf                                                              | ||||
| ./zaf self-remove                       To self-remove zaf and its config                                                | ||||
| ./zaf cache-clean                       To remove all entries from cache                                                 | ||||
| ./zaf cache-list                        To show all entries in cache                                                     | ||||
|  | ||||
| ``` | ||||
|  | ||||
| ### Installing plugin | ||||
| ### Plugin operations | ||||
|  | ||||
| #### Installing plugin | ||||
| To install plugin from common repository. If git is available, local git repo is tried first. If not, remote https repo is tried second. | ||||
| ``` | ||||
| zaf install zaf | ||||
| @@ -153,14 +239,50 @@ zaf install /some/plugin | ||||
| ``` | ||||
| Installer will look into control file, run setup task defined there, fetch binaries and scripts needed for specific plugin and test system dependencies for that plugin. If everything is OK, zaf_plugin.conf is created in zabbix_agentd.d conf directory and userparameters are automaticaly added. | ||||
|  | ||||
| ## How it works | ||||
| Zaf installer will do most of actions needed to monitor some specific plugin items. Configuration of plugin is very simple and text readable. Anybody can write its own plugin or make its plugin "zafable". It is enough to create *control.zaf" file. For example, look into https://github.com/limosek/zaf-plugins repository. This is default repository for zaf.  | ||||
| #### Plugin parameters | ||||
| Plugin can have some global parameters. For example url of local server to check. See booked plugin. In that case, you have to specify parameters before use. | ||||
| To set parameters by environment: | ||||
| ``` | ||||
| zaf install booked ZAF_booked_url=http://booked.server/api ZAF_booked_username=user | ||||
| ``` | ||||
| To set parameters later: | ||||
| ``` | ||||
| zaf plugin-set booked url http://booked.server/api | ||||
| zaf plugin-set booked username user | ||||
| ``` | ||||
| Plugin parameters are available as environment variables in shell script/binary run by agent. You can simulate this environment by | ||||
| ``` | ||||
| zaf itemsh booked.num_reservations | ||||
| ``` | ||||
| Interactive shell will be spawn and you can test your commands or scripts in same way how zabbix agent would do it. Use exit command or ctrl-D to get back. | ||||
|  | ||||
| #### Run plugin subcommand | ||||
| If plugin is capable of runing subcommand (for example csv plugin), it can be called directly | ||||
| ``` | ||||
| zaf csv send | ||||
| ``` | ||||
|  | ||||
| ### Agent tests | ||||
|  | ||||
| #### To test result of item (using zabbix_agent -t) | ||||
|  | ||||
| ``` | ||||
| zaf test plugin.item[parameters] | ||||
| ``` | ||||
|  | ||||
| #### To test result of item (using zabbix_get) | ||||
|  | ||||
| ``` | ||||
| zaf test plugin.item[parameters] | ||||
| ``` | ||||
|  | ||||
| #### To get result of item directly to stdout | ||||
|  | ||||
| ``` | ||||
| zaf run plugin.item[parameters] | ||||
| ``` | ||||
|  | ||||
| ## I want to make my own plugin! | ||||
| Great! Look into https://github.com/limosek/zaf-plugins repository, look to control files and try to create your own. It is easy! You can contact me for help. | ||||
|  | ||||
| ## I want to help with zaf! | ||||
| Great! I have no time for testing on systems and writing system specific hacks. Next to this, templates should be optimized and tested for basic plugins.  | ||||
|  | ||||
|  | ||||
|  | ||||
|   | ||||
							
								
								
									
										22
									
								
								arch.mk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								arch.mk
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| # Arch linux specific definitions | ||||
|  | ||||
| ARCH_DIR=tmp/archlinux | ||||
|  | ||||
| ifeq ($(ARCH_PKG),) | ||||
|  ARCH_PKG=$(shell . lib/zaf.lib.sh; echo out/zaf-$$ZAF_VERSION.arch) | ||||
| endif | ||||
|  | ||||
| $(ARCH_PKG):	clean arch-init arch-build | ||||
|  | ||||
| arch-init: | ||||
| 	@mkdir -p tmp out $(ARCH_DIR) | ||||
| 	@. lib/zaf.lib.sh; \ | ||||
| 	. lib/ctrl.lib.sh; \ | ||||
| 	cat files/archlinux/PKGBUILD |  zaf_far '{PLUGINS}' "$(PLUGINS)"  | zaf_far "{IPLUGINS}" "$(IPLUGINS)" | \ | ||||
| 		zaf_far "{ZAF_OPTIONS}" "$(ZAF_OPTIONS)" | zaf_far "{AGENT_OPTIONS}" "$(AGENT_OPTIONS)" \ | ||||
| 		>$(ARCH_DIR)/PKGBUILD | ||||
|  | ||||
| arch-build: | ||||
| 	@cd $(ARCH_DIR) && makepkg -f | ||||
|  | ||||
|  | ||||
							
								
								
									
										15
									
								
								contrib/zafdeb.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										15
									
								
								contrib/zafdeb.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| #!/bin/sh | ||||
|  | ||||
| . lib/zaf.lib.sh | ||||
|  | ||||
| ! [ -d plugins ] && git clone https://github.com/limosek/zaf-plugins.git plugins | ||||
|  | ||||
| make deb DEBIAN_PKG="out/zaf-$ZAF_VERSION-git.deb" \ | ||||
|   ZAF_OPTIONS="ZAF_GIT=1 ZAF_REPO_GITURL='https://github.com/limosek/zaf-plugins.git'" | ||||
|  | ||||
| make deb DEBIAN_PKG="out/zaf-$ZAF_VERSION.deb" \ | ||||
|   ZAF_OPTIONS="ZAF_GIT=0" | ||||
|  | ||||
| make deb DEBIAN_PKG="out/zaf-$ZAF_VERSION-all.deb" ZAF_OPTIONS="ZAF_GIT=0" \ | ||||
|   PLUGINS="./plugins/fsx ./plugins/openssh ./plugins/psx ./plugins/tcqos ./plugins/zaf ./plugins/fail2ban" | ||||
|  | ||||
							
								
								
									
										57
									
								
								deb.mk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								deb.mk
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | ||||
| # Debian specific config | ||||
|  | ||||
| DEBIAN_DIR=tmp/deb | ||||
| DEBIAN_CTRL=$(DEBIAN_DIR)/DEBIAN | ||||
|  | ||||
| ifeq ($(DEBIAN_PKG),) | ||||
|  DEBIAN_PKG=$(shell . lib/zaf.lib.sh; echo out/zaf-$$ZAF_VERSION.deb) | ||||
| endif | ||||
|  | ||||
| $(DEBIAN_PKG):	clean deb-init deb-deps deb-control deb-scripts deb-cp deb-package | ||||
|  | ||||
| deb-init: | ||||
| 	@mkdir -p tmp out $(DEBIAN_DIR) | ||||
|  | ||||
| deb-deps: $(CONTROLFILES) | ||||
| 	@which dpkg >/dev/null && which dpkg-buildpackage >/dev/null && which dch >/dev/null || { echo "You need essential debian developer tools. Please install them:\nsudo apt-get install build-essential devscripts debhelper"; exit 2; } | ||||
|  | ||||
| deb-control: | ||||
| 	@mkdir -p $(DEBIAN_CTRL) | ||||
| 	@. lib/zaf.lib.sh; \ | ||||
| 	. lib/ctrl.lib.sh; \ | ||||
| 	for p in $(PLUGINS); do \ | ||||
| 	  	DEPENDS="$$DEPENDS,$$(zaf_ctrl_get_global_option $$p/control.zaf Depends-dpkg | tr ' ' ',')"; \ | ||||
| 	done; \ | ||||
| 	[ "$$ZAF_GITBRANCH" = "master" ] && master=master; \ | ||||
| 	zaf_far '{ZAF_VERSION}' "$${ZAF_VERSION}$$master" <files/debian/control.template | zaf_far '{ZAF_DEPENDS}' "$$DEPENDS" >$(DEBIAN_CTRL)/control | ||||
|  | ||||
| deb-scripts: | ||||
| 	@. lib/zaf.lib.sh; \ | ||||
| 	. lib/ctrl.lib.sh; \ | ||||
| 	cat files/debian/postinst.template >$(DEBIAN_CTRL)/postinst | ||||
| 	@chmod +x $(DEBIAN_CTRL)/postinst | ||||
| 	@cp files/debian/preinst.template $(DEBIAN_CTRL)/preinst | ||||
| 	@chmod +x $(DEBIAN_CTRL)/preinst | ||||
| 	@cp files/debian/prerm.template $(DEBIAN_CTRL)/prerm | ||||
| 	@chmod +x $(DEBIAN_CTRL)/prerm | ||||
|  | ||||
| deb-cp: | ||||
| 	@mkdir -p $(DEBIAN_DIR) | ||||
| 	@set -e; INSTALL_PREFIX=$(DEBIAN_DIR) ZAF_DEBUG=$(ZAF_DEBUG) ./install.sh auto $(ZAF_OPTIONS) ZAF_PLUGINS="$(ZAF_PLUGINS)" $(AGENT_OPTIONS) | ||||
| 	@cat lib/*lib.sh install.sh >$(DEBIAN_DIR)/usr/lib/zaf/install.sh | ||||
| 	@chmod +x $(DEBIAN_DIR)/usr/lib/zaf/install.sh | ||||
| 	@rm -rf $(DEBIAN_DIR)/tmp | ||||
| 	@cp $(DEBIAN_DIR)/etc/zaf.conf tmp/zaf.conf | ||||
| 	@grep -E "$$(echo $(ZAF_EXPORT_OPTS) | tr ' ' '|')=" tmp/zaf.conf  >$(DEBIAN_DIR)/etc/zaf.conf | ||||
| ifneq ($(AGENT_OPTIONS),) | ||||
| 	@echo "ZAF_AGENT_OPTIONS=\"$(AGENT_OPTIONS)\"" >>$(DEBIAN_DIR)/etc/zaf.conf | ||||
| endif | ||||
|  | ||||
| deb-package: | ||||
| 	@dpkg-deb -b $(DEBIAN_DIR) $(DEBIAN_PKG) | ||||
| 	@echo "\nCheck configuration:" | ||||
| 	@cat $(DEBIAN_DIR)/etc/zaf.conf | ||||
| 	@echo PLUGINS embedded: $(ZAF_PLUGINS) | ||||
| 	@echo | ||||
|  | ||||
|  | ||||
							
								
								
									
										39
									
								
								files/archlinux/PKGBUILD
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								files/archlinux/PKGBUILD
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| pkgname="zaf-git" | ||||
| pkgver=${PKGVER:-autogenerated} | ||||
| pkgrel=${PKGREL:-1} | ||||
| pkgdesc="zabbix agent framework - a cli tool for zabbix" | ||||
| arch=("i686" "x86_64") | ||||
| license=("GPL") | ||||
| depends=( | ||||
|     "lsb-release" | ||||
|     "git" | ||||
| ) | ||||
| backup=( | ||||
|     "etc/zaf.conf" | ||||
| ) | ||||
| source=( | ||||
|     "zaf-git::git://github.com/limosek/zaf#branch=master" | ||||
| ) | ||||
| md5sums=("SKIP") | ||||
|  | ||||
| pkgver() { | ||||
|     cd "$srcdir/$pkgname" | ||||
|     local date=$(git log -1 --format="%cd" --date=short | sed s/-//g) | ||||
|     local count=$(git rev-list --count HEAD) | ||||
|     local commit=$(git rev-parse --short HEAD) | ||||
|     echo "$date.${count}_$commit" | ||||
| } | ||||
|  | ||||
| build() { | ||||
|     cd "$srcdir/$pkgname" | ||||
|  | ||||
|     : | ||||
| } | ||||
|  | ||||
| package() { | ||||
|     cd "$srcdir/$pkgname" | ||||
|  | ||||
|     INSTALL_PREFIX="$pkgdir" \ | ||||
|         ./install.sh auto {ZAF_OPTIONS} {AGENT_OPTIONS} | ||||
| } | ||||
|  | ||||
							
								
								
									
										10
									
								
								files/debian/postinst.template
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								files/debian/postinst.template
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| #!/bin/sh | ||||
|  | ||||
| case $1 in | ||||
| configure) | ||||
|   zaf agent-config | ||||
| ;; | ||||
| esac | ||||
|  | ||||
| true | ||||
|  | ||||
| @@ -1,17 +0,0 @@ | ||||
| #!/bin/sh | ||||
|  | ||||
| case $1 in | ||||
| configure) | ||||
|   if [ -f /usr/lib/zaf/install.sh ] && [ -f /etc/zaf.conf ] && [ -f /usr/lib/zaf/zaf.lib.sh ] && which zaf >/dev/null; then | ||||
| 	. /etc/zaf.conf | ||||
| 	. /usr/lib/zaf/zaf.lib.sh | ||||
| 	. /usr/lib/zaf/os.lib.sh | ||||
| 	. /usr/lib/zaf/ctrl.lib.sh | ||||
| 	cd /usr/lib/zaf && /usr/lib/zaf/install.sh reconf | ||||
| 	[ -n "{PLUGINS}" ] && zaf reinstall {PLUGINS} {IPLUGINS} | ||||
|   fi | ||||
| ;; | ||||
| esac | ||||
|  | ||||
| true | ||||
|  | ||||
							
								
								
									
										465
									
								
								install.sh
									
									
									
									
									
								
							
							
						
						
									
										465
									
								
								install.sh
									
									
									
									
									
								
							| @@ -5,58 +5,50 @@ if [ -z "$ZAF_URL" ]; then | ||||
| 	# Runing as standalone install.sh. We have to download rest of files first. | ||||
| 	ZAF_URL="https://github.com/limosek/zaf/" | ||||
| fi | ||||
| if [ -z "$ZAF_RAW_URL" ]; then | ||||
| 	ZAF_RAW_URL="https://raw.githubusercontent.com/limosek/zaf" | ||||
| fi | ||||
|  | ||||
| [ -z "$ZAF_GITBRANCH" ] && ZAF_GITBRANCH=1.1 | ||||
| [ -z "$ZAF_GITBRANCH" ] && ZAF_GITBRANCH=master | ||||
|  | ||||
| ############### Functions | ||||
|  | ||||
| # Lite version of zaf_fetch_url, full version will be loaded later | ||||
| zaf_fetch_url(){ | ||||
| 	if [ -z "$ZAF_OFFLINE" ]; then | ||||
| 		echo  curl -f -k -s -L -o - "$1" >&2; curl -f -k -s -L -o - "$1" | ||||
| 	if zaf_which curl >/dev/null 2>/dev/null; then | ||||
| 		echo	curl -f -k -s -L -o - "$1" >&2; | ||||
| 		curl -f -k -s -L -o - "$1" | ||||
| 	else | ||||
| 		echo "Offline mode wants to download $1. Exiting." >&2 | ||||
| 		exit 2 | ||||
| 		wget --no-check-certificate -O - "$1" | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| # Download tgz and extract to /tmp/zaf-installer | ||||
| # Lite version of zaf_which, full version will be loaded later | ||||
| zaf_which() { | ||||
| 	if which >/dev/null 2>/dev/null; then | ||||
| 		which "$1" | ||||
| 	else | ||||
| 		for i in /bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin; do | ||||
| 			[ -x $i/$1 ] && { echo $i/$1; return; } | ||||
| 		done | ||||
| 		return 1 | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| # Lite version of zaf_err, full version will be loaded later | ||||
| zaf_err() { | ||||
| 	logger ${ZAF_LOG_STDERR} -p user.err -t zaf-error -- $@ | ||||
| 	logger ${ZAF_LOG_STDERR} -p user.err -t zaf-error "Exiting with error!" | ||||
| 	exit 1 | ||||
| } | ||||
|  | ||||
| # Download tgz and extract to tmpdir | ||||
| zaf_download_files() { | ||||
| 	rm -rf /tmp/zaf-installer | ||||
| 	zaf_fetch_url $ZAF_URL/archive/$ZAF_GITBRANCH.tar.gz | tar -f - -C /tmp -zx && mv /tmp/zaf-$ZAF_GITBRANCH /tmp/zaf-installer | ||||
| 	[ -z $ZAF_DIR ] && zaf_err "ZAF_DIR not set!" | ||||
| 	rm -rf $ZAF_DIR | ||||
| 	zaf_fetch_url $ZAF_URL/archive/$ZAF_GITBRANCH.tar.gz | tar -f - -C $ZAF_TMP_DIR -zx && mv $ZAF_TMP_DIR/zaf-$ZAF_GITBRANCH $ZAF_DIR || zaf_err "Cannot download and unpack zaf!" | ||||
| } | ||||
|  | ||||
| if ! [ -f README.md ]; then | ||||
| 	# We are runing from stdin | ||||
| 	if ! which curl >/dev/null; | ||||
| 	then | ||||
| 		zaf_err "Curl not found. Cannot continue. Please install it." | ||||
| 	fi | ||||
| 	echo "Installing from url $url..." | ||||
| 	[ -z "$*" ] && auto=auto | ||||
| 	zaf_download_files && cd /tmp/zaf-installer && exec ./install.sh $auto "$@" | ||||
| 	echo "Error downloading and runing installer!" >&2 | ||||
| 	exit 2 | ||||
| fi | ||||
|  | ||||
| if ! type zaf_version >/dev/null; then | ||||
| . lib/zaf.lib.sh | ||||
| . lib/os.lib.sh | ||||
| . lib/ctrl.lib.sh  | ||||
| . lib/cache.lib.sh  | ||||
| . lib/zbxapi.lib.sh  | ||||
| fi | ||||
|  | ||||
| # Read options as config for ZAF | ||||
| for pair in "$@"; do | ||||
|     echo $pair | grep -q '^ZAF\_' || continue | ||||
|     option=$(echo $pair|cut -d '=' -f 1) | ||||
|     value=$(echo $pair|cut -d '=' -f 2-) | ||||
|     eval "C_${option}='$value'" | ||||
|     zaf_wrn "Overriding $option from cmdline." | ||||
| done | ||||
|  | ||||
| [ -z "$ZAF_CFG_FILE" ] && ZAF_CFG_FILE=$INSTALL_PREFIX/etc/zaf.conf | ||||
| [ -n "$C_ZAF_DEBUG" ] && ZAF_DEBUG=$C_ZAF_DEBUG | ||||
|  | ||||
| # Read option. If it is already set in zaf.conf, it is skipped. If env variable is set, it is used instead of default | ||||
| # It sets global variable name on result. | ||||
| # $1 - option name | ||||
| @@ -66,12 +58,13 @@ done | ||||
| zaf_get_option(){ | ||||
| 	local opt | ||||
|  | ||||
|         eval opt=\$C_$1 | ||||
| 	ZAF_HELP_OPTS="$ZAF_HELP_OPTS\n$1 $2 [$3]" | ||||
| 	eval opt=\$C_$1 | ||||
| 	if [ -n "$opt" ]; then | ||||
|             eval "$1='$opt'" | ||||
|             zaf_dbg "Got '$2' <$1> from CLI: $opt" | ||||
|             return | ||||
|         fi | ||||
| 		eval "$1='$opt'" | ||||
| 		zaf_dbg "Got '$2' <$1> from CLI: $opt" | ||||
| 		return | ||||
| 	fi | ||||
| 	eval opt=\$$1 | ||||
| 	if [ -n "$opt" ] && ! [ "$4" = "user" ]; then | ||||
| 		eval "$1='$opt'" | ||||
| @@ -109,54 +102,73 @@ zaf_set_option(){ | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| # Set config option in zabbix agent config file | ||||
| # $1 option | ||||
| # $2 value | ||||
| zaf_set_agent_option() { | ||||
| 	local option="$1" | ||||
| 	local value="$2" | ||||
| 	if grep -q ^$option\= $ZAF_AGENT_CONFIG; then | ||||
| 		zaf_dbg "Setting option $option in $ZAF_AGENT_CONFIG." | ||||
| 		sed -i "s/$option=\(.*\)/$option=$2/" $ZAF_AGENT_CONFIG | ||||
| # Set config option in zabbix config file | ||||
| # $1 config file | ||||
| # $2 option | ||||
| # $3 value | ||||
| zaf_set_zabbix_option() { | ||||
| 	local cfgfile="$1" | ||||
| 	local option="$2" | ||||
| 	local value="$3" | ||||
| 	if grep -q ^$option\= $cfgfile; then | ||||
| 		zaf_dbg "Setting Zabbix agent option $option in $cfgfile to $3." | ||||
| 		sed -i "s/$option=\(.*\)/$option=$value/" $cfgfile | ||||
| 	else | ||||
| 		 zaf_move_agent_option "$1" "$2" | ||||
| 		 zaf_move_zabbix_option "$1" "$2" "$3" | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| # Unset config option in zabbix agent config file | ||||
| # $1 option | ||||
| zaf_unset_agent_option() { | ||||
| 	local option="$1" | ||||
| 	local value="$2" | ||||
| 	if grep -q ^$option\= $ZAF_AGENT_CONFIG; then | ||||
| 		zaf_dbg "Unsetting option $option in $ZAF_AGENT_CONFIG." | ||||
| 		sed -i "s/$option=\(.*\)/#$option=$2/" $ZAF_AGENT_CONFIG | ||||
| # Get config option from zabbix config file | ||||
| # $1 config file | ||||
| # $2 option | ||||
| zaf_get_zabbix_option() { | ||||
| 	local cfgfile="$1" | ||||
| 	local option="$2" | ||||
| 	grep ^$option\= $cfgfile | cut -d '=' -f 2-; | ||||
| } | ||||
|  | ||||
| # Unset config option in zabbix config file | ||||
| # $1 config file | ||||
| # $2 option | ||||
| zaf_unset_zabbix_option() { | ||||
| 	local cfgfile="$1" | ||||
| 	local option="$2" | ||||
| 	local value="$3" | ||||
| 	if grep -q ^$option\= $cfgfile; then | ||||
| 		zaf_dbg "Unsetting option $option in $cfgfile." | ||||
| 		sed -i "s/$option=\(.*\)/#$option=$2/" $cfgfile | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| # Add config option in zabbix agent  config file | ||||
| # $1 option | ||||
| # $2 value | ||||
| zaf_add_agent_option() { | ||||
| 	local option="$1" | ||||
| 	local value="$2" | ||||
| 	if ! grep -q "^$1=$2" $ZAF_AGENT_CONFIG; then | ||||
| 		zaf_dbg "Adding option $option to $ZAF_AGENT_CONFIG." | ||||
| 		echo "$option=$value" >>$ZAF_AGENT_CONFIG | ||||
| # Add config option in zabbix config file | ||||
| # $1 config file | ||||
| # $2 option | ||||
| # $3 value | ||||
| zaf_add_zabbix_option() { | ||||
| 	local cfgfile="$1" | ||||
| 	local option="$2" | ||||
| 	local value="$3" | ||||
| 	if ! grep -q "^$option=$value" $cfgfile; then | ||||
| 		zaf_dbg "Adding option $option to $cfgfile." | ||||
| 		echo "$option=$value" >>$cfgfile | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| # Move config option fron zabbix agent config file to zaf options file and set value | ||||
| # $1 option | ||||
| # $2 value | ||||
| zaf_move_agent_option() { | ||||
| 	local option="$1" | ||||
| 	local value="$2" | ||||
| 	if grep -q ^$option\= $ZAF_AGENT_CONFIG; then | ||||
| 		zaf_dbg "Moving option $option from $ZAF_AGENT_CONFIG to ." | ||||
| 		sed -i "s/$option=(.*)/$option=$2/" $ZAF_AGENT_CONFIG | ||||
| # Move config option fron zabbix config file to zaf options file and set value | ||||
| # $1 config file | ||||
| # $2 options file | ||||
| # $3 option | ||||
| # $4 value | ||||
| zaf_move_zabbix_option() { | ||||
| 	local cfgfile="$1" | ||||
| 	local optsfile="$2" | ||||
| 	local option="$3" | ||||
| 	local value="$4" | ||||
| 	if grep -q ^$option\= $cfgfile; then | ||||
| 		zaf_dbg "Moving option $option from $cfgfile to $optsfile." | ||||
| 		sed -i "s/$option=(.*)/$option=$value/" $cfgfile | ||||
| 	fi | ||||
| 	[ -n "$value" ] && echo "$option=$value" >> "$ZAF_AGENT_CONFIGD/zaf_options.conf" | ||||
| 	[ -n "$value" ] && echo "$option=$value" >> "$optsfile" | ||||
| } | ||||
|  | ||||
| # Automaticaly configure agent if supported | ||||
| @@ -166,32 +178,75 @@ zaf_configure_agent() { | ||||
| 	local option | ||||
| 	local value | ||||
| 	local options | ||||
| 	local changes | ||||
| 	local aparams | ||||
|  | ||||
|         zaf_install_dir "$ZAF_AGENT_CONFIGD" | ||||
| 	zaf_install_dir "$ZAF_AGENT_CONFIGD" | ||||
| 	echo -n >"$ZAF_AGENT_CONFIGD/zaf_options.conf" || zaf_err "Cannot access $ZAF_AGENT_CONFIGD/zaf_options.conf" | ||||
| 	! [ -f "$ZAF_AGENT_CONFIG" ] && zaf_install "$ZAF_AGENT_CONFIG" | ||||
| 	for pair in "$@"; do | ||||
| 	if [ -n "$ZAF_ZBXSRV_HOST" ]; then | ||||
| 		aparms="Z_Server=$ZAF_ZBXSRV_HOST,localhost Z_ServerActive=$ZAF_ZBXSRV_HOST" | ||||
| 	else | ||||
| 		aparms="" | ||||
| 	fi | ||||
| 	if [ -n "$ZAF_HOSTNAME" ]; then | ||||
| 		aparms="$aparms Z_Hostname=$ZAF_HOSTNAME" | ||||
| 	else | ||||
| 		aparms="$aparms Z_HostnameItem=system.hostname Z_Hostname=" | ||||
| 		zaf_dbg "Using hostname as Hostname item for Zabbix" | ||||
| 	fi | ||||
| 	for pair in $aparms "$@"; do | ||||
| 		echo $pair | grep -q '^Z\_' || continue # Skip non Z_ vars | ||||
| 		option=$(echo $pair|cut -d '=' -f 1|cut -d '_' -f 2) | ||||
| 		value=$(echo $pair|cut -d '=' -f 2-) | ||||
| 		if [ -n "$value" ]; then | ||||
| 			zaf_set_agent_option "$option" "$value" | ||||
| 			zaf_set_zabbix_option "$ZAF_AGENT_CONFIG" "$option" "$value" | ||||
| 		else | ||||
| 			zaf_unset_agent_option "$option" | ||||
| 			zaf_unset_zabbix_option "$ZAF_AGENT_CONFIG" "$option" | ||||
| 		fi | ||||
| 		options="$options Z_$option=$value" | ||||
| 		echo $options |grep -vq "Z_$option=" && options="$options Z_$option=$value" | ||||
| 		changes=1 | ||||
| 	done | ||||
| 	zaf_set_option ZAF_AGENT_OPTIONS "${options}" | ||||
| 	[ -n "$changes" ] # Return false if no changes | ||||
| } | ||||
|  | ||||
| # Automaticaly configure server if supported | ||||
| # Parameters are in format S_zabbixconfvar=value | ||||
| zaf_configure_server() { | ||||
| 	local pair | ||||
| 	local option | ||||
| 	local value | ||||
| 	local options | ||||
| 	local changes | ||||
|  | ||||
| 	zaf_install_dir "$ZAF_SERVER_CONFIGD" | ||||
| 	echo -n >"$ZAF_SERVER_CONFIGD/zaf_options.conf" || zaf_err "Cannot access $ZAF_SERVER_CONFIGD/zaf_options.conf" | ||||
| 	for pair in "$@"; do | ||||
| 		echo $pair | grep -q '^S\_' || continue # Skip non S_ vars | ||||
| 		option=$(echo $pair|cut -d '=' -f 1|cut -d '_' -f 2) | ||||
| 		value=$(echo $pair|cut -d '=' -f 2-) | ||||
| 		if [ -n "$value" ]; then | ||||
| 			zaf_set_zabbix_option "$ZAF_SERVER_CONFIG" "$option" "$value" | ||||
| 		else | ||||
| 			zaf_unset_zabbix_option "$ZAF_SERVER_CONFIG" "$option" | ||||
| 		fi | ||||
| 		options="$options S_$option=$value" | ||||
| 		changes=1 | ||||
| 	done | ||||
| 	zaf_set_option ZAF_SERVER_OPTIONS "${options}" | ||||
| 	[ -n "$changes" ] # Return false if no changes | ||||
| } | ||||
|  | ||||
|  | ||||
| zaf_preconfigure(){ | ||||
| 	zaf_detect_system  | ||||
|         zaf_os_specific zaf_configure_os | ||||
| 	[ -z "$ZAF_OS" ] && zaf_detect_system  | ||||
| 	zaf_os_specific zaf_preconfigure_os | ||||
| 	if ! zaf_is_root; then | ||||
|             [ -z "$INSTALL_PREFIX" ] && zaf_err "We are not root. Use INSTALL_PREFIX or become root." | ||||
| 		[ -z "$INSTALL_PREFIX" ] && zaf_err "We are not root. Use INSTALL_PREFIX or become root." | ||||
| 	else | ||||
| 		[ "$1" != "reconf" ] && zaf_os_specific zaf_check_deps zaf && zaf_err "Zaf is installed as system package. Cannot install." | ||||
|         fi | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| zaf_configure(){ | ||||
| @@ -208,37 +263,52 @@ zaf_configure(){ | ||||
| 			fi | ||||
| 		fi | ||||
| 	fi | ||||
| 	if which git >/dev/null; then | ||||
| 		ZAF_GIT=1 | ||||
| 	else | ||||
| 		ZAF_GIT=0 | ||||
| 	if [ -z "$ZAF_GIT" ]; then | ||||
| 		if zaf_which git >/dev/null; then | ||||
| 			ZAF_GIT=1 | ||||
| 		else | ||||
| 			ZAF_GIT=0 | ||||
| 		fi | ||||
| 	fi | ||||
| 	zaf_get_option ZAF_GIT "Git is installed" "$ZAF_GIT" "$INSTALL_MODE" | ||||
| 	zaf_get_option ZAF_CURL_INSECURE "Insecure curl (accept all certificates)" "1" "$INSTALL_MODE" | ||||
| 	zaf_get_option ZAF_TMP_BASE "Tmp directory prefix (\$USER will be added)" "/tmp/zaf" "$INSTALL_MODE" | ||||
| 	zaf_get_option ZAF_TMP_DIR "Tmp directory" "/tmp/" "$INSTALL_MODE" | ||||
| 	zaf_get_option ZAF_CACHE_DIR "Cache directory" "/tmp/zafc" "$INSTALL_MODE" | ||||
| 	zaf_get_option ZAF_LIB_DIR "Libraries directory" "/usr/lib/zaf" "$INSTALL_MODE" | ||||
|         zaf_get_option ZAF_BIN_DIR "Directory to put binaries" "/usr/bin" "$INSTALL_MODE" | ||||
| 	zaf_get_option ZAF_BIN_DIR "Directory to put binaries" "/usr/bin" "$INSTALL_MODE" | ||||
| 	zaf_get_option ZAF_PLUGINS_DIR "Plugins directory" "${ZAF_LIB_DIR}/plugins" "$INSTALL_MODE" | ||||
| 	[ "${ZAF_GIT}" = 1 ] && zaf_get_option ZAF_REPO_GITURL "Git plugins repository" "https://github.com/limosek/zaf-plugins.git" "$INSTALL_MODE" | ||||
| 	zaf_get_option ZAF_PROXY "http proxy used by zaf" "" "$INSTALL_MODE" | ||||
| 	zaf_get_option ZAF_REPO_URL "Plugins http[s] repository" "https://raw.githubusercontent.com/limosek/zaf-plugins/master/" "$INSTALL_MODE" | ||||
| 	zaf_get_option ZAF_REPO_DIR "Plugins directory" "${ZAF_LIB_DIR}/repo" "$INSTALL_MODE" | ||||
|  | ||||
| 	zaf_get_option ZAF_AGENT_CONFIG "Zabbix agent config" "/etc/zabbix/zabbix_agentd.conf" "$INSTALL_MODE" | ||||
| 	! [ -d "${ZAF_AGENT_CONFIGD}" ] && [ -d "/etc/zabbix/zabbix_agentd.d" ] && ZAF_AGENT_CONFIGD="/etc/zabbix/zabbix_agentd.d" | ||||
| 	[ -z "${ZAF_AGENT_CONFIGD}" ] && ! [ -d "${ZAF_AGENT_CONFIGD}" ] && [ -d "/etc/zabbix/zabbix_agentd.d" ] && ZAF_AGENT_CONFIGD="/etc/zabbix/zabbix_agentd.d" | ||||
| 	zaf_get_option ZAF_AGENT_CONFIGD "Zabbix agent config.d" "/etc/zabbix/zabbix_agentd.conf.d/" "$INSTALL_MODE" | ||||
| 	zaf_get_option ZAF_AGENT_BIN "Zabbix agent binary" "/usr/sbin/zabbix_agentd" "$INSTALL_MODE" | ||||
| 	zaf_get_option ZAF_AGENT_RESTART "Zabbix agent restart cmd" "service zabbix-agent restart" "$INSTALL_MODE" | ||||
| 	zaf_get_option ZAF_ZBXSRV_HOST "Zabbix server hostname" "zabbix" "$INSTALL_MODE" | ||||
| 	zaf_get_option ZAF_ZBXSRV_PORT "Zabbix server port" "10051" "$INSTALL_MODE" | ||||
|  | ||||
| 	zaf_get_option ZAF_SERVER_CONFIG "Zabbix server config" "/etc/zabbix/zabbix_server.conf" "$INSTALL_MODE" | ||||
| 	[ -z "${ZAF_SERVER_CONFIGD}" ] && ! [ -d "${ZAF_SERVER_CONFIGD}" ] && [ -d "/etc/zabbix/zabbix_server.d" ] && ZAF_SERVER_CONFIGD="/etc/zabbix/zabbix_server.d" | ||||
| 	zaf_get_option ZAF_SERVER_CONFIGD "Zabbix server config.d" "/etc/zabbix/zabbix_server.conf.d/" "$INSTALL_MODE" | ||||
| 	zaf_get_option ZAF_SERVER_BIN "Zabbix server binary" "/usr/sbin/zabbix_server" "$INSTALL_MODE" | ||||
| 	zaf_get_option ZAF_HOSTNAME "Hostname of this machine" "" "$INSTALL_MODE" | ||||
| 	 | ||||
| 	zaf_get_option ZAF_SUDOERSD "Sudo sudoers.d directory" "/etc/sudoers.d" "$INSTALL_MODE" | ||||
| 	zaf_get_option ZAF_CROND "Cron.d directory" "/etc/cron.d" "$INSTALL_MODE" | ||||
| 	zaf_get_option ZAF_ZBXAPI_URL "Zabbix API url" "http://localhost/zabbix/api_jsonrpc.php" "$INSTALL_MODE" | ||||
| 	zaf_get_option ZAF_ZBXAPI_USER "Zabbix API user" "zaf" "$INSTALL_MODE" | ||||
| 	zaf_get_option ZAF_ZBXAPI_PASS "Zabbix API password" "" "$INSTALL_MODE" | ||||
| 	zaf_get_option ZAF_ZBXAPI_AUTHTYPE "Zabbix API authentication type" "internal" "$INSTALL_MODE" | ||||
| 	zaf_get_option ZAF_PLUGINS "Plugins to autoinstall" "" "$INSTALL_MODE" | ||||
|  | ||||
| 	if zaf_is_root && ! [ -x $ZAF_AGENT_BIN ]; then | ||||
| 		zaf_err "Zabbix agent ($ZAF_AGENT_BIN) not installed? Use ZAF_AGENT_BIN env variable to specify location. Exiting." | ||||
| 	fi | ||||
|  | ||||
|         [ -n "$INSTALL_PREFIX" ] && zaf_install_dir "/etc" | ||||
| 	[ -n "$INSTALL_PREFIX" ] && zaf_install_dir "/etc" | ||||
| 	if ! [ -f "${ZAF_CFG_FILE}" ]; then | ||||
| 		touch "${ZAF_CFG_FILE}" || zaf_err "No permissions to ${ZAF_CFG_FILE}" | ||||
| 	fi | ||||
| @@ -249,83 +319,176 @@ zaf_configure(){ | ||||
| 	zaf_set_option ZAF_AGENT_PKG "${ZAF_AGENT_PKG}" | ||||
| 	zaf_set_option ZAF_GIT "${ZAF_GIT}" | ||||
| 	zaf_set_option ZAF_CURL_INSECURE "${ZAF_CURL_INSECURE}" | ||||
| 	zaf_set_option ZAF_TMP_BASE "$ZAF_TMP_BASE" | ||||
| 	zaf_set_option ZAF_TMP_DIR "$ZAF_TMP_DIR" | ||||
| 	zaf_set_option ZAF_CACHE_DIR "$ZAF_CACHE_DIR" | ||||
| 	zaf_set_option ZAF_LIB_DIR "$ZAF_LIB_DIR" | ||||
|         zaf_set_option ZAF_BIN_DIR "$ZAF_BIN_DIR" | ||||
| 	zaf_set_option ZAF_BIN_DIR "$ZAF_BIN_DIR" | ||||
| 	zaf_set_option ZAF_PLUGINS_DIR "$ZAF_PLUGINS_DIR" | ||||
| 	zaf_set_option ZAF_REPO_URL "$ZAF_REPO_URL" | ||||
| 	zaf_set_option ZAF_PROXY "$ZAF_PROXY" | ||||
| 	[ "${ZAF_GIT}" = 1 ] && zaf_set_option ZAF_REPO_GITURL "$ZAF_REPO_GITURL" | ||||
| 	zaf_set_option ZAF_REPO_DIR "$ZAF_REPO_DIR" | ||||
| 	zaf_set_option ZAF_AGENT_CONFIG "$ZAF_AGENT_CONFIG" | ||||
| 	zaf_set_option ZAF_AGENT_CONFIGD "$ZAF_AGENT_CONFIGD" | ||||
| 	zaf_set_option ZAF_AGENT_BIN "$ZAF_AGENT_BIN" | ||||
| 	zaf_set_option ZAF_FILES_UID "$ZAF_FILES_UID" | ||||
| 	zaf_set_option ZAF_FILES_GID "$ZAF_FILES_GID" | ||||
| 	zaf_set_option ZAF_FILES_UMASK "$ZAF_FILES_UMASK" | ||||
| 	zaf_set_option ZAF_AGENT_RESTART "$ZAF_AGENT_RESTART" | ||||
| 	zaf_set_option ZAF_ZBXSRV_HOST "$ZAF_ZBXSRV_HOST" | ||||
| 	zaf_set_option ZAF_ZBXSRV_PORT "$ZAF_ZBXSRV_PORT" | ||||
| 	zaf_set_option ZAF_HOSTNAME "$ZAF_HOSTNAME" | ||||
| 	if [ -x "$ZAF_SERVER_BIN" ]; then | ||||
| 		zaf_set_option ZAF_SERVER_CONFIG "$ZAF_SERVER_CONFIG" | ||||
| 		zaf_set_option ZAF_SERVER_CONFIGD "$ZAF_SERVER_CONFIGD" | ||||
| 		zaf_set_option ZAF_SERVER_EXTSCRIPTS "$(zaf_get_zabbix_option $ZAF_SERVER_CONFIG ExternalScripts)" | ||||
| 		zaf_set_option ZAF_SERVER_BIN "$ZAF_SERVER_BIN" | ||||
| 	else | ||||
| 		zaf_set_option ZAF_SERVER_CONFIG "" | ||||
| 		zaf_set_option ZAF_SERVER_BIN "" | ||||
| 		zaf_set_option ZAF_SERVER_CONFIGD "" | ||||
| 		zaf_set_option ZAF_SERVER_EXTSCRIPTS "" | ||||
| 	fi | ||||
| 	zaf_set_option ZAF_SUDOERSD "$ZAF_SUDOERSD" | ||||
| 	zaf_set_option ZAF_CROND "$ZAF_CROND" | ||||
| 	zaf_set_option ZAF_ZBXAPI_URL "$ZAF_ZBXAPI_URL" | ||||
| 	zaf_set_option ZAF_ZBXAPI_USER "$ZAF_ZBXAPI_USER" | ||||
| 	zaf_set_option ZAF_ZBXAPI_PASS "$ZAF_ZBXAPI_PASS" | ||||
| 	zaf_set_option ZAF_ZBXAPI_AUTHTYPE "$ZAF_ZBXAPI_AUTHTYPE" | ||||
| 	[ -n "$ZAF_PREPACKAGED_DIR" ] && zaf_set_option ZAF_PREPACKAGED_DIR "$ZAF_PREPACKAGED_DIR" | ||||
| 	if [ -n "$ZAF_PLUGINS" ]; then | ||||
| 		for p in $(echo $ZAF_PLUGINS | tr ',' ' '); do | ||||
| 			zaf_install_plugin $p | ||||
| 		done | ||||
| 	fi | ||||
|  | ||||
| 	if zaf_is_root; then | ||||
|         	zaf_configure_agent $ZAF_AGENT_OPTIONS "$@" | ||||
| 		zaf_add_agent_option "Include" "$ZAF_AGENT_CONFIGD" | ||||
| 		zaf_configure_agent $ZAF_AGENT_OPTIONS "$@" | ||||
| 		zaf_add_zabbix_option "$ZAF_AGENT_CONFIG" "Include" "$ZAF_AGENT_CONFIGD" | ||||
| 		if [ -f "$ZAF_SERVER_BIN" ]; then | ||||
| 			zaf_configure_server $ZAF_SERVER_OPTIONS "$@" && zaf_add_zabbix_option "$ZAF_SERVER_CONFIG" "Include" "$ZAF_SERVER_CONFIGD" | ||||
| 		else | ||||
| 			zaf_wrn "Skipping server config. Zabbix server binary '$ZAF_SERVER_BIN' not found." | ||||
| 		fi | ||||
| 	fi | ||||
|  | ||||
| 	if ! [ -d $ZAF_CACHE_DIR ]; then | ||||
| 		mkdir -p "$ZAF_CACHE_DIR" | ||||
| 		if zaf_is_root && [ -n "$ZAF_FILES_UID" ] && [ -n "$ZAF_FILES_GID" ]; then | ||||
| 			zaf_wrn "Cache: Changing perms to $ZAF_CACHE_DIR (zabbix/$ZAF_ZABBIX_GID/0770)" | ||||
| 			chown $ZAF_FILES_UID "$ZAF_CACHE_DIR" | ||||
| 			chgrp $ZAF_FILES_GID "$ZAF_CACHE_DIR" | ||||
| 			chmod $ZAF_FILES_UMASK "$ZAF_CACHE_DIR" | ||||
| 		fi | ||||
| 	fi | ||||
| 	zaf_cache_init | ||||
| } | ||||
|  | ||||
| zaf_install_all() { | ||||
| 	rm -rif ${ZAF_TMP_DIR} | ||||
| 	mkdir -p ${ZAF_TMP_DIR} | ||||
| 	zaf_install_dir ${ZAF_LIB_DIR} | ||||
| 	for i in lib/zaf.lib.sh lib/os.lib.sh lib/ctrl.lib.sh lib/cache.lib.sh lib/zbxapi.lib.sh README.md; do | ||||
| 		zaf_install $i ${ZAF_LIB_DIR}/ || zaf_err "Error installing $i" | ||||
| 	for i in lib/zaf.lib.sh lib/plugin.lib.sh lib/os.lib.sh lib/ctrl.lib.sh lib/cache.lib.sh lib/zbxapi.lib.sh lib/JSON.sh; do | ||||
| 		zaf_install $i ${ZAF_LIB_DIR}/  | ||||
| 	done | ||||
| 	for i in lib/zaflock lib/preload.sh; do | ||||
| 		zaf_install_bin $i ${ZAF_LIB_DIR}/ || zaf_err "Error installing $i" | ||||
| 	for i in lib/zaflock lib/zafcache lib/preload.sh lib/zafret; do | ||||
| 		zaf_install_bin $i ${ZAF_LIB_DIR}/  | ||||
| 	done | ||||
| 	zaf_install_dir ${ZAF_BIN_DIR} | ||||
| 	for i in zaf; do | ||||
| 		zaf_install_bin $i ${ZAF_BIN_DIR}/ || zaf_err "Error installing $i" | ||||
| 		zaf_install_bin $i ${ZAF_BIN_DIR}/  | ||||
| 	done | ||||
| 	zaf_install_dir ${ZAF_PLUGINS_DIR} | ||||
| 	zaf_install_dir ${ZAF_PLUGINS_DIR} | ||||
|         zaf_install_dir ${ZAF_BIN_DIR} | ||||
| 	zaf_install_dir ${ZAF_BIN_DIR} | ||||
| } | ||||
|  | ||||
| zaf_postconfigure() { | ||||
| 	if zaf_is_root; then | ||||
| 	    [ "${ZAF_GIT}" = 1 ] && ${INSTALL_PREFIX}/${ZAF_BIN_DIR}/zaf update | ||||
|             ${INSTALL_PREFIX}/${ZAF_BIN_DIR}/zaf reinstall zaf || zaf_err "Error installing zaf plugin." | ||||
|             if zaf_is_root && ! zaf_test_item zaf.framework_version; then | ||||
| 		 ${INSTALL_PREFIX}/${ZAF_BIN_DIR}/zaf cache-clean | ||||
| 		 [ "${ZAF_GIT}" = 1 ] && ${INSTALL_PREFIX}/${ZAF_BIN_DIR}/zaf update | ||||
| 		 ${INSTALL_PREFIX}/${ZAF_BIN_DIR}/zaf reinstall zaf || zaf_err "Error installing zaf plugin." | ||||
| 		 ${INSTALL_PREFIX}/${ZAF_BIN_DIR}/zaf agent-config || zaf_err "Error configuring agent." | ||||
| 		 zaf_os_specific zaf_postconfigure_os | ||||
| 		 if zaf_is_root && ! zaf_test_item zaf.framework_version; then | ||||
| 		echo "Something is wrong with zabbix agent config." | ||||
| 		echo "Ensure that zabbix_agentd reads ${ZAF_AGENT_CONFIG}" | ||||
| 		echo "and there is Include=${ZAF_AGENT_CONFIGD} directive inside." | ||||
| 		echo "Does ${ZAF_AGENT_RESTART} work?" | ||||
| 		exit 1 | ||||
|             fi | ||||
| 		 fi | ||||
| 	else | ||||
| 	    [ "${ZAF_GIT}" = 1 ] && [ -n  "${INSTALL_PREFIX}" ] && git clone "${ZAF_REPO_GITURL}" "${INSTALL_PREFIX}/${ZAF_REPO_DIR}" | ||||
|         fi | ||||
| 		 [ "${ZAF_GIT}" = 1 ] && [ -n	 "${INSTALL_PREFIX}" ] && git clone "${ZAF_REPO_GITURL}" "${INSTALL_PREFIX}/${ZAF_REPO_DIR}" | ||||
| 	fi | ||||
| 	zaf_wrn "Install done. Use 'zaf' to get started." | ||||
| 	true | ||||
| } | ||||
|  | ||||
| ############ First stage Init | ||||
|  | ||||
| if ! [ -f README.md ]; then | ||||
| 	# Hardcoded variables | ||||
| 	ZAF_VERSION="1.4" | ||||
| 	export ZAF_TMP_DIR="/tmp/zaf-installer" | ||||
| 	export ZAF_DIR="$ZAF_TMP_DIR/zaf" | ||||
| 	if [ -n "$ZAF_PROXY" ]; then | ||||
| 		export ALL_PROXY="$ZAF_PROXY" | ||||
| 		export http_proxy="$ZAF_PROXY" | ||||
| 		export https_proxy="$ZAF_PROXY" | ||||
| 	fi | ||||
| 	mkdir -p $ZAF_TMP_DIR | ||||
| 	if ! zaf_which curl >/dev/null && ! zaf_which wget >/dev/null; | ||||
| 	then | ||||
| 		zaf_err "Curl or wget not found. Cannot continue. Please install it." | ||||
| 	fi | ||||
| 	echo "Installing from url $url..." | ||||
| 	[ -z "$*" ] && auto=auto | ||||
| 	zaf_download_files && cd $ZAF_DIR && exec ./install.sh $auto "$@" | ||||
| 	echo "Error downloading and runing installer!" >&2 | ||||
| 	exit 2 | ||||
| fi | ||||
|  | ||||
| # Try to load local downloaded libs | ||||
| if ! type zaf_version >/dev/null 2>/dev/null; then | ||||
| . lib/zaf.lib.sh | ||||
| . lib/plugin.lib.sh | ||||
| . lib/os.lib.sh | ||||
| . lib/ctrl.lib.sh  | ||||
| . lib/cache.lib.sh  | ||||
| . lib/zbxapi.lib.sh  | ||||
| fi | ||||
| # If something was wrong reading libs, then exit | ||||
| if ! type zaf_version >/dev/null; then | ||||
| 	echo "Problem loading libraries?" | ||||
| 	exit 2 | ||||
| fi | ||||
|  | ||||
| ########### Second stage init (all functions loaded) | ||||
|  | ||||
| [ -z "$ZAF_CFG_FILE" ] && ZAF_CFG_FILE=$INSTALL_PREFIX/etc/zaf.conf | ||||
| if [ -f "${ZAF_CFG_FILE}" ]; then | ||||
| 	. "${ZAF_CFG_FILE}" | ||||
| fi | ||||
| ZAF_TMP_DIR="/tmp/zaf-installer-tmp/" | ||||
| export ZAF_TMP_DIR="/tmp/zaf-installer" | ||||
| export ZAF_DIR="$ZAF_TMP_DIR/zaf" | ||||
|  | ||||
| # If debug is on, do not remove tmp dir  | ||||
| if [ "$ZAF_DEBUG" -le 3 ]; then | ||||
| 	trap "rm -rif ${ZAF_TMP_DIR}" EXIT | ||||
| 	trap "rm -rif /tmp/zaf-installer" EXIT | ||||
| ! [ -d $ZAF_TMP_DIR ] && mkdir -p $ZAF_TMP_DIR | ||||
| zaf_debug_init stderr | ||||
| zaf_tmp_init | ||||
|  | ||||
| # Read options as config for ZAF | ||||
| for pair in "$@"; do | ||||
| 	 echo $pair | grep -q '^ZAF\_' || continue | ||||
| 	 option=$(echo $pair|cut -d '=' -f 1) | ||||
| 	 value=$(echo $pair|cut -d '=' -f 2-) | ||||
| 	 eval "C_${option}='$value'" | ||||
| 	 zaf_wrn "Overriding $option from cmdline." | ||||
| done | ||||
| [ -z "$C_ZAF_TMP_DIR" ] && C_ZAF_TMP_DIR="/tmp/" | ||||
| if [ -n "$ZAF_PROXY" ]; then | ||||
| 	export ALL_PROXY="$ZAF_PROXY" | ||||
| fi | ||||
| ! [ -d "${ZAF_TMP_DIR}" ] && mkdir "${ZAF_TMP_DIR}" | ||||
|  | ||||
| case $1 in | ||||
| interactive) | ||||
|         shift | ||||
| 	shift | ||||
| 	INSTALL_MODE=interactive | ||||
| 	zaf_preconfigure | ||||
| 	zaf_configure "$@" | ||||
| @@ -333,52 +496,52 @@ interactive) | ||||
| 	zaf_postconfigure | ||||
| 	;; | ||||
| auto) | ||||
|         shift | ||||
| 	shift | ||||
| 	INSTALL_MODE=auto | ||||
| 	zaf_preconfigure | ||||
| 	zaf_configure "$@" | ||||
|         zaf_install_all | ||||
| 	zaf_install_all | ||||
| 	zaf_postconfigure | ||||
|         ;; | ||||
| 	;; | ||||
| debug-auto) | ||||
|         shift; | ||||
| 	shift; | ||||
| 	ZAF_DEBUG=4 | ||||
| 	INSTALL_MODE=auto | ||||
| 	zaf_preconfigure | ||||
|         zaf_configure "$@" | ||||
| 	zaf_configure "$@" | ||||
| 	zaf_install_all | ||||
| 	zaf_postconfigure | ||||
|         ;; | ||||
| 	;; | ||||
| debug-interactive) | ||||
|         shift; | ||||
|         ZAF_DEBUG=4 | ||||
| 	shift; | ||||
| 	ZAF_DEBUG=4 | ||||
| 	INSTALL_MODE=interactive | ||||
| 	zaf_preconfigure | ||||
| 	zaf_configure "$@" | ||||
| 	zaf_install_all | ||||
| 	zaf_postconfigure | ||||
|         ;; | ||||
| 	;; | ||||
| debug) | ||||
|         shift; | ||||
|         ZAF_DEBUG=4 | ||||
| 	shift; | ||||
| 	ZAF_DEBUG=4 | ||||
| 	INSTALL_MODE=auto | ||||
| 	zaf_preconfigure | ||||
| 	zaf_configure "$@" | ||||
| 	zaf_install_all | ||||
| 	zaf_postconfigure | ||||
|         ;; | ||||
| 	;; | ||||
| reconf) | ||||
|         shift; | ||||
|         rm -f $ZAF_CFG_FILE | ||||
| 	shift; | ||||
| 	rm -f $ZAF_CFG_FILE | ||||
| 	INSTALL_MODE=auto | ||||
| 	zaf_preconfigure reconf | ||||
| 	zaf_configure "$@" | ||||
| 	zaf_postconfigure | ||||
|         ;; | ||||
| 	;; | ||||
| install) | ||||
| 	INSTALL_MODE=auto | ||||
| 	zaf_preconfigure nor | ||||
|         zaf_configure "$@" | ||||
| 	zaf_configure "$@" | ||||
| 	zaf_install_all | ||||
| 	zaf_postconfigure | ||||
| 	;; | ||||
| @@ -386,16 +549,18 @@ install) | ||||
| 	echo | ||||
| 	echo "Please specify how to install." | ||||
| 	echo "install.sh {auto|interactive|debug-auto|debug-interactive|reconf} [Agent-Options] [Zaf-Options]" | ||||
|         echo "scratch means that config file will be created from scratch" | ||||
|         echo " Agent-Options: Z_Option=value [...]" | ||||
|         echo " Zaf-Options: ZAF_OPT=value [...]" | ||||
| 	echo "scratch means that config file will be created from scratch" | ||||
| 	echo " Agent-Options: Z_Option=value [...]" | ||||
| 	echo " Server-Options: S_Option=value [...]" | ||||
| 	echo " Zaf-Options: ZAF_OPT=value [...]" | ||||
| 	echo " To unset Agent-Option use Z_Option=''" | ||||
|         echo  | ||||
| 	echo  | ||||
| 	echo "Example 1 (default install): install.sh auto" | ||||
| 	echo 'Example 2 (preconfigure agent options): install.sh auto A_Server=zabbix.server A_ServerActive=zabbix.server A_Hostname=$(hostname)' | ||||
| 	echo "Example 3 (preconfigure zaf packaging system to use): install.sh auto ZAF_PKG=opkg" | ||||
| 	echo "Example 4 (interactive): install.sh interactive" | ||||
| 	echo | ||||
| 	echo 'Example 2 (preconfigure agent options): install.sh auto Z_Server=zabbix.server Z_ServerActive=zabbix.server Z_Hostname=$(hostname)' | ||||
| 	echo 'Example 3 (preconfigure server options): install.sh auto S_StartPollers=10 S_ListenPort=10051' | ||||
| 	echo "Example 4 (preconfigure zaf packaging system to use): install.sh auto ZAF_PKG=opkg" | ||||
| 	echo "Example 5 (interactive): install.sh interactive" | ||||
| 	echo  | ||||
| 	exit 1 | ||||
| esac | ||||
|  | ||||
|   | ||||
							
								
								
									
										10
									
								
								ipk.mk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								ipk.mk
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| # Makefile for generating openwrt ipk packages | ||||
| # Contrinutions welcome :) | ||||
|  | ||||
| ifeq ($(IPK_PKG),) | ||||
|  IPK_PKG=$(shell . lib/zaf.lib.sh; echo out/zaf-$$ZAF_VERSION.ipk) | ||||
| endif | ||||
|  | ||||
| $(IPK_PKG): | ||||
| 	@echo "Not supported yet. Contributions welcomed! :) "; exit 2 | ||||
|  | ||||
							
								
								
									
										208
									
								
								lib/JSON.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										208
									
								
								lib/JSON.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,208 @@ | ||||
| #!/bin/sh | ||||
|  | ||||
| throw() { | ||||
| 	echo "$*" >&2 | ||||
| 	exit 1 | ||||
| } | ||||
|  | ||||
| BRIEF=0 | ||||
| LEAFONLY=0 | ||||
| PRUNE=0 | ||||
| NO_HEAD=0 | ||||
| NORMALIZE_SOLIDUS=0 | ||||
|  | ||||
| usage() { | ||||
| 	echo | ||||
| 	echo "Usage: JSON.sh [-b] [-l] [-p] [-s] [-h]" | ||||
| 	echo | ||||
| 	echo "-p - Prune empty. Exclude fields with empty values." | ||||
| 	echo "-l - Leaf only. Only show leaf nodes, which stops data duplication." | ||||
| 	echo "-b - Brief. Combines 'Leaf only' and 'Prune empty' options." | ||||
| 	echo "-n - No-head. Do not show nodes that have no path (lines that start with [])." | ||||
| 	echo "-s - Remove escaping of the solidus symbol (stright slash)." | ||||
| 	echo "-h - This help text." | ||||
| 	echo | ||||
| } | ||||
|  | ||||
| parse_options() { | ||||
| 	set -- "$@" | ||||
| 	local ARGN=$# | ||||
| 	while [ "$ARGN" -ne 0 ] | ||||
| 	do | ||||
| 		case $1 in | ||||
| 			-h) usage | ||||
| 					exit 0 | ||||
| 			;; | ||||
| 			-b) BRIEF=1 | ||||
| 					LEAFONLY=1 | ||||
| 					PRUNE=1 | ||||
| 			;; | ||||
| 			-l) LEAFONLY=1 | ||||
| 			;; | ||||
| 			-p) PRUNE=1 | ||||
| 			;; | ||||
| 			-n) NO_HEAD=1 | ||||
| 			;; | ||||
| 			-s) NORMALIZE_SOLIDUS=1 | ||||
| 			;; | ||||
| 			?*) echo "ERROR: Unknown option." | ||||
| 					usage | ||||
| 					exit 0 | ||||
| 			;; | ||||
| 		esac | ||||
| 		shift 1 | ||||
| 		ARGN=$((ARGN-1)) | ||||
| 	done | ||||
| } | ||||
|  | ||||
| awk_egrep () { | ||||
| 	local pattern_string=$1 | ||||
|  | ||||
| 	gawk '{ | ||||
| 		while ($0) { | ||||
| 			start=match($0, pattern); | ||||
| 			token=substr($0, start, RLENGTH); | ||||
| 			print token; | ||||
| 			$0=substr($0, start+RLENGTH); | ||||
| 		} | ||||
| 	}' pattern="$pattern_string" | ||||
| } | ||||
|  | ||||
| tokenize () { | ||||
| 	local GREP | ||||
| 	local ESCAPE | ||||
| 	local CHAR | ||||
|  | ||||
| 	if echo "test string" | egrep -ao --color=never "test" >/dev/null 2>&1 | ||||
| 	then | ||||
| 		GREP='egrep -ao --color=never' | ||||
| 	else | ||||
| 		GREP='egrep -ao' | ||||
| 	fi | ||||
|  | ||||
| 	if echo "test string" | egrep -o "test" >/dev/null 2>&1 | ||||
| 	then | ||||
| 		ESCAPE='(\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})' | ||||
| 		CHAR='[^[:cntrl:]"\\]' | ||||
| 	else | ||||
| 		GREP=awk_egrep | ||||
| 		ESCAPE='(\\\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})' | ||||
| 		CHAR='[^[:cntrl:]"\\\\]' | ||||
| 	fi | ||||
|  | ||||
| 	local STRING="\"$CHAR*($ESCAPE$CHAR*)*\"" | ||||
| 	local NUMBER='-?(0|[1-9][0-9]*)([.][0-9]*)?([eE][+-]?[0-9]*)?' | ||||
| 	local KEYWORD='null|false|true' | ||||
| 	local SPACE='[[:space:]]+' | ||||
|  | ||||
| 	# Force zsh to expand $A into multiple words | ||||
| 	local is_wordsplit_disabled=$(unsetopt 2>/dev/null | grep -c '^shwordsplit$') | ||||
| 	if [ $is_wordsplit_disabled != 0 ]; then setopt shwordsplit; fi | ||||
| 	$GREP "$STRING|$NUMBER|$KEYWORD|$SPACE|." | egrep -v "^$SPACE$" | ||||
| 	if [ $is_wordsplit_disabled != 0 ]; then unsetopt shwordsplit; fi | ||||
| } | ||||
|  | ||||
| parse_array () { | ||||
| 	local index=0 | ||||
| 	local ary='' | ||||
| 	read -r token | ||||
| 	case "$token" in | ||||
| 		']') ;; | ||||
| 		*) | ||||
| 			while : | ||||
| 			do | ||||
| 				parse_value "$1" "$index" | ||||
| 				index=$((index+1)) | ||||
| 				ary="$ary""$value"  | ||||
| 				read -r token | ||||
| 				case "$token" in | ||||
| 					']') break ;; | ||||
| 					',') ary="$ary," ;; | ||||
| 					*) throw "EXPECTED , or ] GOT ${token:-EOF}" ;; | ||||
| 				esac | ||||
| 				read -r token | ||||
| 			done | ||||
| 			;; | ||||
| 	esac | ||||
| 	[ "$BRIEF" -eq 0 ] && value=$(printf '[%s]' "$ary") || value= | ||||
| 	: | ||||
| } | ||||
|  | ||||
| parse_object () { | ||||
| 	local key | ||||
| 	local obj='' | ||||
| 	read -r token | ||||
| 	case "$token" in | ||||
| 		'}') ;; | ||||
| 		*) | ||||
| 			while : | ||||
| 			do | ||||
| 				case "$token" in | ||||
| 					'"'*'"') key=$token ;; | ||||
| 					*) throw "EXPECTED string GOT ${token:-EOF}" ;; | ||||
| 				esac | ||||
| 				read -r token | ||||
| 				case "$token" in | ||||
| 					':') ;; | ||||
| 					*) throw "EXPECTED : GOT ${token:-EOF}" ;; | ||||
| 				esac | ||||
| 				read -r token | ||||
| 				parse_value "$1" "$key" | ||||
| 				obj="$obj$key:$value"				  | ||||
| 				read -r token | ||||
| 				case "$token" in | ||||
| 					'}') break ;; | ||||
| 					',') obj="$obj," ;; | ||||
| 					*) throw "EXPECTED , or } GOT ${token:-EOF}" ;; | ||||
| 				esac | ||||
| 				read -r token | ||||
| 			done | ||||
| 		;; | ||||
| 	esac | ||||
| 	[ "$BRIEF" -eq 0 ] && value=$(printf '{%s}' "$obj") || value= | ||||
| 	: | ||||
| } | ||||
|  | ||||
| parse_value () { | ||||
| 	local jpath="${1:+$1,}$2" isleaf=0 isempty=0 print=0 | ||||
| 	case "$token" in | ||||
| 		'{') parse_object "$jpath" ;; | ||||
| 		'[') parse_array	"$jpath" ;; | ||||
| 		# At this point, the only valid single-character tokens are digits. | ||||
| 		''|[!0-9]) throw "EXPECTED value GOT ${token:-EOF}" ;; | ||||
| 		*) value=$token | ||||
| 			 # if asked, replace solidus ("\/") in json strings with normalized value: "/" | ||||
| 			 [ "$NORMALIZE_SOLIDUS" -eq 1 ] && value=$(echo "$value" | sed 's#\\/#/#g') | ||||
| 			 isleaf=1 | ||||
| 			 [ "$value" = '""' ] && isempty=1 | ||||
| 			 ;; | ||||
| 	esac | ||||
| 	[ "$value" = '' ] && return | ||||
| 	[ "$NO_HEAD" -eq 1 ] && [ -z "$jpath" ] && return | ||||
|  | ||||
| 	[ "$LEAFONLY" -eq 0 ] && [ "$PRUNE" -eq 0 ] && print=1 | ||||
| 	[ "$LEAFONLY" -eq 1 ] && [ "$isleaf" -eq 1 ] && [ $PRUNE -eq 0 ] && print=1 | ||||
| 	[ "$LEAFONLY" -eq 0 ] && [ "$PRUNE" -eq 1 ] && [ "$isempty" -eq 0 ] && print=1 | ||||
| 	[ "$LEAFONLY" -eq 1 ] && [ "$isleaf" -eq 1 ] && \ | ||||
| 		[ $PRUNE -eq 1 ] && [ $isempty -eq 0 ] && print=1 | ||||
| 	[ "$print" -eq 1 ] && printf "[%s]\t%s\n" "$jpath" "$value" | ||||
| 	: | ||||
| } | ||||
|  | ||||
| parse () { | ||||
| 	read -r token | ||||
| 	parse_value | ||||
| 	read -r token | ||||
| 	case "$token" in | ||||
| 		'') ;; | ||||
| 		*) throw "EXPECTED EOF GOT $token" ;; | ||||
| 	esac | ||||
| } | ||||
|  | ||||
| if ([ "$0" = "$BASH_SOURCE" ] || ! [ -n "$BASH_SOURCE" ]); | ||||
| then | ||||
| 	parse_options "$@" | ||||
| 	tokenize | parse | ||||
| fi | ||||
|  | ||||
| # vi: expandtab sw=2 ts=2 | ||||
							
								
								
									
										132
									
								
								lib/cache.lib.sh
									
									
									
									
									
								
							
							
						
						
									
										132
									
								
								lib/cache.lib.sh
									
									
									
									
									
								
							| @@ -1,18 +1,54 @@ | ||||
| # Zaf cache related functions | ||||
|  | ||||
| zaf_cache_clean(){ | ||||
| 	if [ -n "$ZAF_CACHE_DIR" ]; then | ||||
| 		zaf_wrn "Removing cache entries" | ||||
| 		rm -rf "$ZAF_CACHE_DIR" | ||||
| 	else | ||||
| 		zaf_err "Cache dir not set." | ||||
| zaf_cache_init(){ | ||||
| 	local files | ||||
| 	local file | ||||
|  | ||||
| 	if [ "$ZAF_CACHE_DIR" = "/tmp/zafc" ] && ! [ -d "$ZAF_CACHE_DIR" ]; then | ||||
| 		mkdir -p $ZAF_CACHE_DIR | ||||
| 		chown $ZAF_FILES_UID $ZAF_CACHE_DIR >/dev/null 2>/dev/null | ||||
| 	fi | ||||
| 	mkdir -p "$ZAF_CACHE_DIR" | ||||
| 	if ! [ -w $ZAF_CACHE_DIR ]; then | ||||
| 		zaf_dbg "Cache dir $ZAF_CACHE_DIR is not accessible! Disabling cache." | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| zaf_cache_clean(){ | ||||
| 	local files | ||||
|  | ||||
| 	if [ -w "$ZAF_CACHE_DIR" ]; then | ||||
| 		zaf_wrn "Removing cache entries" | ||||
| 		files=$(find $ZAF_CACHE_DIR/ -type f) | ||||
| 		[ -n "$files" ] && rm -f $files | ||||
| 	else | ||||
| 		zaf_dbg "Cache dir not set. Disabling cache." | ||||
| 	fi | ||||
| 	zaf_cache_init | ||||
| } | ||||
|  | ||||
| # Get cache key from requested param | ||||
| zaf_cache_key(){ | ||||
| 	echo "$1" | md5sum - | cut -d ' ' -f 1 | ||||
| 	echo "$1" | (md5sum - ||md5) 2>/dev/null | cut -d ' ' -f 1 | ||||
| } | ||||
|  | ||||
| # Wait for lock  | ||||
| # $1 - key | ||||
| zaf_cache_lock(){ | ||||
| 	local lockfile | ||||
| 	lockfile="${ZAF_CACHE_DIR}/${key}.lock" | ||||
| 	 | ||||
| 	[ -f "$lockfile" ] && sleep 1 | ||||
| 	[ -f "$lockfile" ] && return 1 | ||||
| 	return 0 | ||||
| } | ||||
|  | ||||
| # Unlock cache key | ||||
| # $1 - key | ||||
| zaf_cache_unlock(){ | ||||
| 	local lockfile | ||||
| 	lockfile="${ZAF_CACHE_DIR}/${key}.lock" | ||||
| 	 | ||||
| 	rm -f $lockfile | ||||
| } | ||||
|  | ||||
| # Put object into cache | ||||
| @@ -20,34 +56,53 @@ zaf_cache_key(){ | ||||
| # $2 value | ||||
| # $3 lifetime in seconds | ||||
| zaf_tocache(){ | ||||
| 	! [ -w $ZAF_CACHE_DIR ] && return 1 | ||||
| 	! [ -w $ZAF_CACHE_DIR ] && return | ||||
| 	local key | ||||
| 	local value | ||||
| 	local expiry | ||||
| 	local infofile | ||||
| 	local datafile | ||||
|  | ||||
| 	key=$(zaf_cache_key "$1") | ||||
| 	echo "$2" >$ZAF_CACHE_DIR/$key | ||||
| 	echo "$1" >$ZAF_CACHE_DIR/$key.info | ||||
| 	touch -m -d "$3 seconds" $ZAF_CACHE_DIR/$key.info | ||||
| 	zaf_trc "Cache: Saving entry $1($key)" | ||||
| 	datafile=${ZAF_CACHE_DIR}/$key | ||||
| 	infofile=${ZAF_CACHE_DIR}/${key}.info | ||||
|  | ||||
| 	zaf_cache_lock "$key" || { zaf_wrn "Cache: Entry $1[$key] locked!"; return 1; } | ||||
|  | ||||
| 	rm -f $datafile $infofile | ||||
| 	echo "$2" >$datafile | ||||
| 	echo "$1" >$infofile | ||||
| 	expiry=$(zaf_date_add "$3") | ||||
| 	zaf_trc "Cache: Saving entry $1[$key,expiry=$expiry]" | ||||
| 	touch -m -d "$expiry" $infofile | ||||
| 	zaf_cache_unlock $key | ||||
| } | ||||
|  | ||||
| # Put object into cache from stdin and copy to stdout | ||||
| # $1 key | ||||
| # $2 lifetime in seconds | ||||
| zaf_tocache_stdin(){ | ||||
| 	! [ -w $ZAF_CACHE_DIR ] && return 1 | ||||
| 	! [ -w $ZAF_CACHE_DIR ] && { cat; return; } | ||||
| 	local key | ||||
| 	local expiry | ||||
| 	local infofile | ||||
| 	local datafile | ||||
|  | ||||
| 	key=$(zaf_cache_key "$1") | ||||
| 	cat >$ZAF_CACHE_DIR/$key | ||||
| 	if [ -s $ZAF_CACHE_DIR/$key ]; then | ||||
| 		zaf_trc "Cache: Saving entry $1($key)" | ||||
| 		echo "$1" >$ZAF_CACHE_DIR/$key.info | ||||
| 		touch -m -d "$2 seconds" $ZAF_CACHE_DIR/$key.info | ||||
| 		cat $ZAF_CACHE_DIR/$key | ||||
| 	else | ||||
| 		rm $ZAF_CACHE_DIR/$key | ||||
| 	fi | ||||
| 	datafile=${ZAF_CACHE_DIR}/$key | ||||
| 	lockfile=${ZAF_CACHE_DIR}/${key}.lock | ||||
| 	infofile=${ZAF_CACHE_DIR}/${key}.info | ||||
|  | ||||
| 	zaf_cache_lock "$key" || { zaf_wrn "Cache: Entry $1[$key] locked!"; return 1; } | ||||
|  | ||||
| 	rm -f $datafile $infofile | ||||
| 	cat >$datafile | ||||
| 	expiry="$(zaf_date_add $2)" | ||||
| 	echo "$1 [key=$key,expiry=$expiry]" >$infofile | ||||
| 	zaf_trc "Cache: Saving entry $1[key=$key,expiry=$expiry]" | ||||
| 	touch -m -d "$expiry" $infofile | ||||
| 	zaf_cache_unlock "$key" | ||||
| 	cat $datafile | ||||
| } | ||||
|  | ||||
| # Remove entry from cache | ||||
| @@ -57,23 +112,39 @@ zaf_cache_delentry(){ | ||||
| 	local key | ||||
| 	key=$(zaf_cache_key "$1") | ||||
| 	zaf_trc "Cache: removing $1($key) from cache" | ||||
| 	rm -f "$ZAF_CACHE_DIR/$key*" | ||||
| 	rm -f "${ZAF_CACHE_DIR}/$key*" | ||||
| } | ||||
|  | ||||
| # List entries in cache | ||||
| zaf_cache_list(){ | ||||
| 	! [ -w $ZAF_CACHE_DIR ] && return 1 | ||||
| 	local i | ||||
| 	ls ${ZAF_CACHE_DIR}/*info >/dev/null 2>/dev/null || return 1 | ||||
| 	local key | ||||
| 	for i in ${ZAF_CACHE_DIR}/*info; do | ||||
| 		cat $i | ||||
| 	done | ||||
| } | ||||
|  | ||||
| # Get object from cache | ||||
| # $1 key | ||||
| zaf_fromcache(){ | ||||
| 	! [ -r $ZAF_CACHE_DIR ] || [ -n "$ZAF_NOCACHE" ] && return 1 | ||||
| 	! [ -w $ZAF_CACHE_DIR ] && return 3 | ||||
| 	local key | ||||
| 	local value | ||||
| 	local infofile | ||||
| 	local datafile | ||||
|  | ||||
| 	key=$(zaf_cache_key "$1") | ||||
| 	if [ -f $ZAF_CACHE_DIR/$key ]; then | ||||
| 		if [ "$ZAF_CACHE_DIR/$key.info" -nt "$ZAF_CACHE_DIR/$key" ]; then | ||||
| 	datafile="${ZAF_CACHE_DIR}/${key}" | ||||
| 	infofile="${ZAF_CACHE_DIR}/${key}.info" | ||||
|  | ||||
| 	if [ -f $datafile ]; then | ||||
| 		if [ "$infofile" -nt "$datafile" ]; then | ||||
| 			zaf_trc "Cache: serving $1($key) from cache" | ||||
| 			cat $ZAF_CACHE_DIR/$key | ||||
| 			cat "$datafile" | ||||
| 		else | ||||
| 			zaf_trc "Cache: removing old entry $1" | ||||
| 			rm -f "$ZAF_CACHE_DIR/$key*" | ||||
| 			zaf_cache_delentry $key | ||||
| 			return 2 | ||||
| 		fi | ||||
| 	else | ||||
| @@ -82,3 +153,4 @@ zaf_fromcache(){ | ||||
| 	fi | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
							
								
								
									
										276
									
								
								lib/ctrl.lib.sh
									
									
									
									
									
								
							
							
						
						
									
										276
									
								
								lib/ctrl.lib.sh
									
									
									
									
									
								
							| @@ -5,10 +5,29 @@ zaf_ctrl_get_items() { | ||||
| 	grep '^Item ' | cut -d ' ' -f 2 | cut -d ':' -f 1 | tr '\r\n' ' ' | ||||
| } | ||||
|  | ||||
| # Get external item list from control on stdin | ||||
| zaf_ctrl_get_extitems() { | ||||
| 	grep '^ExtItem ' | cut -d ' ' -f 2 | cut -d ':' -f 1 | tr '\r\n' ' ' | ||||
| } | ||||
|  | ||||
| # Get external item body from stdin | ||||
| # $1 itemname | ||||
| zaf_ctrl_get_extitem_block() { | ||||
| 	grep -v '^#' | awk '/^ExtItem '$1'/ { i=0; | ||||
| 	while (i==0) { | ||||
| 		getline; | ||||
| 		if (/^\/ExtItem/) exit; | ||||
| 		print $0; | ||||
| 	}}; | ||||
| 	END { | ||||
| 		exit i==0; | ||||
| 	}' | ||||
| } | ||||
|  | ||||
| # Get item body from stdin | ||||
| # $1 itemname | ||||
| zaf_ctrl_get_item_block() { | ||||
| 	grep -v '^#' | awk '/^Item '$1'/ { i=0; | ||||
| 	grep -vE '^#[a-zA-Z ]' | awk '/^Item '$1'/ { i=0; | ||||
| 	while (i==0) { | ||||
| 		getline; | ||||
| 		if (/^\/Item/) exit; | ||||
| @@ -22,10 +41,10 @@ zaf_ctrl_get_item_block() { | ||||
| # Get global plugin block body from stdin | ||||
| # $1 itemname | ||||
| zaf_ctrl_get_global_block() { | ||||
| 	grep -v '^#' | awk '{ i=0; print $0; | ||||
| 	grep -vE '^#[a-zA-Z ]' | awk '{ i=0; print $0; | ||||
| 	while (i==0) { | ||||
| 		getline; | ||||
| 		if (/^Item /) exit; | ||||
| 		if (/^(Item |ExtItem)/) exit; | ||||
| 		print $0; | ||||
| 	}}' | ||||
| } | ||||
| @@ -33,7 +52,7 @@ zaf_ctrl_get_global_block() { | ||||
| # Get item multiline option | ||||
| # $1 optionname | ||||
| zaf_block_get_moption() { | ||||
| 	awk '/^'$1'::$/ { i=0; print $0; | ||||
| 	awk '/^'$1'::$/ { i=0; if (!/::/) print $0; | ||||
| 	while (i==0) { | ||||
| 		getline; | ||||
| 		if (/^::$/) {i=1; continue;}; | ||||
| @@ -57,7 +76,7 @@ zaf_block_get_option() { | ||||
| zaf_ctrl_get_global_option() { | ||||
| 	local ctrlvar | ||||
| 	local ctrlopt | ||||
|  | ||||
| 	 | ||||
| 	ctrlopt="ZAF_CTRL_$(zaf_stripctrl $2)" | ||||
| 	eval ctrlvar=\$$ctrlopt | ||||
| 	if [ -n "$ctrlvar" ]; then | ||||
| @@ -68,6 +87,7 @@ zaf_ctrl_get_global_option() { | ||||
| 		|| zaf_ctrl_get_global_block <$1 | zaf_block_get_option "$2" | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| # Get item specific option (single or multiline) | ||||
| # $1 - control file | ||||
| # $2 - item name | ||||
| @@ -87,16 +107,38 @@ zaf_ctrl_get_item_option() { | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| # Get external item specific option (single or multiline) | ||||
| # $1 - control file | ||||
| # $2 - item name | ||||
| # $3 - option name | ||||
| zaf_ctrl_get_extitem_option() { | ||||
| 	local ctrlvar | ||||
| 	local ctrlopt | ||||
|  | ||||
| 	ctrlopt="ZAF_CTRLI_$(zaf_stripctrl $2)_$(zaf_stripctrl $3)" | ||||
| 	eval ctrlvar=\$$ctrlopt | ||||
| 	if [ -n "$ctrlvar" ]; then | ||||
| 		zaf_dbg "Overriding item control field $2/$3 from env $ctrlopt($ctrlvar)" | ||||
| 		echo $ctrlopt | ||||
| 	else | ||||
| 		zaf_ctrl_get_extitem_block <$1 "$2" | zaf_block_get_moption "$3" \ | ||||
| 		|| zaf_ctrl_get_extitem_block <$1 "$2" | zaf_block_get_option "$3" | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| # Check dependencies based on control file | ||||
| zaf_ctrl_check_deps() { | ||||
| 	local deps | ||||
| 	deps=$(zaf_ctrl_get_global_block <$1 | zaf_block_get_option "Depends-${ZAF_PKG}" ) | ||||
| 	if ! zaf_os_specific zaf_check_deps $deps; then | ||||
| 		zaf_err "Missing one of dependend system packages: $deps" | ||||
| 	if [ -n "$ZAF_PKG" ]; then | ||||
| 		deps=$(zaf_ctrl_get_global_block <$1 | zaf_block_get_option "Depends-${ZAF_PKG}" ) | ||||
|  | ||||
| 		if ! zaf_os_specific zaf_check_deps $deps; then | ||||
| 			zaf_err "Missing one of dependend system packages: $deps" | ||||
| 		fi | ||||
| 	fi | ||||
| 	deps=$(zaf_ctrl_get_global_block <$1 | zaf_block_get_option "Depends-bin" ) | ||||
| 	for cmd in $deps; do | ||||
| 		if ! which $cmd >/dev/null; then | ||||
| 		if ! zaf_which $cmd >/dev/null; then | ||||
| 			zaf_err "Missing binary dependency $cmd. Please install it first." | ||||
| 		fi | ||||
| 	done | ||||
| @@ -115,16 +157,19 @@ zaf_ctrl_sudo() { | ||||
|  | ||||
| 	pdir="$3" | ||||
| 	plugin=$1 | ||||
| 	zaf_dbg "Installing sudoers entry $ZAF_SUDOERSD/zaf_$plugin" | ||||
| 	sudo=$(zaf_ctrl_get_global_option $2 "Sudo" | zaf_far '{PLUGINDIR}' "${plugindir}") | ||||
| 	[ -z "$sudo" ] && return  # Nothing to install | ||||
| 	if ! which sudo >/dev/null; then | ||||
| 	[ -z "$sudo" ] || [ -z "$ZAF_SUDOERSD" ] && return | ||||
| 	! [ -d "$ZAF_SUDOERSD" ] && { zaf_wrn "$ZAF_SUDOERSD nonexistent! Skipping sudo install!"; return 1; } | ||||
| 	zaf_dbg "Installing sudoers entry $ZAF_SUDOERSD/zaf_$plugin" | ||||
| 	 | ||||
| 	[ -z "$sudo" ] && return	# Nothing to install | ||||
| 	if ! zaf_which sudo >/dev/null; then | ||||
| 		zaf_wrn "Sudo needed bud not installed?" | ||||
| 	fi | ||||
| 	cmd=$(echo $sudo | cut -d ' ' -f 1) | ||||
| 	parms=$(echo $sudo | cut -d ' ' -f 2-) | ||||
| 	if which $cmd >/dev/null ; then | ||||
| 		(echo "zabbix ALL=NOPASSWD:SETENV: $(which $cmd) $(echo $parms | tr '%' '*')";echo) >$ZAF_SUDOERSD/zaf_$plugin || zaf_err "Error during zaf_ctrl_sudo" | ||||
| 	if zaf_which $cmd >/dev/null ; then | ||||
| 		(echo "zabbix ALL=NOPASSWD:SETENV: $(zaf_which $cmd) $(echo $parms | tr '%' '*')";echo) >$ZAF_SUDOERSD/zaf_$plugin || zaf_err "Error during zaf_ctrl_sudo" | ||||
| 		chmod 0440 $ZAF_SUDOERSD/zaf_$plugin | ||||
| 	else | ||||
| 		zaf_err "Cannot find binary '$cmd' to put into sudoers." | ||||
| @@ -142,13 +187,15 @@ zaf_ctrl_cron() { | ||||
|  | ||||
| 	pdir="$3" | ||||
| 	plugin=$1 | ||||
| 	zaf_dbg "Installing cron entry $ZAF_CROND/zaf_$plugin" | ||||
| 	cron=$(zaf_ctrl_get_global_option $2 "Cron") | ||||
| 	[ -z "$cron" ]	|| [ -z "$ZAF_CROND" ] && return | ||||
| 	! [ -d "$ZAF_CROND" ] && { zaf_wrn "$ZAF_CROND nonexistent! Skipping cron install!"; return 1; } | ||||
| 	zaf_dbg "Installing cron entry $ZAF_CROND/zaf_$plugin" | ||||
| 	[ -z "$cron" ] && return # Nothing to install | ||||
| 	zaf_ctrl_get_global_option $2 "Cron" | zaf_far '{PLUGINDIR}' "${plugindir}" >$ZAF_CROND/zaf_$plugin || zaf_err "Error during zaf_ctrl_cron" | ||||
| } | ||||
|  | ||||
| # Install files defined to be installed in control to plugun directory | ||||
| # Install files defined to be installed in control to plugin directory | ||||
| # $1 pluginurl | ||||
| # $2 control | ||||
| # $3 plugindir | ||||
| @@ -162,74 +209,181 @@ zaf_ctrl_install() { | ||||
|  | ||||
| 	pdir="$3" | ||||
| 	(set -e | ||||
| 	binaries=$(zaf_ctrl_get_global_option $2 "Install-bin") | ||||
| 	binaries=$(zaf_ctrl_get_global_option $2 "Install-bin")" "$(zaf_ctrl_get_global_option $2 "Install-cmd") | ||||
| 	for b in $binaries; do | ||||
| 		zaf_fetch_url "$1/$b" >"${ZAF_TMP_DIR}/$b" | ||||
|                 zaf_install_bin "${ZAF_TMP_DIR}/$b" "$pdir" | ||||
| 		zaf_install_bin "${ZAF_TMP_DIR}/$b" "$pdir" | ||||
| 	done | ||||
| 	files=$(zaf_ctrl_get_global_option $2 "Install-files") | ||||
| 	for f in $files; do | ||||
| 		zaf_fetch_url "$1/$b" >"${ZAF_TMP_DIR}/$b" | ||||
|                 zaf_install "${ZAF_TMP_DIR}/$b" "$pdir" | ||||
| 		zaf_fetch_url "$1/$f" >"${ZAF_TMP_DIR}/$f" | ||||
| 		zaf_install "${ZAF_TMP_DIR}/$f" "$pdir" | ||||
| 	done | ||||
| 	script=$(zaf_ctrl_get_global_option $2 "Install-script") | ||||
| 	[ -n "$script" ] && eval "$script" | ||||
| 	true | ||||
| 	) || zaf_err "Error during zaf_ctrl_install" | ||||
| } | ||||
|  | ||||
| # Generates zabbix cfg from control file | ||||
| # Generates zabbix items cfg from control file | ||||
| # $1 control | ||||
| # $2 pluginname | ||||
| zaf_ctrl_generate_cfg() { | ||||
| # $3 if set, no script will be created | ||||
| # $4 if set, cmd is set always to $4 | ||||
| zaf_ctrl_generate_items_cfg() { | ||||
| 	local items | ||||
| 	local cmd | ||||
| 	local iscript | ||||
| 	local ikey | ||||
| 	local lock | ||||
| 	local cache | ||||
| 	local tmpfile | ||||
| 	local pname | ||||
| 	local pdefault | ||||
| 	local pregex | ||||
| 	local prest | ||||
| 	local zafparms | ||||
|  | ||||
| 	items=$(zaf_ctrl_get_items <"$1") | ||||
| 	tmpfile=$(zaf_tmpfile genparms) | ||||
| 	(set -e | ||||
| 	for i in $items; do | ||||
|             iscript=$(zaf_stripctrl $i) | ||||
| 	    params=$(zaf_ctrl_get_item_option $1 $i "Parameters") | ||||
| 	    if [ -n "$params" ]; then | ||||
| 		ikey="$2.$i[*]" | ||||
| 		args="" | ||||
| 		apos=1; | ||||
| 		for p in $params; do | ||||
| 			args="$args \$$apos" | ||||
| 			apos=$(expr $apos + 1) | ||||
| 		done | ||||
| 	    else | ||||
| 		ikey="$2.$i" | ||||
| 	    fi | ||||
| 	    lock=$(zaf_ctrl_get_item_option $1 $i "Lock") | ||||
| 	    if [ -n "$lock" ]; then | ||||
| 		lock="${ZAF_LIB_DIR}/zaflock $lock " | ||||
| 	    fi | ||||
| 	    cache=$(zaf_ctrl_get_item_option $1 $i "Cache") | ||||
| 	    if [ -n "$cache" ]; then | ||||
| 		cache="_cache '$cache' " | ||||
| 	    fi | ||||
|             cmd=$(zaf_ctrl_get_item_option $1 $i "Cmd") | ||||
|             if [ -n "$cmd" ]; then | ||||
|                 $(which echo) "UserParameter=$ikey,${ZAF_LIB_DIR}/preload.sh $cache $lock$cmd"; | ||||
|                 continue | ||||
|             fi | ||||
|             cmd=$(zaf_ctrl_get_item_option $1 $i "Script") | ||||
|             if [ -n "$cmd" ]; then | ||||
|                 zaf_ctrl_get_item_option $1 $i "Script" | \ | ||||
| 		  zaf_far '{INCLUDES}' '. /etc/zaf.conf; . ${ZAF_LIB_DIR}/zaf.lib.sh; . ${ZAF_LIB_DIR}/ctrl.lib.sh; . ${ZAF_LIB_DIR}/zbxapi.lib.sh; . ${ZAF_LIB_DIR}/cache.lib.sh; ' \ | ||||
| 		  >${ZAF_TMP_DIR}/${iscript}.sh; | ||||
|                 zaf_install_bin ${ZAF_TMP_DIR}/${iscript}.sh ${ZAF_PLUGINS_DIR}/$2/ | ||||
|                 $(which echo) "UserParameter=$ikey,$cache $lock${ZAF_PLUGINS_DIR}/$2/${iscript}.sh $args"; | ||||
|                 continue; | ||||
|             fi | ||||
| 	    zaf_err "Item $i declared in control file but has no Cmd, Function or Script!" | ||||
| 		iscript=$(zaf_stripctrl $i) | ||||
| 		zaf_ctrl_get_item_option $1 $i "Parameters" >$tmpfile | ||||
| 		echo >>$tmpfile | ||||
| 		zafparams=""; | ||||
| 		if [ -s "$tmpfile" ]; then | ||||
| 			ikey="$2.$i[*]" | ||||
| 			args="" | ||||
| 			apos=1; | ||||
| 			while read pname pdefault pregex prest; do | ||||
| 				[ -z "$pname" ] && continue | ||||
| 				zaf_trc "Adding param $pname ($pdefault $pregex) to $i" | ||||
| 				zafparams="$zafparams value=\"\$$apos\"; zaf_agentparm $pname $pdefault $pregex; export $pname; " | ||||
| 				args="$args \$$apos" | ||||
| 				apos=$(expr $apos + 1) | ||||
| 			done <$tmpfile | ||||
| 		else | ||||
| 			ikey="$2.$i" | ||||
| 			zafparams="" | ||||
| 			args="" | ||||
| 		fi | ||||
| 		env="export ITEM_KEY='$ikey'; export PLUGIN='$2'; export PATH=${ZAF_PLUGINS_DIR}/$2:$ZAF_LIB_DIR:\$PATH; cd ${ZAF_PLUGINS_DIR}/$2; . $ZAF_LIB_DIR/preload.sh; " | ||||
| 		lock=$(zaf_ctrl_get_item_option $1 $i "Lock") | ||||
| 		if [ -n "$lock" ]; then | ||||
| 			lock="${ZAF_LIB_DIR}/zaflock $lock " | ||||
| 		fi | ||||
| 		cache=$(zaf_ctrl_get_item_option $1 $i "Cache") | ||||
| 		if [ -n "$cache" ]; then | ||||
| 			cache="${ZAF_LIB_DIR}/zafcache '$cache' " | ||||
| 		fi | ||||
| 		ret=$(zaf_ctrl_get_item_option $1 $i "Return") | ||||
| 		retnull=$(zaf_ctrl_get_item_option $1 $i "Return-null") | ||||
| 		reterr=$(zaf_ctrl_get_item_option $1 $i "Return-error") | ||||
| 		if [ -n "$ret" ] || [ -n "$reterr" ] || [ -n "$retnull" ]; then | ||||
| 			retscr=" 1>\${tmpf}o 2>\${tmpf}e; ${ZAF_LIB_DIR}/zafret \${tmpf}o \${tmpf}e \$? '$ret' '$retnull' '$retempty' "; | ||||
| 		else | ||||
| 			retscr=""; | ||||
| 		fi | ||||
| 		if [ -z "$4" ]; then | ||||
| 			cmd=$(zaf_ctrl_get_item_option $1 $i "Cmd") | ||||
| 		else | ||||
| 			cmd="$4" | ||||
| 		fi | ||||
| 		if [ -n "$cmd" ]; then | ||||
| 			printf "%s" "UserParameter=$ikey,${env}${zafparams}${preload}${cache}${lock}${cmd}${retscr}"; echo | ||||
| 			continue | ||||
| 		fi | ||||
| 		cmd=$(zaf_ctrl_get_item_option $1 $i "Script") | ||||
| 		if [ -n "$cmd" ]; then | ||||
| 			( echo "#!/bin/sh" | ||||
| 			echo ". $ZAF_LIB_DIR/preload.sh; " | ||||
| 			zaf_ctrl_get_item_option $1 $i "Script" | ||||
| 			) >${ZAF_TMP_DIR}/${iscript}.sh; | ||||
| 			[ -z "$3" ] && zaf_install_bin ${ZAF_TMP_DIR}/${iscript}.sh ${ZAF_PLUGINS_DIR}/$2/ | ||||
| 			if [ -z "$4" ]; then | ||||
| 				script="${ZAF_PLUGINS_DIR}/$2/${iscript}.sh" | ||||
| 			else | ||||
| 				script="$4" | ||||
| 			fi | ||||
| 			printf "%s" "UserParameter=$ikey,${env}${preload}${zafparams}${cache}${lock}$script ${args}"; echo | ||||
| 			rm -f ${ZAF_TMP_DIR}/${iscript}.sh | ||||
| 			continue; | ||||
| 		fi | ||||
| 		zaf_err "Item $i declared in control file but has no Cmd, Function or Script!" | ||||
| 	done | ||||
| 	) || zaf_err "Error during zaf_ctrl_generate_cfg" | ||||
| 	) || zaf_err "Error during zaf_ctrl_generate_items_cfg" | ||||
| 	[ "$ZAF_DEBUG" -lt 4 ] && rm -f $tmpfile | ||||
| } | ||||
|  | ||||
| # Generates zabbix items cfg from control file | ||||
| # $1 control | ||||
| # $2 pluginname | ||||
| zaf_ctrl_generate_extitems_cfg() { | ||||
| 	local items | ||||
| 	local cmd | ||||
| 	local iscript | ||||
| 	local ikey | ||||
| 	local lock | ||||
| 	local cache | ||||
| 	local tmpfile | ||||
| 	local pname | ||||
| 	local pdefault | ||||
| 	local pregex | ||||
| 	local prest | ||||
| 	local zafparms | ||||
|  | ||||
| 	items=$(zaf_ctrl_get_extitems <"$1") | ||||
| 	tmpfile=$(zaf_tmpfile genparms) | ||||
| 	(set -e | ||||
| 	for i in $items; do | ||||
| 		iscript=$(zaf_stripctrl $i) | ||||
| 		(zaf_ctrl_get_extitem_option $1 $i "Parameters"; echo) >$tmpfile | ||||
| 		ikey="$2.$i" | ||||
| 		if [ -s "$tmpfile" ]; then | ||||
| 			args="" | ||||
| 			apos=1; | ||||
| 			while read pname pdefault pregex prest; do | ||||
| 				zafparams="$zafparams value=\"\$$apos\"; zaf_agentparm $pname $pdefault $pregex; export $pname; " | ||||
| 				args="$args \$$apos" | ||||
| 				apos=$(expr $apos + 1) | ||||
| 			done <$tmpfile | ||||
| 		else | ||||
| 			zafparams="" | ||||
| 			args="" | ||||
| 		fi | ||||
| 		env="export ITEM_KEY='$ikey'; export PLUGIN='$2'; export PATH=${ZAF_PLUGINS_DIR}/$2:$ZAF_LIB_DIR:\$PATH; cd ${ZAF_PLUGINS_DIR}/$2; . $ZAF_LIB_DIR/preload.sh; " | ||||
| 		lock=$(zaf_ctrl_get_extitem_option $1 $i "Lock") | ||||
| 		if [ -n "$lock" ]; then | ||||
| 			lock="${ZAF_LIB_DIR}/zaflock $lock " | ||||
| 		fi | ||||
| 		cache=$(zaf_ctrl_get_extitem_option $1 $i "Cache") | ||||
| 		if [ -n "$cache" ]; then | ||||
| 			cache="${ZAF_LIB_DIR}/zafcache '$cache' " | ||||
| 		fi | ||||
| 		ret=$(zaf_ctrl_get_extitem_option $1 $i "Return") | ||||
| 		retnull=$(zaf_ctrl_get_extitem_option $1 $i "Return-null") | ||||
| 		reterr=$(zaf_ctrl_get_extitem_option $1 $i "Return-error") | ||||
| 		if [ -n "$ret" ] || [ -n "$reterr" ] || [ -n "$retnull" ]; then | ||||
| 			retscr=" 1>\${tmpf}o 2>\${tmpf}e; ${ZAF_LIB_DIR}/zafret \${tmpf}o \${tmpf}e \$? '$ret' '$retnull' '$retempty' \$*"; | ||||
| 		else | ||||
| 			retscr=""; | ||||
| 		fi | ||||
| 		cmd=$(zaf_ctrl_get_extitem_option "$1" "$i" "Cmd") | ||||
| 		if [ -n "$cmd" ]; then | ||||
| 			echo "#!/bin/sh" >"${ZAF_SERVER_EXTSCRIPTS}/$ikey" | ||||
| 			chmod +x "${ZAF_SERVER_EXTSCRIPTS}/$ikey" | ||||
| 			(printf "%s" "${env}${zafparams}${preload}${cache}${lock}${cmd}${retscr}"; echo) >>"${ZAF_SERVER_EXTSCRIPTS}/$ikey" | ||||
| 			continue | ||||
| 		fi | ||||
| 		cmd=$(zaf_ctrl_get_extitem_option "$1" "$i" "Script") | ||||
| 		if [ -n "$cmd" ]; then | ||||
| 			echo "#!/bin/sh" >"${ZAF_SERVER_EXTSCRIPTS}/$ikey" | ||||
| 			chmod +x "${ZAF_SERVER_EXTSCRIPTS}/$ikey" | ||||
| 			(printf "%s" "${env}${zafparams}${preload}${cache}${lock}${cmd}"; echo) >>"${ZAF_SERVER_EXTSCRIPTS}/$ikey" | ||||
| 			continue; | ||||
| 		fi | ||||
| 		zaf_err "External item $i declared in control file but has no Cmd, Function or Script!" | ||||
| 	done | ||||
| 	) || zaf_err "Error during zaf_ctrl_generate_extitems_cfg" | ||||
| 	rm -f $tmpfile | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										135
									
								
								lib/os.lib.sh
									
									
									
									
									
								
							
							
						
						
									
										135
									
								
								lib/os.lib.sh
									
									
									
									
									
								
							| @@ -1,43 +1,71 @@ | ||||
| # Os related functions | ||||
|  | ||||
| zaf_configure_os_openwrt() { | ||||
|     ZAF_AGENT_RESTART="/etc/init.d/zabbix_agentd restart" | ||||
|     ZAF_AGENT_CONFIGD="/var/run/zabbix_agentd.conf.d/" | ||||
|     ZAF_AGENT_CONFIG="/etc/zabbix_agentd.conf" | ||||
|     ZAF_AGENT_PKG="zabbix-agentd" | ||||
|     ZAF_CURL_INSECURE=1 | ||||
| zaf_preconfigure_os_openwrt() { | ||||
| 		ZAF_AGENT_RESTART="/etc/init.d/zabbix_agentd restart" | ||||
| 		ZAF_AGENT_CONFIGD="/var/run/zabbix_agentd.conf.d/" | ||||
| 		ZAF_AGENT_CONFIG="/etc/zabbix_agentd.conf" | ||||
| 		ZAF_AGENT_PKG="zabbix-agentd" | ||||
| 		ZAF_CURL_INSECURE=1 | ||||
| } | ||||
| zaf_preconfigure_os_beesip() { | ||||
| 	 zaf_preconfigure_os_openwrt | ||||
| }  | ||||
|  | ||||
| zaf_preconfigure_os_freebsd() { | ||||
| 		ZAF_AGENT_PKG="zabbix3-agent" | ||||
| 		ZAF_AGENT_CONFIG="/usr/local/etc/zabbix3/zabbix_agentd.conf" | ||||
| 		ZAF_AGENT_CONFIGD="/usr/local/etc/zabbix3/zabbix_agentd.conf.d/" | ||||
| 		ZAF_AGENT_BIN="/usr/local/sbin/zabbix_agentd" | ||||
| 		ZAF_AGENT_RESTART="service zabbix_agentd restart" | ||||
| 		ZAF_SUDOERSD="/usr/local/etc/sudoers.d" | ||||
| } | ||||
|  | ||||
| zaf_configure_os_freebsd() { | ||||
|     ZAF_AGENT_PKG="zabbix3-agent" | ||||
|     ZAF_AGENT_CONFIG="/usr/local/etc/zabbix3/zabbix_agentd.conf" | ||||
|     ZAF_AGENT_CONFIGD="/usr/local/etc/zabbix3/zabbix_agentd.conf.d/" | ||||
|     ZAF_AGENT_BIN="/usr/local/sbin/zabbix_agentd" | ||||
|     ZAF_AGENT_RESTART="service zabbix_agentd restart" | ||||
| zaf_postconfigure_os_openwrt() { | ||||
| 	if ! grep -q "zaf agent-config" /etc/init.d/zabbix_agentd; then | ||||
| 		sed -i 's/uci2config $NAME/uci2config $NAME; zaf agent-config/' /etc/init.d/zabbix_agentd | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| zaf_postconfigure_os_beesip() { | ||||
| 	zaf_postconfigure_os_openwrt | ||||
| } | ||||
|  | ||||
| zaf_which() { | ||||
| 	if which >/dev/null 2>/dev/null; then | ||||
| 		which "$1" | ||||
| 	else | ||||
| 		for i in /bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin; do | ||||
| 			[ -x $i/$1 ] && { echo $i/$1; return; } | ||||
| 		done | ||||
| 		return 1 | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| zaf_detect_system() { | ||||
| 	if which dpkg >/dev/null; then | ||||
| 	ZAF_FILES_UID=zabbix | ||||
| 	ZAF_FILES_GID=zabbix | ||||
| 	ZAF_FILES_UMASK=0770 | ||||
| 	if zaf_which dpkg >/dev/null; then | ||||
| 		ZAF_PKG=dpkg | ||||
| 		ZAF_OS=$(lsb_release -is|zaf_tolower) | ||||
| 		ZAF_OS_CODENAME=$(lsb_release -cs|zaf_tolower) | ||||
| 		ZAF_CURL_INSECURE=0 | ||||
| 		ZAF_AGENT_PKG="zabbix-agent" | ||||
| 		return | ||||
| 	else if which rpm >/dev/null; then | ||||
| 	else if zaf_which rpm >/dev/null; then | ||||
| 		ZAF_PKG="rpm" | ||||
| 		ZAF_OS=$(lsb_release -is|zaf_tolower) | ||||
| 		ZAF_OS_CODENAME=$(lsb_release -cs|zaf_tolower) | ||||
| 		ZAF_CURL_INSECURE=0 | ||||
| 		ZAF_AGENT_PKG="zabbix-agent" | ||||
| 		return | ||||
| 	else if which opkg >/dev/null; then | ||||
| 	else if zaf_which opkg >/dev/null; then | ||||
| 		ZAF_PKG="opkg" | ||||
| 		. /etc/openwrt_release | ||||
| 		ZAF_OS="$(echo $DISTRIB_ID|zaf_tolower)" | ||||
| 		ZAF_OS_CODENAME="$(echo $DISTRIB_CODENAME|zaf_tolower)" | ||||
| 		return	 | ||||
| 	else if which pkg >/dev/null; then | ||||
| 	else if zaf_which pkg >/dev/null; then | ||||
| 		ZAF_PKG="pkg" | ||||
| 		ZAF_OS="freebsd" | ||||
| 		ZAF_OS_CODENAME="$(freebsd-version|cut -d '-' -f 1)" | ||||
| @@ -47,9 +75,9 @@ zaf_detect_system() { | ||||
| 		ZAF_OS="unknown" | ||||
| 		ZAF_OS_CODENAME="unknown" | ||||
| 		ZAF_AGENT_PKG="" | ||||
|                 return | ||||
| 	   fi | ||||
| 	  fi | ||||
| 								return | ||||
| 		 fi | ||||
| 		fi | ||||
| 	 fi | ||||
| 	fi | ||||
| } | ||||
| @@ -58,79 +86,70 @@ zaf_detect_system() { | ||||
| # $1 - name of the function. | ||||
| # all variants will be tested. (name_os_codename, name_os, name_{dpkg|opkg|rpm}, name ) | ||||
| zaf_os_specific(){ | ||||
|     local func="$1" | ||||
|      | ||||
|     if type "${func}_${ZAF_OS}_${ZAF_OS_CODENAME}" >/dev/null 2>/dev/null; then | ||||
|         eval "${func}_${ZAF_OS}_${ZAF_OS_CODENAME} $2 $3 $4 $5 $6" | ||||
|     else if type "${func}_${ZAF_OS}" >/dev/null 2>/dev/null; then | ||||
|         eval "${func}_${ZAF_OS} $2 $3 $4 $5 $6"  | ||||
|     else if type "${func}_${ZAF_PKG}" >/dev/null 2>/dev/null; then | ||||
|         eval "${func}_${ZAF_PKG} $2 $3 $4 $5 $6" | ||||
|     else | ||||
|         zaf_dbg "No OS/packager specific implementation for $1" | ||||
|       fi | ||||
|      fi | ||||
|     fi | ||||
| 		local func="$1" | ||||
| 		 | ||||
| 		if type "${func}_${ZAF_OS}_${ZAF_OS_CODENAME}" >/dev/null 2>/dev/null; then | ||||
| 				eval "${func}_${ZAF_OS}_${ZAF_OS_CODENAME} $2 $3 $4 $5 $6" | ||||
| 		else if type "${func}_${ZAF_OS}" >/dev/null 2>/dev/null; then | ||||
| 				eval "${func}_${ZAF_OS} $2 $3 $4 $5 $6"  | ||||
| 		else if type "${func}_${ZAF_PKG}" >/dev/null 2>/dev/null; then | ||||
| 				eval "${func}_${ZAF_PKG} $2 $3 $4 $5 $6" | ||||
| 		else | ||||
| 				zaf_dbg "No OS/packager specific implementation for $1" | ||||
| 			fi | ||||
| 		 fi | ||||
| 		fi | ||||
| } | ||||
|  | ||||
| zaf_is_root(){ | ||||
|     [ "$USER" = "root" ] | ||||
| 		[ "$USER" = "root" ] || [ "$EUID" = "0" ] || [ -n "$ZAF_ISROOT" ] | ||||
| } | ||||
|  | ||||
| # Install file, bin or directory and respect install prefix  | ||||
| # $1 - src file | ||||
| # $2 - directory | ||||
| zaf_install(){ | ||||
|     zaf_dbg "Install file $1 to $INSTALL_PREFIX/$2/$(basename $1)" | ||||
|     $ZAF_DO cp "$1" "$INSTALL_PREFIX/$2/$(basename $1)" | ||||
| 		zaf_dbg "Install file $1 to $INSTALL_PREFIX/$2/$(basename $1)" | ||||
| 		$ZAF_DO cp "$1" "$INSTALL_PREFIX/$2/$(basename $1)" || zaf_err "Cannot create file $INSTALL_PREFIX/$2/$(basename $1)!" | ||||
| } | ||||
| # $1 - src file | ||||
| # $2 - directory | ||||
| zaf_install_bin(){ | ||||
|     zaf_dbg "Install binary $1 to $INSTALL_PREFIX/$2/$(basename $1)" | ||||
|     $ZAF_DO cp "$1" "$INSTALL_PREFIX/$2/$(basename $1)" | ||||
|     $ZAF_DO chmod +x "$INSTALL_PREFIX/$2/$(basename $1)" | ||||
| 		zaf_dbg "Install binary $1 to $INSTALL_PREFIX/$2/$(basename $1)" | ||||
| 		$ZAF_DO cp "$1" "$INSTALL_PREFIX/$2/$(basename $1)" || zaf_err "Cannot create binary $INSTALL_PREFIX/$2/$(basename $1)!" | ||||
| 		$ZAF_DO chmod +x "$INSTALL_PREFIX/$2/$(basename $1)" | ||||
| } | ||||
| # $1 - directory | ||||
| zaf_install_dir(){ | ||||
|     zaf_dbg "Install directory $1 to $INSTALL_PREFIX/$1" | ||||
|     $ZAF_DO mkdir -p "$INSTALL_PREFIX/$1" | ||||
| 		zaf_dbg "Install directory $1 to $INSTALL_PREFIX/$1" | ||||
| 		$ZAF_DO mkdir -p "$INSTALL_PREFIX/$1" || zaf_err "Cannot create directory $INSTALL_PREFIX/$1!" | ||||
| } | ||||
| # $1 - file | ||||
| zaf_touch(){ | ||||
|     zaf_dbg "Touch $INSTALL_PREFIX/$1" | ||||
|     $ZAF_DO touch "$INSTALL_PREFIX/$1" | ||||
| 		zaf_dbg "Touch $INSTALL_PREFIX/$1" | ||||
| 		$ZAF_DO touch "$INSTALL_PREFIX/$1" | ||||
| } | ||||
| # $1 - directory | ||||
| zaf_uninstall(){ | ||||
|     if [ -n "$INSTALL_PREFIX" ]; then | ||||
|     	zaf_dbg "Removing $INSTALL_PREFIX/$1" | ||||
| 		if [ -n "$INSTALL_PREFIX" ]; then | ||||
| 			zaf_dbg "Removing $INSTALL_PREFIX/$1" | ||||
| 	$ZAF_DO rm -rf "$INSTALL_PREFIX/$1" | ||||
|     else | ||||
| 		else | ||||
| 	zaf_dbg "Removing $1" | ||||
| 	$ZAF_DO rm -rf "$1" | ||||
|     fi | ||||
| } | ||||
|  | ||||
| # Automaticaly install agent on debian | ||||
| # For another os, create similar function (install_zabbix_centos) | ||||
| zaf_install_agent_debian() { | ||||
|     zaf_fetch_url "http://repo.zabbix.com/zabbix/3.0/debian/pool/main/z/zabbix-release/zabbix-release_3.0-1+${ZAF_OS_CODENAME}_all.deb" >"/tmp/zaf-installer/zabbix-release_3.0-1+${ZAF_OS_CODENAME}_all.deb" \ | ||||
| 	&& dpkg -i "/tmp/zaf-installer/zabbix-release_3.0-1+${ZAF_OS_CODENAME}_all.deb" \ | ||||
| 	&& apt-get update \ | ||||
| 	&& apt-get install -y -q $ZAF_AGENT_PKG | ||||
| 		fi | ||||
| } | ||||
|  | ||||
| zaf_install_agent_opkg() { | ||||
|     opkg update && \ | ||||
|     opkg install $ZAF_AGENT_PKG | ||||
| 		opkg update && \ | ||||
| 		opkg install $ZAF_AGENT_PKG | ||||
| } | ||||
|  | ||||
| # Check if dpkg dependency is met | ||||
| # $* - packages | ||||
| zaf_check_deps_dpkg() { | ||||
| 	for i in $*; do | ||||
| 		dpkg-query -f '${Status},${Package}\n' -W $* 2>/dev/null | grep -q "^install ok"  | ||||
| 		dpkg-query -f '${db:Status-Status},${Package}\n' -W $* 2>/dev/null | grep -qE "^(installed|^,)"  | ||||
| 	done | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										441
									
								
								lib/plugin.lib.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										441
									
								
								lib/plugin.lib.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,441 @@ | ||||
| # Plugin related functions | ||||
|  | ||||
| # Update repo | ||||
| zaf_update_repo() { | ||||
| 	[ "$ZAF_GIT" != 1 ] && { zaf_err "Git is disabled or is not installed. Exiting."; } | ||||
| 	if [ -z "${ZAF_REPO_GITURL}" ] || [ -z "${ZAF_REPO_DIR}" ]; then | ||||
| 		zaf_err "This system is not configured for git repository." | ||||
| 	else | ||||
| 		[ ! -d "${ZAF_REPO_DIR}" ] && git clone "${ZAF_REPO_GITURL}" "${ZAF_REPO_DIR}" | ||||
| 		(cd ${ZAF_REPO_DIR} && git pull) | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| # Construct url from plugin name | ||||
| # It can be http[s]://url | ||||
| # /path (from file) | ||||
| # name (to try from repo) | ||||
| zaf_get_plugin_url() { | ||||
| 	local url | ||||
|  | ||||
| 	if [ "$(zaf_url_info $1)" = "path" ]; then | ||||
| 		url="$1"		# plugin with path - from directory | ||||
| 	else | ||||
| 		if [ "$(zaf_url_info $1)" = "url" ]; then | ||||
| 			url="$1"	# plugin with http[s] url  | ||||
| 		else | ||||
| 			if [ -n "${ZAF_REPO_URL}" ]; then | ||||
| 					url="${ZAF_REPO_URL}/$1"  | ||||
| 			else | ||||
| 					zaf_err "Cannot find plugin $1" | ||||
| 			fi | ||||
| 		fi | ||||
| 	fi | ||||
| 	echo $url | ||||
| } | ||||
|  | ||||
| # $1 - control | ||||
| zaf_plugin_info() { | ||||
| 	local control="$1" | ||||
| 	local items | ||||
|  | ||||
| 	! [ -f "$control" ] && zaf_err "Control file $control not found." | ||||
| 	plugin=$(zaf_ctrl_get_global_option "${control}" Plugin) | ||||
| 	pdescription=$(zaf_ctrl_get_global_option "${control}" Description) | ||||
| 	pmaintainer=$(zaf_ctrl_get_global_option "${control}" Maintainer) | ||||
| 	pversion=$(zaf_ctrl_get_global_option "${control}" Version) | ||||
| 	purl=$(zaf_ctrl_get_global_option "${control}" Url) | ||||
| 	phome=$(zaf_ctrl_get_global_option "${control}" Home) | ||||
| 	pitems=$(zaf_ctrl_get_items <"${control}") | ||||
| 	peitems=$(zaf_ctrl_get_extitems <"${control}") | ||||
| 	params=$(zaf_ctrl_get_global_option "${control}" Parameters) | ||||
| 	echo | ||||
| 	echo -n "Plugin '$plugin' "; [ -n "$pversion" ] && echo -n "version ${pversion}"; echo ":" | ||||
| 	echo "$pdescription"; echo | ||||
| 	[ -n "$pmaintainer" ] && echo "Maintainer: $pmaintainer" | ||||
| 	[ -n "$purl" ] && echo "Url: $purl" | ||||
| 	[ -n "$phome" ] && echo "Home: $phome" | ||||
| 	echo  | ||||
| 	if zaf_is_plugin "$(basename $plugin)"; then | ||||
| 		items=$(zaf_list_plugin_items $plugin) | ||||
| 		if [ -n "$params" ]; then | ||||
| 			printf "%b" "Plugin parameters: (name,default,actual value)\n" | ||||
| 			zaf_ctrl_get_global_option "${control}" Parameters | while read param default ; do | ||||
| 				printf "%b" "$param\t$default\t$(zaf_get_plugin_parameter $(dirname $1) $param)\n" | ||||
| 			done | ||||
| 			echo; | ||||
| 		fi  | ||||
| 		[ -n "$items" ] && { echo -n "Defined items: "; echo $items; } | ||||
| 		items=$(zaf_list_plugin_items $plugin test) | ||||
| 		[ -n "$items" ] && { echo -n "Test items: "; echo $items; } | ||||
| 		items=$(zaf_list_plugin_items $plugin precache) | ||||
| 		[ -n "$items" ] && { echo -n "Precache items: "; echo $items; } | ||||
| 		[ -n "$peitems" ] && { echo -n "External check items: "; echo $peitems; } | ||||
| 		 | ||||
| 	else | ||||
| 		echo "Items: $pitems" | ||||
| 	fi | ||||
| 	echo | ||||
| } | ||||
|  | ||||
| # Get global plugin parameters | ||||
| # $1 plugin | ||||
| zaf_get_plugin_parameters() { | ||||
| 	zaf_ctrl_get_global_option "${ZAF_PLUGINS_DIR}/${p}/control.zaf" "Parameters" | while read param rest; do echo $param; done | ||||
| } | ||||
|  | ||||
| # Set plugin global parameter | ||||
| # $1 plugindir | ||||
| # $2 parameter | ||||
| # $3 value | ||||
| zaf_set_plugin_parameter() { | ||||
| 	printf "%s" "$3" >"${INSTALL_PREFIX}/${1}/${2}.value" | ||||
| } | ||||
|  | ||||
| # Get plugin global parameter | ||||
| # $1 plugindir | ||||
| # $2 parameter | ||||
| zaf_get_plugin_parameter() { | ||||
| 	[ -f "${1}/${2}.value" ] && cat "${1}/${2}.value" | ||||
| } | ||||
|  | ||||
| # Prepare plugin into dir  | ||||
| # $1 is url, directory or plugin name (will be searched in default plugin dir).  | ||||
| # $2 is directory to prepare.  | ||||
| zaf_prepare_plugin() { | ||||
| 	local url | ||||
| 	local plugindir | ||||
| 	local control | ||||
| 	local pluginname | ||||
|  | ||||
| 	url=$(zaf_get_plugin_url "$1")/control.zaf || exit $? | ||||
| 	plugindir="$2" | ||||
| 	control=${plugindir}/control.zaf | ||||
| 	if [ "$(zaf_url_info $1)" = "path" ] &&  [ "$url" = "$control" ]; then | ||||
| 		zaf_err "prepare_plugin: Cannot install from itself ($url,$control)!" | ||||
| 	fi | ||||
| 	zaf_install_dir "$plugindir" | ||||
| 	zaf_dbg "Fetching control file from $url ..." | ||||
| 	if zaf_fetch_url "$url" >"${INSTALL_PREFIX}/${control}" && [ -s "${INSTALL_PREFIX}/${control}" ]; then | ||||
| 		[ -z "${INSTALL_PREFIX}" ] && zaf_ctrl_check_deps "${control}" | ||||
| 		pluginname=$(zaf_ctrl_get_global_block <"${INSTALL_PREFIX}/${control}" | zaf_block_get_option Plugin) | ||||
| 		[ "$(basename $plugindir)" != "$pluginname" ] && zaf_err "prepare_plugin: Plugin name mismach ($plugindir vs ${INSTALL_PREFIX}/${control})!" | ||||
| 		true | ||||
| 	else | ||||
| 		rm -rf "$plugindir" | ||||
| 		zaf_err "prepare_plugin: Cannot fetch or write control file ${INSTALL_PREFIX}/$control from url $url!" | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| zaf_install_plugin() { | ||||
| 	local url | ||||
| 	local plugin | ||||
| 	local plugindir | ||||
| 	local tmpplugindir | ||||
| 	local control | ||||
| 	local version | ||||
| 	local eparam | ||||
| 	local param | ||||
| 	local default | ||||
|  | ||||
| 	plugin=$(basename "$1") | ||||
| 	plugindir="${ZAF_PLUGINS_DIR}/${plugin}" | ||||
| 	if [ -n "$plugin" ] && zaf_prepare_plugin "$1" $plugindir; then | ||||
| 		url=$(zaf_get_plugin_url "$1") | ||||
| 		zaf_wrn "Installing plugin $plugin" | ||||
| 		zaf_dbg "Source url: $url, Destination dir: $plugindir" | ||||
| 		control=${plugindir}/control.zaf | ||||
| 		[ "$ZAF_DEBUG" -gt 1 ] && zaf_plugin_info "${control}" | ||||
| 		if [ -z "${INSTALL_PREFIX}" ]; then | ||||
| 			zaf_ctrl_check_deps "${control}" | ||||
| 			zaf_ctrl_sudo "$plugin" "${control}" "${plugindir}" | ||||
| 			zaf_ctrl_cron "$plugin" "${control}" "${plugindir}" | ||||
| 			zaf_ctrl_generate_items_cfg "${control}" "${plugin}" \ | ||||
| 				| zaf_far '{PLUGINDIR}' "${plugindir}" >${ZAF_AGENT_CONFIGD}/zaf_${plugin}.conf | ||||
| 			zaf_dbg "Generated ${ZAF_AGENT_CONFIGD}/zaf_${plugin}.conf" | ||||
| 			zaf_ctrl_generate_extitems_cfg "${control}" "${plugin}" | ||||
| 		else | ||||
| 			zaf_touch "${plugindir}/postinst.need" | ||||
| 		fi | ||||
| 		zaf_ctrl_install "$url" "${control}" "${plugindir}" | ||||
| 		rm -f "${plugindir}/params" | ||||
| 		zaf_touch "${plugindir}/params" | ||||
| 		(zaf_ctrl_get_global_option "${control}" "Parameters"; echo) | \ | ||||
| 			while read param default; do | ||||
| 				[ -z "$param" ] && continue | ||||
| 				echo $param >>"${plugindir}/params" | ||||
| 				eval eparam=\$ZAF_${plugin}_${param} | ||||
| 				if [ -z "$eparam" ] && ! zaf_get_plugin_parameter "$plugindir" "$param" >/dev/null; then | ||||
| 					zaf_wrn "Do not forget to set parameter $param. Use zaf plugin-set $plugin $param value. Default is $default." | ||||
| 					zaf_set_plugin_parameter "$plugindir" "$param" "$default" | ||||
| 				else | ||||
| 					if [ -n "$eparam" ]; then | ||||
| 						zaf_dbg "Setting $param to $eparam from env." | ||||
| 						zaf_set_plugin_parameter "$plugindir" "$param" "$eparam" | ||||
| 					fi | ||||
| 				fi | ||||
| 			done | ||||
|  | ||||
| 	else | ||||
| 		zaf_err "Cannot install plugin '$plugin' to $plugindir!" | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| zaf_postinstall_plugin() { | ||||
| 	local url | ||||
| 	local plugin | ||||
| 	local plugindir | ||||
| 	local tmpplugindir | ||||
| 	local control | ||||
| 	local version | ||||
|  | ||||
| 	plugin=$(basename "$1") | ||||
| 	plugindir="${ZAF_PLUGINS_DIR}/${plugin}" | ||||
| 	control=${plugindir}/control.zaf | ||||
| 	[ "$ZAF_DEBUG" -gt 1 ] && zaf_plugin_info "${control}" | ||||
| 	zaf_ctrl_check_deps "${control}" | ||||
| 	zaf_ctrl_sudo "$plugin" "${control}" "${plugindir}" | ||||
| 	zaf_ctrl_cron "$plugin" "${control}" "${plugindir}" | ||||
| 	zaf_ctrl_generate_items_cfg "${control}" "${plugin}" \ | ||||
| 		| zaf_far '{PLUGINDIR}' "${plugindir}" >${ZAF_AGENT_CONFIGD}/zaf_${plugin}.conf | ||||
| 	zaf_dbg "Generated ${ZAF_AGENT_CONFIGD}/zaf_${plugin}.conf" | ||||
| 	zaf_ctrl_generate_extitems_cfg "${control}" "${plugin}" | ||||
| } | ||||
|  | ||||
|  | ||||
| # List installed plugins | ||||
| # $1 - plugin | ||||
| zaf_list_plugins() { | ||||
| 	local cfile | ||||
| 	local plugin | ||||
| 	ls -1 ${ZAF_PLUGINS_DIR} | while read p; do | ||||
| 		zaf_is_plugin "$(basename $p)" && echo $p | ||||
| 	done | ||||
| } | ||||
|  | ||||
| zaf_is_plugin() { | ||||
| 	[ -d "$ZAF_PLUGINS_DIR/$1" ] && [ -f "$ZAF_PLUGINS_DIR/$1/control.zaf" ] && return | ||||
| 	false | ||||
| } | ||||
|  | ||||
| zaf_is_item() { | ||||
| 	local plugin | ||||
| 	local item | ||||
|  | ||||
| 	plugin=$(echo $1|cut -d '.' -f 1) | ||||
| 	item=$(echo $1|cut -d '.' -f 2- | cut -d '[' -f 1) | ||||
| 	[ -z "$plugin" ] || [ -z "$item" ] && return 1 | ||||
| 	zaf_is_plugin "$plugin" && zaf_list_plugin_items "$plugin" | grep -qE "\.(${item}\$|${item}\[)" | ||||
| } | ||||
|  | ||||
|  | ||||
| zaf_discovery_plugins() { | ||||
| 	zaf_list_plugins | zaf_discovery '{#PLUGIN}' | ||||
| } | ||||
|  | ||||
| # $1 plugin | ||||
| # $2 ctrl_option | ||||
| zaf_plugin_option() { | ||||
| 	local plugindir | ||||
| 	local cfile | ||||
|  | ||||
| 	if [ -z "$1" ]; then | ||||
| 		zaf_err "Missing plugin name."; | ||||
| 	fi | ||||
| 	if zaf_is_plugin "$1"; then | ||||
| 		plugindir="${ZAF_PLUGINS_DIR}/$1" | ||||
| 		cfile="$plugindir/control.zaf" | ||||
| 		zaf_ctrl_get_global_option $cfile $2 | ||||
| 	else | ||||
| 		zaf_err "Plugin $1 not installed." | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| zaf_plugin_version() { | ||||
| 	zaf_plugin_option "$1" Version | ||||
| } | ||||
| zaf_plugin_maintainer() { | ||||
| 	zaf_plugin_option "$1" Maintainer | ||||
| } | ||||
| zaf_plugin_url() { | ||||
| 	zaf_plugin_option "$1" Url | ||||
| } | ||||
| zaf_plugin_web() { | ||||
| 	zaf_plugin_option "$1" Web | ||||
| } | ||||
| zaf_plugin_template_url() { | ||||
| 	echo $(zaf_plugin_option "$1" Url)/template.xml | ||||
| } | ||||
|  | ||||
| # $1 plugin | ||||
| # $2 test to get test items, precache to get items to precache | ||||
| zaf_list_plugin_items() { | ||||
| 	local items | ||||
| 	local i | ||||
| 	local p | ||||
| 	local key | ||||
| 	local testparms | ||||
| 	local precache | ||||
|  | ||||
| 	if ! zaf_is_plugin "$1"; then | ||||
| 		zaf_err "Missing plugin name or plugin $1 unknown. "; | ||||
| 	fi | ||||
| 	plugindir="${ZAF_PLUGINS_DIR}/$1" | ||||
| 	cfile="$plugindir/control.zaf" | ||||
| 	items=$(zaf_ctrl_get_items <$cfile) | ||||
| 	for i in $items; do | ||||
| 		p=$(zaf_ctrl_get_item_option $cfile $i "Parameters") | ||||
| 		testparms=$(zaf_ctrl_get_item_option $cfile $i "Testparameters") | ||||
| 		precache=$(zaf_ctrl_get_item_option $cfile $i "Precache") | ||||
| 		case $2 in | ||||
| 		test) | ||||
| 			for tp in $testparms; do | ||||
| 				if [ -n "$p" ]; then | ||||
| 					echo -n "$1.$i[$tp] " | ||||
| 				else | ||||
| 					echo -n "$1.$i " | ||||
| 				fi | ||||
| 			done | ||||
| 			;; | ||||
| 		precache) | ||||
| 			for tp in $precache; do | ||||
| 				echo -n "$1.$i[$tp] " | ||||
| 			done | ||||
| 			;; | ||||
| 		*) | ||||
| 			if [ -n "$p" ]; then | ||||
| 				echo -n "$1.$i[] " | ||||
| 			else | ||||
| 				echo -n "$1.$i " | ||||
| 			fi | ||||
| 			;; | ||||
| 		esac | ||||
| 	done | ||||
| 	echo | ||||
| } | ||||
|  | ||||
| zaf_list_plugin_commands() { | ||||
| 	local plugindir | ||||
| 	local commands | ||||
|  | ||||
| 	if ! zaf_is_plugin "$1"; then | ||||
| 		zaf_err "Missing plugin name or plugin $1 unknown. "; | ||||
| 	fi | ||||
| 	plugindir="${ZAF_PLUGINS_DIR}/$1" | ||||
| 	commands=$(zaf_ctrl_get_global_option "${plugindir}/control.zaf" Install-cmd) | ||||
| 	if [ -n "$commands" ]; then | ||||
| 		echo $commands; | ||||
| 	else | ||||
| 		zaf_wrn "Plugin $1 has no commands." | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| # $1 plugin  | ||||
| # $2 cmd | ||||
| # $3...$9 arguments | ||||
| zaf_plugin_run_command() { | ||||
| 	local plugin | ||||
| 	local cmd | ||||
| 	local args | ||||
|  | ||||
| 	plugin=$1 | ||||
| 	cmd=$2 | ||||
| 	args="$3 $4 $5 $6 $7 $8 $9" | ||||
| 	if ! zaf_is_plugin "$plugin"; then | ||||
| 		zaf_err "Missing plugin name or plugin $olugin unknown. "; | ||||
| 	fi | ||||
| 	plugindir="${ZAF_PLUGINS_DIR}/$plugin" | ||||
| 	commands=$(zaf_ctrl_get_global_option "${plugindir}/control.zaf" Install-cmd) | ||||
| 	if echo $commands |grep -q $cmd; then | ||||
| 		export PATH=$plugindir:$PATH | ||||
| 		cd $plugindir | ||||
| 		[ -f functions.sh ] && source functions.sh | ||||
| 		exec $cmd $args; | ||||
| 	else | ||||
| 		zaf_err "Plugin $1 has no command $cmd" | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| zaf_item_info() { | ||||
| 	local plugin | ||||
| 	local item | ||||
| 	local param | ||||
| 	local tmp | ||||
|  | ||||
| 	plugin=$(echo $1 | cut -d '.' -f 1) | ||||
| 	item=$(echo $1 | cut -d '.' -f 2-) | ||||
| 	if zaf_is_plugin $plugin; then | ||||
| 		if zaf_ctrl_get_items <$ZAF_PLUGINS_DIR/$plugin/control.zaf | grep -wq "$item"; then | ||||
| 			printf "%b" "Item $1\n\n" | ||||
| 			tmp=$(zaf_ctrl_get_item_option $ZAF_PLUGINS_DIR/$plugin/control.zaf "$item" "Cache") | ||||
| 			[ -n "$tmp" ] && printf "%b" "Cache: $tmp \n\n" | ||||
| 			tmp=$(zaf_ctrl_get_item_option $ZAF_PLUGINS_DIR/$plugin/control.zaf "$item" "Parameters") | ||||
| 			[ -n "$tmp" ] && printf "%b" "Parameters:\n$tmp\n\n" | ||||
| 			tmp=$(zaf_ctrl_get_item_option $ZAF_PLUGINS_DIR/$plugin/control.zaf "$item" "Return") | ||||
| 			[ -n "$tmp" ] && printf "%b" "Return: $tmp\n\n" | ||||
| 			tmp=$(zaf_ctrl_get_item_option $ZAF_PLUGINS_DIR/$plugin/control.zaf "$item" "Return-null") | ||||
| 			[ -n "$tmp" ] && printf "%b" "Return-null: $tmp\n\n" | ||||
| 			tmp=$(zaf_ctrl_get_item_option $ZAF_PLUGINS_DIR/$plugin/control.zaf "$item" "Return-empty") | ||||
| 			[ -n "$tmp" ] && printf "%b" "Return-empty: $tmp\n\n" | ||||
| 			tmp=$(zaf_ctrl_get_item_option $ZAF_PLUGINS_DIR/$plugin/control.zaf "$item" "Testparameters") | ||||
| 			[ -n "$tmp" ] && printf "%b" "Testparameters: $tmp\n\n" | ||||
| 			tmp=$(zaf_ctrl_get_item_option $ZAF_PLUGINS_DIR/$plugin/control.zaf "$item" "Precache") | ||||
| 			[ -n "$tmp" ] && printf "%b" "Precache: $tmp\n\n" | ||||
| 			grep "UserParameter=$1" $ZAF_AGENT_CONFIGD/zaf_${plugin}.conf | ||||
| 		else | ||||
| 			zaf_err "No such item $item." | ||||
| 		fi	 | ||||
| 	else | ||||
| 		zaf_err "No such plugin $plugin." | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| zaf_list_items() { | ||||
| 	for p in $(zaf_list_plugins); do | ||||
| 		echo $p: $(zaf_list_plugin_items $p) | ||||
| 	done | ||||
| } | ||||
|  | ||||
| zaf_get_item() { | ||||
| 	if which zabbix_get >/dev/null; then | ||||
| 		zaf_trc zabbix_get -s localhost -k "'$1'" | ||||
| 		(zabbix_get -s localhost -k "$1" | tr '\n' ' '; echo) || zaf_wrn "Cannot reach agent on localhost. Please localhost to Server list." | ||||
| 		return 11 | ||||
| 	else | ||||
| 		zaf_wrn "Please install zabbix_get binary to check items over network." | ||||
| 		return 11 | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| zaf_test_item() { | ||||
| 	zaf_trc $ZAF_AGENT_BIN -t "'$1'" | ||||
| 	if $ZAF_AGENT_BIN -t "$1" | grep ZBX_NOTSUPPORTED; then | ||||
| 		return 1 | ||||
| 	else | ||||
| 		$ZAF_AGENT_BIN -t "$1" | tr '\n' ' ' | ||||
| 		echo | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| zaf_run_item() { | ||||
| 	local item | ||||
| 	item=$(echo $1| cut -d '[' -f 1) | ||||
| 	params=$(echo $1| cut -d '[' -f 2- | tr ',' ' '| tr -d ']') | ||||
| 	cmd=$(grep "^UserParameter=$item" $ZAF_AGENT_CONFIGD/zaf*.conf	| cut -d ',' -f 2-) | ||||
| 	echo $cmd >/tmp/a  | ||||
| 	sh /tmp/a $params | ||||
| } | ||||
|  | ||||
| zaf_precache_item() { | ||||
| 	cmd=$(grep "^UserParameter=$item" $ZAF_AGENT_CONFIGD/zaf*.conf	| cut -d ',' -f 2- | sed -e "s/_cache/_nocache/") | ||||
| 	zaf_wrn "Precaching item $item[$(echo $*| tr ' ' ',')] ($cmd)" | ||||
| 	eval $cmd | ||||
| } | ||||
|  | ||||
| zaf_remove_plugin() { | ||||
| 	! zaf_is_plugin $1 && { zaf_err "Plugin $1 not installed!"; } | ||||
| 	zaf_wrn "Removing plugin $1 (version $(zaf_plugin_version $1))" | ||||
| 	rm -rf ${ZAF_PLUGINS_DIR}/$1 | ||||
| 	rm -f ${ZAF_AGENT_CONFIGD}/zaf_$1.conf ${ZAF_CROND}/zaf_$1 ${ZAF_SUDOERSD}/zaf_$1 | ||||
| } | ||||
|  | ||||
| @@ -2,36 +2,49 @@ | ||||
|  | ||||
| . /etc/zaf.conf | ||||
|  | ||||
| [ -z "$ZAF_TMP_BASE" ] && ZAF_TMP_BASE=/tmp/zaf | ||||
| ZAF_TMP_DIR="${ZAF_TMP_BASE}-${USER}" | ||||
| [ -z "$ZAF_CACHE_DIR" ] && ZAF_CACHE_DIR=${ZAF_TMP_BASE}c | ||||
|  | ||||
| trap "rm -rif ${ZAF_TMP_DIR}" EXIT | ||||
| ! [ -d "${ZAF_TMP_DIR}" ] && mkdir "${ZAF_TMP_DIR}" | ||||
| ! [ -d "${ZAF_CACHE_DIR}" ] && mkdir "${ZAF_CACHE_DIR}" | ||||
| [ -z "$ZAF_DEBUG" ] && ZAF_DEBUG=1 | ||||
|  | ||||
| . ${ZAF_LIB_DIR}/zaf.lib.sh | ||||
| . ${ZAF_LIB_DIR}/plugin.lib.sh | ||||
| . ${ZAF_LIB_DIR}/ctrl.lib.sh | ||||
| . ${ZAF_LIB_DIR}/os.lib.sh | ||||
| . ${ZAF_LIB_DIR}/zbxapi.lib.sh | ||||
| . ${ZAF_LIB_DIR}/cache.lib.sh | ||||
|  | ||||
| if ! type zaf_version >/dev/null; then | ||||
| 	echo "Problem loading libraries?" | ||||
| 	exit 2 | ||||
| fi | ||||
|  | ||||
| zaf_debug_init | ||||
| zaf_tmp_init | ||||
| zaf_cache_init | ||||
|  | ||||
| # Global plugin parameters | ||||
| [ -f ./params ] && for p in $(cat ./params); do | ||||
| 	var=$p | ||||
| 	value="$(cat ${p}.value)" | ||||
| 	zaf_trc "Global $p parameter $var=$value" | ||||
| 	eval export $var="$value"	 | ||||
| done | ||||
|  | ||||
| export ZAF_LIB_DIR | ||||
| export ZAF_TMP_DIR | ||||
| export ZAF_CACHE_DIR | ||||
| export ZAF_PLUGINS_DIR | ||||
| export ZAF_DEBUG | ||||
| unset ZAF_LOG_STDERR | ||||
| export PATH | ||||
|  | ||||
| if [ "$1" = "_cache" ] || [ "$1" = "_nocache" ] ; then | ||||
| 	[ "$1" = "_nocache" ] && export ZAF_NOCACHE=1 | ||||
| 	shift | ||||
| 	seconds=$1 | ||||
| 	shift | ||||
| 	parms=$(echo $*|tr -d ' ') | ||||
| 	if ! zaf_fromcache $parms; then | ||||
| 		([ "$(basename $0)" = "preload.sh" ] && [ -n "$*" ] && $@ ) | zaf_tocache_stdin $parms $seconds | ||||
| 	fi | ||||
| # Plugin specific functions if exists | ||||
| [ -f ./functions.sh ] && . ./functions.sh | ||||
|  | ||||
| if [ "$(basename $0)" = "preload.sh" ] && [ -n "$*" ]; then | ||||
| 	tmpf=$(zaf_tmpfile preload) | ||||
| 	export tmpf | ||||
| 	$@ 2>$tmpf | ||||
| 	[ -s $tmpf ] && zaf_wrn <$tmpf | ||||
| else | ||||
| 	[ "$(basename $0)" = "preload.sh" ] && [ -n "$*" ] && $@ | ||||
| 	tmpf=$(zaf_tmpfile preload) | ||||
| 	export tmpf	 | ||||
| fi | ||||
|  | ||||
|  | ||||
|   | ||||
							
								
								
									
										568
									
								
								lib/zaf.lib.sh
									
									
									
									
									
								
							
							
						
						
									
										568
									
								
								lib/zaf.lib.sh
									
									
									
									
									
								
							| @@ -1,7 +1,7 @@ | ||||
|  | ||||
| # Hardcoded variables | ||||
| ZAF_VERSION="1.1" | ||||
| ZAF_GITBRANCH="1.1" | ||||
| ZAF_VERSION="1.4" | ||||
| ZAF_GITBRANCH="master" | ||||
| ZAF_URL="https://github.com/limosek/zaf" | ||||
| ZAF_RAW_URL="https://raw.githubusercontent.com/limosek/zaf" | ||||
|  | ||||
| @@ -11,24 +11,77 @@ zaf_msg() { | ||||
| 	echo $@ | ||||
| } | ||||
| zaf_trc() { | ||||
| 	[ "$ZAF_DEBUG" -ge "3" ] && logger -s -t zaf -- $@ | ||||
| 	[ "$ZAF_DEBUG" -ge "3" ] && logger -p user.info ${ZAF_LOG_STDERR} -t zaf-trace -- $@ | ||||
| 	return 0 | ||||
| } | ||||
| zaf_dbg() { | ||||
| 	[ "$ZAF_DEBUG" -ge "2" ] && logger -s -t zaf -- $@ | ||||
| 	[ "$ZAF_DEBUG" -ge "2" ] && logger -p user.debug ${ZAF_LOG_STDERR} -t zaf-debug -- $@ | ||||
| 	return 0 | ||||
| } | ||||
| zaf_wrn() { | ||||
| 	[ "$ZAF_DEBUG" -ge "1" ] && logger -s -t zaf -- $@ | ||||
| 	[ "$ZAF_DEBUG" -ge "1" ] && logger -p user.warn ${ZAF_LOG_STDERR} -t zaf-warning -- $@ | ||||
| 	return 0 | ||||
| } | ||||
| zaf_err() { | ||||
| 	logger -s -t zaf -- $@ | ||||
|         logger -s -t zaf "Exiting with error!" | ||||
|         exit 1 | ||||
| 	logger ${ZAF_LOG_STDERR} -p user.err -t zaf-error -- $@ | ||||
| 	logger ${ZAF_LOG_STDERR} -p user.err -t zaf-error "Exiting with error!" | ||||
| 	exit 1 | ||||
| } | ||||
| # Help option | ||||
| # $1 - key | ||||
| # $2 -  | ||||
| zaf_hlp() { | ||||
| 	local kl | ||||
| 	local dl | ||||
| 	local cols | ||||
|  | ||||
| 	cols=$COLUMNS | ||||
| 	[ -z "$cols" ] && cols=120 | ||||
| 	kl=$(expr $cols / 3) | ||||
| 	dl=$(expr $cols - $kl) | ||||
| 	printf %-${kl}s%-${dl}s%b "$1" "$2" "\n" | ||||
| } | ||||
| # $1 if nonempty, log to stderr too | ||||
| zaf_debug_init() { | ||||
| 	[ -z "$ZAF_DEBUG" ] && ZAF_DEBUG=1 | ||||
| 	export ZAF_DEBUG | ||||
| 	[ -n "$1" ] && export ZAF_LOG_STDERR="-s" | ||||
| } | ||||
|  | ||||
| zaf_tmp_init() { | ||||
| 	[ -z "$ZAF_TMP_DIR" ] && ZAF_TMP_DIR=/tmp/ | ||||
| 	! [ -w "$ZAF_TMP_DIR" ] && zaf_err "Tmp dir $ZAF_TMP_DIR is not writable." | ||||
| } | ||||
|  | ||||
| zaf_version(){ | ||||
| 	echo $ZAF_VERSION | ||||
| } | ||||
|  | ||||
| # Add parameter for agent check | ||||
| # $1 parameter name (will be set to var) | ||||
| # $2 if nonempty, it is default value. If empty, parameter is mandatory | ||||
| # $3 if nonempty, regexp to test | ||||
| zaf_agentparm(){ | ||||
| 	local name | ||||
| 	local default | ||||
| 	local regexp | ||||
|  | ||||
| 	name="$1" | ||||
| 	default="$2" | ||||
| 	regexp="$3" | ||||
| 	 | ||||
| 	[ -z "$value" ] && [ -z "$default" ] && zaf_err "$ITEM_KEY: Missing mandatory parameter $name." | ||||
| 	if [ -z "$value" ]; then | ||||
| 		value="$default" | ||||
| 	else | ||||
| 		if [ -n "$regexp" ]; then | ||||
| 			echo "$value" | grep -qE "$regexp" ||	 zaf_err "$ITEM_KEY: Bad parameter '$name' value '$value' (not in regexp '$regexp')." | ||||
| 		fi | ||||
| 	fi | ||||
| 	zaf_trc "$ITEM_KEY: Param $name set to $value" | ||||
| 	eval $name=\"$value\" | ||||
| } | ||||
|  | ||||
| # Fetch url to stdout  | ||||
| # $1 url | ||||
| # It supports real file, file:// and other schemes known by curl | ||||
| @@ -49,49 +102,75 @@ zaf_fetch_url() { | ||||
| 	case $scheme in | ||||
| 	http|https|ftp|file) | ||||
| 		[ "$scheme" != "file" ] && [ -n "$ZAF_OFFLINE" ] && zaf_err "Cannot download $1 in offline mode!" | ||||
| 		[ "${ZAF_CURL_INSECURE}" = "1" ] && insecure="-k" | ||||
| 		zaf_dbg curl $insecure -f -s -L -o - $1 | ||||
| 		curl $insecure -f -s -L -o - "$1" | zaf_tocache_stdin "$1" 120 | ||||
| 		if zaf_which curl >/dev/null 2>/dev/null; then | ||||
| 			[ "${ZAF_CURL_INSECURE}" = "1" ] && insecure="-k" | ||||
| 			zaf_dbg curl $insecure -f -s -L -o - $1 | ||||
| 			curl $insecure -f -s -L -o - "$1" | zaf_tocache_stdin "$1" 120 | ||||
| 		else | ||||
| 			[ "${ZAF_CURL_INSECURE}" = "1" ] && insecure="--no-check-certificate" | ||||
| 			zaf_dbg wget $insecure -O - $1 | ||||
| 			wget $insecure -O - "$1" | zaf_tocache_stdin "$1" 120 | ||||
| 		fi | ||||
| 	;; | ||||
| 	esac  | ||||
| } | ||||
|  | ||||
| # Get info about url | ||||
| # returns	 path or url | ||||
| zaf_url_info() { | ||||
| 	if echo "$1" | grep -q '^/'; then | ||||
| 		echo "path" | ||||
| 	else | ||||
| 		if echo "$1" | grep -q ^http; then | ||||
| 			echo "url" | ||||
| 		else | ||||
| 			echo "unknown" | ||||
| 		fi | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| # Find and replace string | ||||
| zaf_far(){ | ||||
|    local f | ||||
|    local t | ||||
|         local sedcmd="sed" | ||||
|         i=1 | ||||
|         while [ "$i" -lt "$#" ]; | ||||
|         do | ||||
|                 eval f=\$${i} | ||||
|                 i=$(expr $i + 1) | ||||
|                 eval t=\$${i} | ||||
|                 i=$(expr $i + 1) | ||||
|                 sedcmd="$sedcmd -e 's~$f~$t~g'" | ||||
|         done | ||||
|    eval $sedcmd | ||||
| 	 local f | ||||
| 	 local t | ||||
| 				local sedcmd="sed" | ||||
| 				i=1 | ||||
| 				while [ "$i" -lt "$#" ]; | ||||
| 				do | ||||
| 								eval f=\$${i} | ||||
| 								i=$(expr $i + 1) | ||||
| 								eval t=\$${i} | ||||
| 								i=$(expr $i + 1) | ||||
| 								sedcmd="$sedcmd -e 's~$f~$t~g'" | ||||
| 				done | ||||
| 	 eval $sedcmd | ||||
| } | ||||
|  | ||||
| # Trim spaces and newlines from string | ||||
| zaf_trim(){ | ||||
| 	tr -d '\n' | ||||
| } | ||||
|  | ||||
| # Limit concurrent processes or continue | ||||
| zaf_bglimit(){ | ||||
|     local maxbg | ||||
|     local maxnumber | ||||
|     local cnumber | ||||
|     if [ $# -eq 0 ] ; then | ||||
|             maxbg=5 | ||||
|     else | ||||
| 	    maxbg=$1 | ||||
|     fi | ||||
|     maxnumber=$((0 + ${1:-0})) | ||||
|     while true; do | ||||
|             cnumber=$(jobs | wc -l) | ||||
|             if [ $cnumber -lt $maxnumber ]; then | ||||
|                     break | ||||
|             fi | ||||
| 	    zaf_dbg "Limiting next job due to $maxbg limit of bg jobs" | ||||
|             sleep 1 | ||||
|     done | ||||
| 		local maxbg | ||||
| 		local maxnumber | ||||
| 		local cnumber | ||||
| 		[ -z "$BASH_VERSION" ] && { zaf_dbg "Job server not available. Use bash!"; return 1; } | ||||
| 		if [ $# -eq 0 ] ; then | ||||
| 						maxbg=5 | ||||
| 		else | ||||
| 			maxbg=$1 | ||||
| 		fi | ||||
| 		maxnumber=$((0 + ${1:-0})) | ||||
| 		while true; do | ||||
| 						cnumber=$(jobs | wc -l) | ||||
| 						if [ $cnumber -lt $maxnumber ]; then | ||||
| 										break | ||||
| 						fi | ||||
| 			zaf_dbg "Limiting next job due to $maxbg limit of bg jobs" | ||||
| 						sleep 1 | ||||
| 		done | ||||
| } | ||||
|  | ||||
| # Initialises discovery function | ||||
| @@ -104,27 +183,27 @@ EOF | ||||
|  | ||||
| # Add row(s) to discovery data | ||||
| zaf_discovery_add_row(){ | ||||
|   local rows | ||||
|   local row | ||||
| 	local rows | ||||
| 	local row | ||||
|  | ||||
|   rows=$1 | ||||
|   row=$2 | ||||
|   shift;shift | ||||
|   echo " {" | ||||
|   while [ -n "$1" ]; do | ||||
|     echo -n '  "'$1'":"'$2'" ' | ||||
|     shift;shift | ||||
|     if [ -n "$1" ]; then | ||||
| 	rows=$1 | ||||
| 	row=$2 | ||||
| 	shift;shift | ||||
| 	echo " {" | ||||
| 	while [ -n "$1" ]; do | ||||
| 		echo -n '	 "'$1'":"'$2'" ' | ||||
| 		shift;shift | ||||
| 		if [ -n "$1" ]; then | ||||
| 	echo "," | ||||
|     else | ||||
| 		else | ||||
| 	echo "" | ||||
|     fi | ||||
|   done | ||||
|   if [ "$row" -lt "$rows" ]; then | ||||
|   	echo " }," | ||||
|   else | ||||
| 		fi | ||||
| 	done | ||||
| 	if [ "$row" -lt "$rows" ]; then | ||||
| 		echo " }," | ||||
| 	else | ||||
| 	echo " }" | ||||
|   fi | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| # Dumps json object | ||||
| @@ -139,22 +218,22 @@ EOF | ||||
| # Arguments are name of variables to discovery. | ||||
| # Dumps json to stdout | ||||
| zaf_discovery(){ | ||||
|   local tmpfile | ||||
|   local rows | ||||
|   local a b c d e f g h i j row | ||||
| 	local tmpfile | ||||
| 	local rows | ||||
| 	local a b c d e f g h i j row | ||||
|  | ||||
|   tmpfile="${ZAF_TMP_DIR}/disc$$" | ||||
|   cat >$tmpfile | ||||
|   rows=$(wc -l <$tmpfile) | ||||
|   local a b c d e f g h i j; | ||||
|   zaf_discovery_begin | ||||
|   row=1 | ||||
|   while read a b c d e f g h i j; do | ||||
|     zaf_discovery_add_row "$rows" "$row" "$1" "${1:+${a}}" "$2" "${2:+${b}}" "$3" "${3:+${c}}" "$4" "${4:+${d}}" "$5" "${5:+${e}}" "$6" "${6:+${f}}" "$7" "${7:+${g}}" "$8" "${8:+${h}}" "$9" "${9:+${i}}" | ||||
|     row=$(expr $row + 1) | ||||
|   done <$tmpfile | ||||
|   zaf_discovery_end | ||||
|   rm -f $tmpfile | ||||
| 	tmpfile="${ZAF_TMP_DIR}/disc$$" | ||||
| 	cat >$tmpfile | ||||
| 	rows=$(wc -l <$tmpfile) | ||||
| 	local a b c d e f g h i j; | ||||
| 	zaf_discovery_begin | ||||
| 	row=1 | ||||
| 	while read a b c d e f g h i j; do | ||||
| 		zaf_discovery_add_row "$rows" "$row" "$1" "${1:+${a}}" "$2" "${2:+${b}}" "$3" "${3:+${c}}" "$4" "${4:+${d}}" "$5" "${5:+${e}}" "$6" "${6:+${f}}" "$7" "${7:+${g}}" "$8" "${8:+${h}}" "$9" "${9:+${i}}" | ||||
| 		row=$(expr $row + 1) | ||||
| 	done <$tmpfile | ||||
| 	zaf_discovery_end | ||||
| 	rm -f $tmpfile | ||||
| } | ||||
|  | ||||
| ############################################ Zaf internal routines | ||||
| @@ -171,257 +250,6 @@ zaf_check_agent_config() { | ||||
| 	${ZAF_AGENT_BIN} -t zaf.version | ||||
| } | ||||
|  | ||||
| # Update repo | ||||
| zaf_update_repo() { | ||||
| 	[ "$ZAF_GIT" != 1 ] && { zaf_err "Git is disabled or is not installed. Exiting."; } | ||||
| 	if [ -z "${ZAF_REPO_GITURL}" ] || [ -z "${ZAF_REPO_DIR}" ]; then | ||||
| 		zaf_err "This system is not configured for git repository." | ||||
| 	else | ||||
| 		[ ! -d "${ZAF_REPO_DIR}" ] && git clone "${ZAF_REPO_GITURL}" "${ZAF_REPO_DIR}" | ||||
| 		(cd ${ZAF_REPO_DIR} && git pull) | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| # Construct url from plugin name | ||||
| # It can be http[s]://url | ||||
| # /path (from file) | ||||
| # name (to try from repo) | ||||
| zaf_get_plugin_url() { | ||||
| 	local url | ||||
|  | ||||
| 	if echo "$1" | grep -q '/'; then | ||||
| 		url="$1" 		# plugin with path - from directory | ||||
| 	else | ||||
| 		if echo "$1" | grep -q ^http; then | ||||
| 			url="$1"	# plugin with http[s] url  | ||||
| 		else | ||||
| 			if [ -d "${ZAF_REPO_DIR}/$1" ]; then | ||||
| 				url="${ZAF_REPO_DIR}/$1" | ||||
| 			else | ||||
| 				if [ -n "${ZAF_PREPACKAGED_DIR}" ] &&  [ -d "${ZAF_PREPACKAGED_DIR}/$1" ]; then | ||||
| 					url="${ZAF_PREPACKAGED_DIR}/$1" | ||||
| 				else | ||||
| 					if [ -n "${ZAF_REPO_URL}" ]; then | ||||
| 						url="${ZAF_REPO_URL}/$1"  | ||||
| 					else | ||||
| 						zaf_err "Cannot find plugin $1" | ||||
| 					fi | ||||
| 				fi | ||||
| 			fi | ||||
| 		fi | ||||
| 	fi | ||||
| 	echo $url | ||||
| } | ||||
|  | ||||
| # $1 - control | ||||
| zaf_plugin_info() { | ||||
| 	local control="$1" | ||||
|  | ||||
| 	! [ -f "$control" ] && zaf_err "Control file $control not found." | ||||
| 	plugin=$(zaf_ctrl_get_global_block <"${control}" | zaf_block_get_option Plugin) | ||||
| 	pdescription=$(zaf_ctrl_get_global_block <"${control}" | zaf_block_get_moption Description) | ||||
| 	pmaintainer=$(zaf_ctrl_get_global_block <"${control}" | zaf_block_get_option Maintainer) | ||||
| 	pversion=$(zaf_ctrl_get_global_block <"${control}" | zaf_block_get_option Version) | ||||
| 	purl=$(zaf_ctrl_get_global_block <"${control}" | zaf_block_get_option Url) | ||||
| 	phome=$(zaf_ctrl_get_global_block <"${control}" | zaf_block_get_option Home) | ||||
| 	pitems=$(zaf_ctrl_get_items <"${control}") | ||||
| 	echo | ||||
| 	echo -n "Plugin '$plugin' "; [ -n "$pversion" ] && echo -n "version ${pversion}"; echo ":" | ||||
| 	echo "$pdescription"; echo | ||||
| 	[ -n "$pmaintainer" ] && echo "Maintainer: $pmaintainer" | ||||
| 	[ -n "$purl" ] && echo "Url: $purl" | ||||
| 	[ -n "$phome" ] && echo "Home: $phome" | ||||
| 	echo  | ||||
| 	if zaf_is_plugin "$(basename $plugin)"; then | ||||
| 		echo -n "Defined items: "; zaf_list_plugin_items $plugin | ||||
| 		echo -n "Test items: "; zaf_list_plugin_items $plugin test | ||||
| 		echo -n "Precache items: "; zaf_list_plugin_items $plugin precache | ||||
| 	else | ||||
| 		echo "Items: $pitems" | ||||
| 	fi | ||||
| 	echo | ||||
| } | ||||
|  | ||||
| # Prepare plugin into dir  | ||||
| # $1 is url, directory or plugin name (will be searched in default plugin dir).  | ||||
| # $2 is directory to prepare.  | ||||
| zaf_prepare_plugin() { | ||||
| 	local url | ||||
| 	local plugindir | ||||
| 	local control | ||||
|  | ||||
| 	url=$(zaf_get_plugin_url "$1")/control.zaf || exit $? | ||||
| 	plugindir="$2" | ||||
| 	control=${plugindir}/control.zaf | ||||
| 	zaf_install_dir "$plugindir" | ||||
| 	zaf_dbg "Fetching control file from $url ..." | ||||
| 	if zaf_fetch_url "$url" >"${control}"; then | ||||
| 		zaf_ctrl_check_deps "${control}" | ||||
| 	else | ||||
| 		zaf_err "prepare_plugin: Cannot fetch or write control file $control from url $url!" | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| zaf_install_plugin() { | ||||
| 	local url | ||||
| 	local plugin | ||||
| 	local plugindir | ||||
| 	local control | ||||
| 	local version | ||||
|  | ||||
| 	if zaf_prepare_plugin "$1" "${ZAF_TMP_DIR}/plugin"; then | ||||
| 		url=$(zaf_get_plugin_url "$1") | ||||
| 		control="${ZAF_TMP_DIR}/plugin/control.zaf" | ||||
|                 plugin=$(zaf_ctrl_get_global_option $control Plugin) | ||||
| 		version=$(zaf_ctrl_get_global_option $control Version) | ||||
| 		plugindir="${ZAF_PLUGINS_DIR}"/$plugin | ||||
| 		if [ -n "$plugin" ] && zaf_prepare_plugin "$1" $plugindir; then | ||||
| 			zaf_wrn "Installing plugin $plugin version $version" | ||||
| 			zaf_dbg "Source url: $url, Destination dir: $plugindir" | ||||
| 			control=${plugindir}/control.zaf | ||||
| 			[ "$ZAF_DEBUG" -gt 1 ] && zaf_plugin_info "${control}" | ||||
| 			zaf_ctrl_check_deps "${control}" | ||||
| 			zaf_ctrl_install "$url" "${control}" "${plugindir}" | ||||
| 			zaf_ctrl_sudo "$plugin" "${control}" "${plugindir}" | ||||
| 			zaf_ctrl_cron "$plugin" "${control}" "${plugindir}" | ||||
| 			zaf_ctrl_generate_cfg "${control}" "${plugin}" \ | ||||
| 			  | zaf_far '{PLUGINDIR}' "${plugindir}" >${ZAF_AGENT_CONFIGD}/zaf_${plugin}.conf | ||||
| 			zaf_dbg "Generated ${ZAF_AGENT_CONFIGD}/zaf_${plugin}.conf" | ||||
| 		else | ||||
| 			zaf_err "Cannot install plugin '$plugin' to $plugindir!" | ||||
| 		fi | ||||
|         else | ||||
|             	zaf_err "Cannot prepare plugin $1" | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| # List installed plugins | ||||
| # $1 - plugin | ||||
| zaf_list_plugins() { | ||||
| 	local cfile | ||||
| 	local plugin | ||||
| 	ls -1 ${ZAF_PLUGINS_DIR} | while read p; do | ||||
| 		zaf_is_plugin "$(basename $p)" && echo $p | ||||
| 	done | ||||
| } | ||||
|  | ||||
| zaf_is_plugin() { | ||||
| 	[ -d "$ZAF_PLUGINS_DIR/$1" ] && [ -f "$ZAF_PLUGINS_DIR/$1/control.zaf" ] && return | ||||
| 	false | ||||
| } | ||||
|  | ||||
| zaf_discovery_plugins() { | ||||
| 	zaf_list_plugins | zaf_discovery '{#PLUGIN}' | ||||
| } | ||||
|  | ||||
| # $1 plugin | ||||
| # $2 ctrl_option | ||||
| zaf_plugin_option() { | ||||
| 	local plugindir | ||||
| 	local cfile | ||||
|  | ||||
| 	if [ -z "$1" ]; then | ||||
| 		zaf_err "Missing plugin name."; | ||||
| 	fi | ||||
| 	if zaf_is_plugin "$1"; then | ||||
| 		plugindir="${ZAF_PLUGINS_DIR}/$1" | ||||
| 		cfile="$plugindir/control.zaf" | ||||
| 		zaf_ctrl_get_global_option $cfile $2 | ||||
| 	else | ||||
| 		zaf_err "Plugin $1 not installed." | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| zaf_plugin_version() { | ||||
| 	zaf_plugin_option "$1" Version | ||||
| } | ||||
| zaf_plugin_maintainer() { | ||||
| 	zaf_plugin_option "$1" Maintainer | ||||
| } | ||||
| zaf_plugin_url() { | ||||
| 	zaf_plugin_option "$1" Url | ||||
| } | ||||
| zaf_plugin_web() { | ||||
| 	zaf_plugin_option "$1" Web | ||||
| } | ||||
| zaf_plugin_template_url() { | ||||
| 	echo $(zaf_plugin_option "$1" Url)/template.xml | ||||
| } | ||||
|  | ||||
| # $1 plugin | ||||
| # $2 test to get test items, precache to get items to precache | ||||
| zaf_list_plugin_items() { | ||||
| 	local items | ||||
| 	local i | ||||
| 	local p | ||||
| 	local key | ||||
| 	local testparms | ||||
| 	local precache | ||||
|  | ||||
| 	if ! zaf_is_plugin "$1"; then | ||||
| 		zaf_err "Missing plugin name or plugin $1 unknown. "; | ||||
| 	fi | ||||
| 	plugindir="${ZAF_PLUGINS_DIR}/$1" | ||||
| 	cfile="$plugindir/control.zaf" | ||||
| 	items=$(zaf_ctrl_get_items <$cfile) | ||||
| 	for i in $items; do | ||||
| 		p=$(zaf_ctrl_get_item_option $cfile $i "Parameters") | ||||
| 		testparms=$(zaf_ctrl_get_item_option $cfile $i "Testparameters") | ||||
| 		precache=$(zaf_ctrl_get_item_option $cfile $i "Precache") | ||||
| 		if [ -n "$p" ]; then | ||||
| 			if [ -n "$testparms" ] && [ "$2" = "test" ]; then | ||||
| 				for tp in $testparms; do | ||||
| 					echo -n "$1.$i[$tp] " | ||||
| 				done | ||||
| 			else | ||||
| 				if [ -n "$precache" ] && [ "$2" = "precache" ]; then | ||||
| 					for tp in $precache; do | ||||
| 						echo -n "$1.$i[$tp] " | ||||
| 					done | ||||
| 				fi | ||||
| 				[ "$2" != "test" ] && key="$1.$i[]" | ||||
| 			fi | ||||
| 		else | ||||
| 			key="$1.$i" | ||||
| 		fi | ||||
| 		[ "$2" != "precache" ] && echo -n "$key " | ||||
| 	done | ||||
| 	echo | ||||
| } | ||||
|  | ||||
| zaf_list_items() { | ||||
| 	for p in $(zaf_list_plugins); do | ||||
| 		echo $p: $(zaf_list_plugin_items $p) | ||||
| 	done | ||||
| } | ||||
|  | ||||
| zaf_get_item() { | ||||
| 	if which zabbix_get >/dev/null; then | ||||
| 		zabbix_get -s localhost -k "$1" || zaf_wrn "Cannot reach agent on localhost. Please localhost to Server list." | ||||
| 		return 11 | ||||
| 	else | ||||
| 		zaf_wrn "Please install zabbix_get binary to check items over network." | ||||
| 		return 11 | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| zaf_test_item() { | ||||
| 	$ZAF_AGENT_BIN -t "$1" | ||||
| } | ||||
|  | ||||
| zaf_precache_item() { | ||||
| 	cmd=$(grep "^UserParameter=$item" $ZAF_AGENT_CONFIGD/zaf*.conf  | cut -d ',' -f 2- | sed -e "s/_cache/_nocache/") | ||||
| 	zaf_wrn "Precaching item $item[$(echo $*| tr ' ' ',')] ($cmd)" | ||||
| 	eval $cmd | ||||
| } | ||||
|  | ||||
| zaf_remove_plugin() { | ||||
| 	! zaf_is_plugin $1 && { zaf_err "Plugin $1 not installed!"; } | ||||
| 	zaf_wrn "Removing plugin $1 (version $(zaf_plugin_version $1))" | ||||
| 	rm -rf ${ZAF_PLUGINS_DIR}/$1 | ||||
| 	rm -f ${ZAF_AGENT_CONFIGD}/zaf_$1.conf ${ZAF_CROND}/zaf_$1 ${ZAF_SUDOERSD}/zaf_$1 | ||||
| } | ||||
|  | ||||
| zaf_tolower() { | ||||
| 	tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | ||||
| } | ||||
| @@ -432,7 +260,97 @@ zaf_toupper() { | ||||
|  | ||||
| # Return simplified key with discarded special chars. | ||||
| zaf_stripctrl() { | ||||
| 	echo $1 | tr '[]*&;:.-' '________' | ||||
| 	echo $1 | tr '[]*&;:.-' '________' | tr -d '\n' | ||||
| } | ||||
|  | ||||
| # Unescape string on stdin | ||||
| # $1 - list of chars to unescape | ||||
| zaf_strunescape() { | ||||
| 	 sed -e 's#\\\(['"$1"']\)#\1#g' | ||||
| } | ||||
|  | ||||
| # Escape string on stdin | ||||
| # $1 - list of chars to escape | ||||
| zaf_strescape() { | ||||
| 	 sed -e 's#\(['"$1"']\)#\\\1#g' | ||||
| } | ||||
|  | ||||
| # Add seconds to current date and return date in YYYY-MM-DD hh:mm:ss | ||||
| # $1 seconds | ||||
| zaf_date_add() { | ||||
| 	date -d "$1 seconds" "+%Y-%m-%d %H:%M:%S" 2>/dev/null || date -d "$(expr $(date +%s) + $1)" -D %s "+%Y-%m-%d %H:%M:%S" | ||||
| } | ||||
|  | ||||
| # Create temp file and return its name | ||||
| # $1 prefix or empty | ||||
| zaf_tmpfile() { | ||||
| 	echo "$ZAF_TMP_DIR/tmp$1$(zaf_random)" | ||||
| } | ||||
|  | ||||
| # return random number | ||||
| zaf_random() { | ||||
| 	hexdump -n 2 -e '/2 "%u"' /dev/urandom | ||||
| } | ||||
|  | ||||
| # Emulate sudo | ||||
| zaf_sudo() { | ||||
| 	if zaf_is_root || ! zaf_which sudo >/dev/null 2>/dev/null; then | ||||
| 		$@ | ||||
| 	else | ||||
| 		sudo $@ | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| # Get item name from plugin.item[parms] | ||||
| zaf_get_plugin_name() { | ||||
| 	echo $1|cut -d '.' -f 1 | ||||
| } | ||||
|  | ||||
| # Get item name from plugin.item[parms] | ||||
| zaf_get_item_name() { | ||||
| 	echo $1|cut -d '.' -f 2-|cut -d '[' -f 1 | ||||
| } | ||||
|  | ||||
| # Get item params from plugin.item[parms] | ||||
| zaf_get_item_params() { | ||||
| 	echo $1|cut -d '[' -f 2|cut -d ']' -f 1 | ||||
| } | ||||
|  | ||||
| # Convert Zabbix style parameters [param1,param2,..] into $1 $2 $3 | ||||
| zaf_paramstosh() { | ||||
| 	local parms | ||||
| 	local IFS | ||||
| 	parms=$(echo $*|cut -d '[' -f 2 | cut -d ']' -f 1| tr ',' '~') | ||||
| 	IFS="~"; for i in $parms; do | ||||
| 		if [ -n "$i" ]; then | ||||
| 			printf "$i " | ||||
| 		else | ||||
| 			printf "'' " | ||||
| 		fi | ||||
| 	done | ||||
| } | ||||
|  | ||||
| #Returns either actual hostname or configured one | ||||
| zaf_hostname() { | ||||
| 	if [ -z "$ZAF_HOSTNAME" ]; then | ||||
| 		hostname | ||||
| 	else | ||||
| 		echo $ZAF_HOSTNAME | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| # Send active agent query (used for auto registration of host) | ||||
| # $1 hostname | ||||
| # $2 metadata | ||||
| zaf_register() { | ||||
| 	local query | ||||
| 	local result | ||||
| 	zaf_dbg "zaf_register $1 $2" | ||||
| 	query="{\"host\": \"$1\", \"host_metadata\": \"$2\", \"request\": \"active checks\"}" | ||||
| 	result="$(echo $query| nc -q1 $ZAF_ZBXSRV_HOST $ZAF_ZBXSRV_PORT | tail -c +14)" | ||||
| 	if echo $result |grep -q failed; then | ||||
| 		zaf_wrn $result | ||||
| 	fi | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
							
								
								
									
										26
									
								
								lib/zafcache
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								lib/zafcache
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| #!/bin/sh | ||||
|  | ||||
| . $(dirname $0)/preload.sh | ||||
|  | ||||
| help() { | ||||
| 	zaf_err "$0 seconds cmd..." | ||||
| } | ||||
|  | ||||
| seconds=$1 | ||||
| shift | ||||
| [ -z "$*" ] && help | ||||
|  | ||||
| zaf_trc "zafcache($seconds): $ITEM_KEY,'$2' '$3' '$4' '$5' '$6' '$7' '$8' '$9'" | ||||
|  | ||||
| if [ -z "$ITEM_KEY" ]; then | ||||
| 	key=$(echo $*|tr ' ' '_') | ||||
| else | ||||
| 	key="$(echo ${ITEM_KEY}|cut -d '[' -f 1)[$(shift; echo $*|tr ' ' ',')]" | ||||
| fi | ||||
|  | ||||
| if ! zaf_fromcache "$key"; then | ||||
| 	tmpf=$(zaf_tmpfile cache) | ||||
| 	$@ 2>"$tmpf" | zaf_tocache_stdin "$key" "$seconds"  | ||||
| 	[ -s $tmpf ] && zaf_wrn <$tmpf | ||||
| fi | ||||
|  | ||||
							
								
								
									
										29
									
								
								lib/zafext
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								lib/zafext
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| #!/bin/sh | ||||
|  | ||||
| . /etc/zaf.conf | ||||
|  | ||||
| . ${ZAF_LIB_DIR}/zaf.lib.sh | ||||
| . ${ZAF_LIB_DIR}/plugin.lib.sh | ||||
| . ${ZAF_LIB_DIR}/ctrl.lib.sh | ||||
| . ${ZAF_LIB_DIR}/os.lib.sh | ||||
| . ${ZAF_LIB_DIR}/zbxapi.lib.sh | ||||
| . ${ZAF_LIB_DIR}/cache.lib.sh | ||||
|  | ||||
| if ! type zaf_version >/dev/null; then | ||||
| 	echo "Problem loading libraries?" | ||||
| 	exit 2 | ||||
| fi | ||||
| zaf_debug_init | ||||
| zaf_tmp_init | ||||
| zaf_cache_init | ||||
|  | ||||
| export ZAF_LIB_DIR | ||||
| export ZAF_TMP_DIR | ||||
| export ZAF_CACHE_DIR | ||||
| export ZAF_PLUGINS_DIR | ||||
| export ZAF_DEBUG | ||||
| unset ZAF_LOG_STDERR | ||||
| export PATH | ||||
| export ZAF_ITEM=$(basename $0) | ||||
|  | ||||
|  | ||||
							
								
								
									
										14
									
								
								lib/zaflock
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								lib/zaflock
									
									
									
									
									
								
							| @@ -1,12 +1,9 @@ | ||||
| #!/bin/sh | ||||
|  | ||||
| . /etc/zaf.conf | ||||
|  | ||||
| . ${ZAF_LIB_DIR}/zaf.lib.sh | ||||
| . $(dirname $0)/preload.sh | ||||
|  | ||||
| help() { | ||||
| 	echo "$0 key cmd" | ||||
| 	exit 2 | ||||
| 	zaf_err "$0 key cmd" | ||||
| } | ||||
|  | ||||
| lkey="$1" | ||||
| @@ -16,7 +13,7 @@ shift | ||||
| [ -z "${ZAF_LOCK_SECONDS}" ] && seconds=5 | ||||
| [ -z "${ZAF_LOCK_FORCE}" ] && force=1 | ||||
|  | ||||
| lockfile="${ZAF_TMP_DIR}/zaflock_${lkey}" | ||||
| lockfile="/tmp/zaflock_${lkey}" | ||||
| i=0 | ||||
| while [ -f "$lockfile" ] && [ $i -lt $seconds ]; do | ||||
| 	sleep 1 | ||||
| @@ -31,7 +28,6 @@ if [ -f "$lockfile" ] && [ -z "$force" ]; then | ||||
| 	exit 1 | ||||
| fi | ||||
|  | ||||
| touch "$lockfile" | ||||
| [ -n "$*" ] && $@ | ||||
| rm -f "$lockfile" | ||||
| [ -n "$*" ] && $@ 2>"$lockfile" | ||||
| [ -s "$lockfile" ] && zaf_wrn <"$lockfile" | ||||
|  | ||||
|   | ||||
							
								
								
									
										52
									
								
								lib/zafret
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										52
									
								
								lib/zafret
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,52 @@ | ||||
| #!/bin/sh | ||||
|  | ||||
| . $(dirname $0)/preload.sh | ||||
|  | ||||
| if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]; then | ||||
| 	zaf_err "zafret valuefile stderrfile retcode [return return_if_null return_if_error]" | ||||
| 	exit 1 | ||||
| fi | ||||
|  | ||||
| value="$(cat $1)" | ||||
| rm -f $1 | ||||
| shift | ||||
|  | ||||
| stderr="$(cat $1)" | ||||
| rm -f $1 | ||||
| shift | ||||
|  | ||||
| retcode="$1" | ||||
| shift | ||||
|  | ||||
| if [ -n "$1" ]; then | ||||
| 	ret="$1" | ||||
| 	shift | ||||
| fi | ||||
|  | ||||
| if [ -n "$1" ]; then | ||||
| 	retnull="$1" | ||||
| 	shift | ||||
| fi | ||||
|  | ||||
| if [ -n "$1" ]; then | ||||
| 	reterr="$1" | ||||
| 	shift | ||||
| fi | ||||
|  | ||||
| if [ "$retcode" != 0 ]; then | ||||
| 	echo "$reterr" | ||||
| 	zaf_wrn "${ITEM_KEY}("$*"): Error code '$retcode', returning '$reterr' ($stderr)" | ||||
| 	exit $retcode | ||||
| fi | ||||
|  | ||||
| if [ -z "$value" ]; then | ||||
| 	echo "$retnull" | ||||
| 	zaf_wrn "${ITEM_KEY}("$*"): Got empty result, returning '$retnull' ($stderr)" | ||||
| 	exit | ||||
| fi | ||||
|  | ||||
| echo $value | ||||
| if [ -n "$stderr" ]; then | ||||
| 	zaf_wrn "${ITEM_KEY}("$*"): $stderr" | ||||
| fi | ||||
|  | ||||
| @@ -1,38 +1,58 @@ | ||||
| # Call api function  | ||||
|  | ||||
| # Call api function and use cache | ||||
| # $1 - query string | ||||
| zaf_zbxapi_do() { | ||||
| 	local result | ||||
| 	local query | ||||
| 	local tmpfile | ||||
|  | ||||
| 	tmpfile=$ZAF_TMP_DIR/zapi$$ | ||||
| 	query="$1" | ||||
| 	zaf_trc "Zabbix API: $query" | ||||
| 	curl -s -f -L -X POST -H 'Content-Type: application/json-rpc' -d "$query" "$ZAF_ZBXAPI_URL" >$tmpfile | ||||
| 	if [ $? = 0 ] &&	$ZAF_LIB_DIR/JSON.sh -b <$tmpfile | grep -q '"result"'; then | ||||
| 		zaf_trc "API OK" | ||||
| 		cat $tmpfile | ||||
| 		rm -f $tmpfile | ||||
| 	else | ||||
| 		zaf_err "Error processing API request. ($?,$tmpfile)" | ||||
| 	fi | ||||
| } | ||||
| # Call api function and cache results  | ||||
| # $1 - query string | ||||
| zaf_zbxapi_do_cache() { | ||||
| 	local result | ||||
| 	local tmpfile | ||||
| 	local query | ||||
|  | ||||
| 	query="$(echo $1 | tr '\n' ' ')" | ||||
| 	tmpfile=$ZAF_TMP_DIR/zcapi$$ | ||||
| 	if ! zaf_fromcache "$1"; then | ||||
| 		zaf_trc "Zabbix API: $1" | ||||
| 		result=$(curl -s -f -L -X POST -H 'Content-Type: application/json-rpc' -d "$1" "$ZAF_ZBXAPI_URL") | ||||
| 		if [ $? = 0 ] && echo $result | grep -q '"result":'; then | ||||
| 			zaf_tocache "$1" "$result" 60		 | ||||
| 			echo $result | ||||
| 		else | ||||
| 			zaf_err "Error processing API request. ($?,$result)" | ||||
| 		fi | ||||
| 		zaf_zbxapi_do "$1" >$tmpfile | ||||
| 		[ -s "$tmpfile" ] && cat $tmpfile | zaf_tocache_stdin "$query" 60 | ||||
| 		rm -f $tmpfile | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| # Extract result from JSON response | ||||
| # Extract one result from JSON response | ||||
| zaf_zbxapi_getresult() { | ||||
| 	sed -e 's/\({"jsonrpc":"2.0","result":\)\(.*\),\("id":.*\)/\2/g' | sed -e 's/^\[\]$//' | ||||
| 	$ZAF_LIB_DIR/JSON.sh -b | grep '\["result"\]' | tr '\t' ' ' | cut -d ' ' -f 2- | ||||
| } | ||||
|  | ||||
| # Extract XML result from JSON response | ||||
| zaf_zbxapi_getxml() { | ||||
| 	zaf_zbxapi_getresult | sed -e 's/{"jsonrpc":"2.0","result":"//' | sed -e 's/","id"\:1}//' | sed -e 's#\\\([<">/]\)#\1#g' | ||||
| 	zaf_zbxapi_getstring | zaf_strunescape '</">' | zaf_far '\\n' "\n" | ||||
| } | ||||
|  | ||||
| # Extract string from JSON response result | ||||
| zaf_zbxapi_getstring() { | ||||
| 	 sed -e 's/^"//'  -e 's/"$//' -e 's/\\n/'\\n'/g' | ||||
| 	 zaf_zbxapi_getresult | sed -e 's/^"//' -e 's/"$//' | ||||
| } | ||||
|  | ||||
| # Extract value from JSON response result | ||||
| # $1 key | ||||
| zaf_zbxapi_getvalue() { | ||||
| 	 tr ',' '\n' | grep "\"$1\":" | cut -d '"' -f 4 | ||||
| zaf_zbxapi_getvalues() { | ||||
| 	 $ZAF_LIB_DIR/JSON.sh -b | grep '\["result",.*,"'$1'"]'	 | tr '\t' ' ' | cut -d ' ' -f 2- | sed -e 's/^"//' -e 's/"$//' | ||||
| } | ||||
|  | ||||
| # Zabbix API related functions | ||||
| @@ -46,143 +66,306 @@ zaf_zbxapi_login(){ | ||||
|  | ||||
|  [ -z "$ZAF_ZBXAPI_URL" ] || [ -z "$ZAF_ZBXAPI_USER" ] || [ -z "$ZAF_ZBXAPI_PASS" ] && zaf_err "Zabbix Api parameters not set! Set ZAF_ZBXAPI_URL, ZAF_ZBXAPI_USER and ZAF_ZBXAPI_PASS and try again." | ||||
|  authstr='{ | ||||
|    "method" : "user.login", | ||||
|    "params" : { | ||||
|       "password" : "'$ZAF_ZBXAPI_PASS'", | ||||
|       "user" : "'$ZAF_ZBXAPI_USER'" | ||||
|    }, | ||||
|    "id" : 0, | ||||
|    "jsonrpc" : "2.0" | ||||
| 	 "method" : "user.login", | ||||
| 	 "params" : { | ||||
| 			"password" : "'$ZAF_ZBXAPI_PASS'", | ||||
| 			"user" : "'$ZAF_ZBXAPI_USER'" | ||||
| 	 }, | ||||
| 	 "id" : 0, | ||||
| 	 "jsonrpc" : "2.0" | ||||
|  }' | ||||
|   | ||||
|  if [ "$ZAF_ZBXAPI_AUTHTYPE" = "http" ] ; then | ||||
|     ZAF_ZBXAPI_URL=$(echo $ZAF_ZBXAPI_URL | cut -d '/' -f 1)//$ZAF_ZBXAPI_USER:$ZAF_ZBXAPI_PASS@$(echo $ZAF_ZBXAPI_URL | cut -d '/' -f 3-) | ||||
| 		ZAF_ZBXAPI_URL=$(echo $ZAF_ZBXAPI_URL | cut -d '/' -f 1)//$ZAF_ZBXAPI_USER:$ZAF_ZBXAPI_PASS@$(echo $ZAF_ZBXAPI_URL | cut -d '/' -f 3-) | ||||
|  fi | ||||
|  result=$(zaf_zbxapi_do "$authstr") | ||||
|  ZAF_ZBXAPI_AUTH=$(echo $result |zaf_zbxapi_getresult| zaf_zbxapi_getstring) | ||||
|  result=$(zaf_zbxapi_do_cache "$authstr") | ||||
|  ZAF_ZBXAPI_AUTH=$(echo $result |zaf_zbxapi_getstring) | ||||
|  [ -z "$ZAF_ZBXAPI_AUTH" ] && zaf_err "Cannot login into API" | ||||
|  zaf_dbg "Logged into zabbix API ($ZAF_ZBXAPI_AUTH)" | ||||
| } | ||||
|  | ||||
| # Get object from zabbix API | ||||
| # $1 object_type | ||||
| # $2 filter | ||||
| # $3 params | ||||
| # $4 output | ||||
| # $5 id | ||||
| zaf_zbxapi_get_object() { | ||||
| 	local obj | ||||
| 	local filter | ||||
| 	local params | ||||
| 	local str | ||||
| 	local output | ||||
| 	local id | ||||
| 	local result | ||||
|  | ||||
| 	obj=$1 | ||||
| 	filter=$2 | ||||
| 	params=$3 | ||||
| 	output=$4 | ||||
| 	id=$5 | ||||
| 	[ -z "$id" ] && id=1 | ||||
| 	[ -n "$filter" ] && filter='"filter": {'$filter'},'; | ||||
| 	[ -z "$output" ] && output="shorten"; | ||||
| 	if [ -n "$params" ]; then | ||||
| 		params='"params": {'$params', '$filter' "output":"'$output'"}'; | ||||
| 	else | ||||
| 		params='"params": {'$filter' "output":"'$output'"}'; | ||||
| 	fi | ||||
| 	str='{ "method": "'$obj'.get", "jsonrpc": "2.0", "auth": "'$ZAF_ZBXAPI_AUTH'",'$params', "id": "'$id'" }' | ||||
| 	result=$(zaf_zbxapi_do_cache "$str") | ||||
| 	[ -z "$result" ] && zaf_dbg "API call result empty or error! ($str)" | ||||
| 	echo $result | ||||
| } | ||||
|  | ||||
| # $1 hostgroup name | ||||
| zaf_zbxapi_gethostgroupid() { | ||||
|  local hstr | ||||
|  local filter | ||||
|  local gfilter | ||||
|   | ||||
|  hstr='{ | ||||
|     "method": "hostgroup.get", | ||||
|     "jsonrpc": "2.0", | ||||
|     "auth": "'$ZAF_ZBXAPI_AUTH'", | ||||
|     "params": { | ||||
| 	"filter": { | ||||
| 	 "name": ["'$1'"] | ||||
| 	}, | ||||
| 	"output": "shorten" | ||||
|     }, | ||||
|     "id": 1 | ||||
|  }' | ||||
|  zaf_zbxapi_do "$hstr" | zaf_zbxapi_getresult | tr ',' '\n' | cut -d '"' -f 4 | ||||
| 	local result | ||||
|  | ||||
| 	result=$(zaf_zbxapi_get_object "hostgroup" '"name": ["'$1'"]') | ||||
| 	[ -z "$result" ] && zaf_err "HostGroup $1 not found!" | ||||
| 	echo $result |zaf_zbxapi_getvalues groupid | ||||
| } | ||||
|  | ||||
| # $1 hostid | ||||
| # $2 property or null for all | ||||
| zaf_zbxapi_gethost() { | ||||
| 	local result | ||||
|  | ||||
| 	result=$(zaf_zbxapi_get_object "host" '' '"hostids": ["'$1'"]' 'extend') | ||||
| 	[ -z "$result" ] && zaf_err "Hostid $1 not found!" | ||||
| 	if [ -z "$2" ]; then | ||||
| 		echo $result | ||||
| 	else | ||||
| 		echo $result |zaf_zbxapi_getvalues $2 | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| # $1 hostname | ||||
| zaf_zbxapi_gethostid() { | ||||
|  local hstr | ||||
|  local host | ||||
|  local groupid | ||||
|  local filter | ||||
|  local gfilter | ||||
|   | ||||
|  host="$1" | ||||
|  if [ -n "$host" ] ; then | ||||
|    filter='"filter": { "host": [ "'$host'" ] },' | ||||
|  fi | ||||
|  hstr='{ | ||||
|     "method": "host.get", | ||||
|     "jsonrpc": "2.0", | ||||
|     "auth": "'$ZAF_ZBXAPI_AUTH'", | ||||
|     "params": { | ||||
| 	'$filter' | ||||
| 	"output": "shorten" | ||||
|     }, | ||||
|     "id": 1 | ||||
|  }' | ||||
|  zaf_zbxapi_do "$hstr" | zaf_zbxapi_getresult | tr ',' '\n' | cut -d '"' -f 4 | ||||
| 	local result | ||||
|  | ||||
| 	result=$(zaf_zbxapi_get_object "host" '"host": ["'$1'"]') | ||||
| 	[ -z "$result" ] && zaf_err "Host $1 not found!" | ||||
| 	echo $result |zaf_zbxapi_getvalues hostid | ||||
| } | ||||
|  | ||||
| # $1 hostid | ||||
| zaf_zbxapi_gethost() { | ||||
|  local hstr | ||||
|  local host | ||||
|  local groupid | ||||
|  local filter | ||||
|  local gfilter | ||||
|   | ||||
|  hostid="$1" | ||||
|  if [ -n "$hostid" ] ; then | ||||
|    filter='"hostids": [ "'$hostid'" ],' | ||||
|  fi | ||||
|  hstr='{ | ||||
|     "method": "host.get", | ||||
|     "jsonrpc": "2.0", | ||||
|     "auth": "'$ZAF_ZBXAPI_AUTH'", | ||||
|     "params": { | ||||
| 	'$filter' | ||||
| 	"output": "extend" | ||||
|     }, | ||||
|     "id": 1 | ||||
|  }' | ||||
|  zaf_zbxapi_do "$hstr" | zaf_zbxapi_getresult | zaf_zbxapi_getvalue host | ||||
| # $1 hostname | ||||
| # $2 inv field or empty for json | ||||
| zaf_zbxapi_gethostinventory() { | ||||
| 	local result | ||||
|  | ||||
| 	result=$(zaf_zbxapi_get_object "host" '"host": ["'$1'"]' '"withInventory": "true", "selectInventory": "extend"') | ||||
| 	[ -z "$result" ] && zaf_err "Host $1 not found!" | ||||
| 	if [ -z "$2" ]; then | ||||
| 		echo $result  | ||||
| 	else | ||||
| 		echo $result |zaf_zbxapi_getvalues $2 | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| # $1 hostgroupid | ||||
| # $1 hostname | ||||
| zaf_zbxapi_gettemplateid() { | ||||
| 	local result | ||||
|  | ||||
| 	result=$(zaf_zbxapi_get_object "template" '"host": ["'$1'"]') | ||||
| 	[ -z "$result" ] && zaf_err "Template $1 not found!" | ||||
| 	echo $result |zaf_zbxapi_getvalues templateid | ||||
| } | ||||
|  | ||||
| # $1 templateid | ||||
| # $2 property or null for all | ||||
| zaf_zbxapi_gettemplate() { | ||||
| 	local result | ||||
|  | ||||
| 	result=$(zaf_zbxapi_get_object "template" '' '"templateids": ["'$1'"]' 'extend') | ||||
| 	[ -z "$result" ] && zaf_err "Templateid $1 not found!" | ||||
| 	if [ -z "$2" ]; then | ||||
| 		echo $result | ||||
| 	else | ||||
| 		echo $result |zaf_zbxapi_getvalues $2 | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| # $1 hostgroupid  | ||||
| zaf_zbxapi_gethostsingroup() { | ||||
|  local hstr | ||||
|  local host | ||||
|  local groupid | ||||
|  local filter | ||||
|  local gfilter | ||||
| 	local result | ||||
|  | ||||
|  groupid="$1" | ||||
|  if [ -n "$groupid" ]; then | ||||
|    gfilter='"groupids": [ "'$groupid'" ],' | ||||
|  fi | ||||
|  | ||||
|  hstr='{ | ||||
|     "method": "host.get", | ||||
|     "jsonrpc": "2.0", | ||||
|     "auth": "'$ZAF_ZBXAPI_AUTH'", | ||||
|     "params": { | ||||
| 	'$gfilter' | ||||
| 	'$filter' | ||||
| 	"output": "shorten" | ||||
|     }, | ||||
|     "id": 1 | ||||
|  }' | ||||
|  zaf_zbxapi_do "$hstr" | zaf_zbxapi_getresult | tr ',' '\n' | cut -d '"' -f 4 | ||||
| 	result=$(zaf_zbxapi_get_object "host" '' '"groupids": ["'$1'"]') | ||||
| 	[ -z "$result" ] && zaf_wrn "No hosts in groupid '$1'" | ||||
| 	echo $result | zaf_zbxapi_getvalues "hostid" | ||||
| } | ||||
|  | ||||
| # Get all hostids in system | ||||
| zaf_zbxapi_gethostids() { | ||||
| 	local result | ||||
|  | ||||
| 	result=$(zaf_zbxapi_get_object "host") | ||||
| 	echo $result | zaf_zbxapi_getvalues "hostid" | ||||
| } | ||||
|  | ||||
| # Get all templateids in system | ||||
| zaf_zbxapi_gettemplateids() { | ||||
| 	local result | ||||
|  | ||||
| 	result=$(zaf_zbxapi_get_object "template") | ||||
| 	echo $result | zaf_zbxapi_getvalues "templateid" | ||||
| } | ||||
|  | ||||
| # $1 hostgroupid  | ||||
| zaf_zbxapi_gettemplatesingroup() { | ||||
| 	local result | ||||
|  | ||||
| 	result=$(zaf_zbxapi_get_object "template" '' '"groupids": ["'$1'"]') | ||||
| 	[ -z "$result" ] && zaf_wrn "No templates in groupid '$1'" | ||||
| 	echo $result | zaf_zbxapi_getvalues "templateid" | ||||
| } | ||||
|  | ||||
| # $1 map or null for all | ||||
| zaf_zbxapi_getmapid() { | ||||
| 	local result | ||||
|  | ||||
| 	if [ -n "$1" ]; then | ||||
| 		result=$(zaf_zbxapi_get_object "map" '"name": ["'$1'"]') | ||||
| 	else | ||||
| 		result=$(zaf_zbxapi_get_object "map") | ||||
| 	fi | ||||
| 	[ -z "$result" ] && zaf_err "Map $1 not found" | ||||
| 	echo $result | zaf_zbxapi_getvalues "sysmapid" | ||||
| } | ||||
|  | ||||
| # $1 mapid | ||||
| # $2 property or null for all | ||||
| zaf_zbxapi_getmap() { | ||||
| 	local result | ||||
|  | ||||
| 	result=$(zaf_zbxapi_get_object "map" '' '"sysmapids": ["'$1'"]' 'extend') | ||||
| 	[ -z "$result" ] && zaf_err "Mapid $1 not found" | ||||
| 	if [ -z "$2" ]; then | ||||
| 		echo $result | ||||
| 	else | ||||
| 		echo $result |zaf_zbxapi_getvalues $2 | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| # Object backup | ||||
| # $1 object | ||||
| # $2 id | ||||
| zaf_zbxapi_export_object(){ | ||||
|  local bkpstr | ||||
|  local obj | ||||
|  local id | ||||
|   | ||||
|  obj="$1" | ||||
|  id="$2" | ||||
|  | ||||
|  bkpstr=' | ||||
|  { | ||||
| 		"method": "configuration.export", | ||||
| 		"jsonrpc": "2.0", | ||||
| 		"params": { | ||||
| 				"options": { | ||||
| 						"'$obj'": [ | ||||
| 								"'$id'" | ||||
| 						] | ||||
| 				}, | ||||
| 				"format": "xml" | ||||
| 		}, | ||||
| 		"auth": "'$ZAF_ZBXAPI_AUTH'", | ||||
| 		"id": 1 | ||||
| }' | ||||
|  zaf_zbxapi_do_cache "$bkpstr" | zaf_zbxapi_getxml | ||||
| } | ||||
|  | ||||
|  | ||||
| # Host backup | ||||
| # $1 hostid | ||||
| zaf_zbxapi_backuphost(){ | ||||
|  local bkpstr | ||||
|   | ||||
|  host="$1" | ||||
|  bkpstr=' | ||||
| zaf_zbxapi_export_host(){ | ||||
|  zaf_zbxapi_export_object hosts "$1" | ||||
| } | ||||
|  | ||||
| # Template backup | ||||
| # $1 templateid | ||||
| zaf_zbxapi_export_template(){ | ||||
|  zaf_zbxapi_export_object templates "$1" | ||||
| } | ||||
|  | ||||
| # Map backup | ||||
| # $1 mapid | ||||
| zaf_zbxapi_export_map(){ | ||||
|  zaf_zbxapi_export_object maps "$1" | ||||
| } | ||||
|  | ||||
| # Import template into zabbix | ||||
| # $1 template file or stdin | ||||
| zaf_zbxapi_import_config(){ | ||||
|  local xmlstr | ||||
|  local impstr | ||||
|  | ||||
|  if [ -z "$1" ]; then | ||||
| 	 xmlstr=$(zaf_strescape '"') | ||||
|  else | ||||
| 	 ! [ -f "$1" ] && return 1 | ||||
| 	 xmlstr=$(zaf_strescape '"\n\r' <$1) | ||||
|  fi | ||||
|  impstr=' | ||||
|  { | ||||
|     "method": "configuration.export", | ||||
|     "jsonrpc": "2.0", | ||||
|     "params": { | ||||
|         "options": { | ||||
|             "hosts": [ | ||||
|                 "'$host'" | ||||
|             ] | ||||
|         }, | ||||
|         "format": "xml" | ||||
|     }, | ||||
|     "auth": "'$ZAF_ZBXAPI_AUTH'", | ||||
|     "id": 1 | ||||
| 		"method": "configuration.import", | ||||
| 		"jsonrpc": "2.0", | ||||
| 		"params": { | ||||
| 				"format": "xml", | ||||
| 				"rules": { | ||||
| 			"applications": { | ||||
| 								"createMissing": true, | ||||
| 								"updateExisting": true | ||||
| 						}, | ||||
| 						"discoveryRules": { | ||||
| 								"createMissing": true, | ||||
| 								"updateExisting": true | ||||
| 						}, | ||||
| 			"graphs": { | ||||
| 								"createMissing": true, | ||||
| 								"updateExisting": true | ||||
| 						}, | ||||
| 						"hosts": { | ||||
| 								"createMissing": true, | ||||
| 								"updateExisting": true | ||||
| 						}, | ||||
| 						"items": { | ||||
| 								"createMissing": true, | ||||
| 								"updateExisting": true | ||||
| 						}, | ||||
| 			"templates": { | ||||
| 								"createMissing": true, | ||||
| 								"updateExisting": true | ||||
| 						}, | ||||
| 						"triggers": { | ||||
| 								"createMissing": true, | ||||
| 								"updateExisting": true | ||||
| 						}, | ||||
| 			"maps": { | ||||
| 								"createMissing": true, | ||||
| 								"updateExisting": true | ||||
| 						}, | ||||
| 			"screens": { | ||||
| 								"createMissing": true, | ||||
| 								"updateExisting": true | ||||
| 						}, | ||||
| 						"items": { | ||||
| 								"createMissing": true, | ||||
| 								"updateExisting": true | ||||
| 						}, | ||||
| 			"valueMaps": { | ||||
| 								"createMissing": true, | ||||
| 								"updateExisting": true | ||||
| 						} | ||||
| 				}, | ||||
| 	"source": "'$xmlstr'" | ||||
| 		}, | ||||
| 		"auth": "'$ZAF_ZBXAPI_AUTH'", | ||||
| 		"id": 3 | ||||
| }' | ||||
|  zaf_zbxapi_do "$bkpstr" | zaf_zbxapi_getxml | ||||
|  zaf_zbxapi_do "$impstr" | zaf_zbxapi_getresult | grep -q true | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
							
								
								
									
										10
									
								
								rpm.mk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								rpm.mk
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| # Makefile for generating rpm packages | ||||
| # Contrinutions welcome :) | ||||
|  | ||||
| ifeq ($(RPM_PKG),) | ||||
|  RPM_PKG=$(shell . lib/zaf.lib.sh; echo out/zaf-$$ZAF_VERSION.rpm) | ||||
| endif | ||||
|  | ||||
| $(RPM_PKG): | ||||
| 	@echo "Not supported yet. Contributions welcomed! :) "; exit 2 | ||||
|  | ||||
							
								
								
									
										32
									
								
								tgz.mk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								tgz.mk
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
|  | ||||
| TGZ_DIR=tmp/tgz | ||||
|  | ||||
| ifeq ($(TGZ_PKG),) | ||||
|  TGZ_PKG=$(shell . lib/zaf.lib.sh; echo out/zaf-$$ZAF_VERSION.tgz) | ||||
| endif | ||||
|  | ||||
| $(TGZ_PKG):	clean tgz-init tgz-deps tgz-control tgz-scripts tgz-cp tgz-package | ||||
|  | ||||
| tgz-init: | ||||
| 	@mkdir -p $(TGZ_DIR) | ||||
|  | ||||
| tgz-deps:  | ||||
| tgz-control: | ||||
| tgz-scripts: | ||||
| tgz-cp: | ||||
| 	@mkdir -p $(TGZ_DIR) | ||||
| 	@set -e; INSTALL_PREFIX=$(TGZ_DIR) ZAF_tgzUG=$(ZAF_tgzUG) ./install.sh auto $(ZAF_OPTIONS) ZAF_PLUGINS="$(ZAF_PLUGINS)" $(AGENT_OPTIONS) | ||||
| 	@cat lib/*lib.sh install.sh >$(TGZ_DIR)/usr/lib/zaf/install.sh | ||||
| 	@chmod +x $(TGZ_DIR)/usr/lib/zaf/install.sh | ||||
| 	@rm -rf $(TGZ_DIR)/tmp | ||||
| 	@cp $(TGZ_DIR)/etc/zaf.conf tmp/zaf.conf | ||||
| 	@grep -E "$$(echo $(ZAF_EXPORT_OPTS) | tr ' ' '|')=" tmp/zaf.conf  >$(TGZ_DIR)/etc/zaf.conf | ||||
| ifneq ($(AGENT_OPTIONS),) | ||||
| 	@echo "ZAF_AGENT_OPTIONS=\"$(AGENT_OPTIONS)\"" >>$(TGZ_DIR)/etc/zaf.conf | ||||
| endif | ||||
|  | ||||
| tgz-package: | ||||
| 	@tar -czf $(TGZ_PKG) -C $(TGZ_DIR) .  | ||||
| 	@echo PLUGINS embedded: $(ZAF_PLUGINS) | ||||
| 	@echo Result: $(TGZ_PKG) | ||||
|  | ||||
							
								
								
									
										474
									
								
								zaf
									
									
									
									
									
								
							
							
						
						
									
										474
									
								
								zaf
									
									
									
									
									
								
							| @@ -11,39 +11,31 @@ ZAF_CFG_FILE="/etc/zaf.conf" | ||||
|  | ||||
| 	# Read options as config for ZAF | ||||
| 	for pair in "$@"; do | ||||
|     		if echo $pair | grep -qE '^ZAF\_(.*)='; then | ||||
|     			option=$(echo $pair|cut -d '=' -f 1) | ||||
|     			value=$(echo $pair|cut -d '=' -f 2-) | ||||
|     			eval "${option}='$value'" | ||||
| 			if echo $pair | grep -qE '^ZAF\_(.*)='; then | ||||
| 				option=$(echo $pair|cut -d '=' -f 1) | ||||
| 				value=$(echo $pair|cut -d '=' -f 2-) | ||||
| 				eval "${option}='$value'" | ||||
| 			export secondstage=1 | ||||
|     		else | ||||
| 			else | ||||
| 			params="$params $pair" | ||||
|     		fi | ||||
| 			fi | ||||
| 	done | ||||
| 	export $(set |grep ^ZAF_ | cut -d '=' -f 1) | ||||
| 	# If some variables in cmd were stripped, rerun only with right arguments and exported variables | ||||
| 	[ -n "$secondstage" ] && exec $0 $params | ||||
| fi | ||||
|  | ||||
| [ -z "$ZAF_TMP_BASE" ] && ZAF_TMP_BASE=/tmp/zaf | ||||
| ZAF_TMP_DIR="${ZAF_TMP_BASE}-${USER}" | ||||
| [ -z "$ZAF_CACHE_DIR" ] && ZAF_CACHE_DIR=${ZAF_TMP_BASE}c | ||||
| export ZAF_BIN=$(realpath $0) | ||||
|  | ||||
| [ -z "$ZAF_DEBUG" ] && ZAF_DEBUG=1 | ||||
| export ZAF_DEBUG | ||||
|  | ||||
| # If debug is on, do not remove tmp dir  | ||||
| if [ "$ZAF_DEBUG" -le 3 ]; then | ||||
| 	trap "rm -rif ${ZAF_TMP_DIR}" EXIT | ||||
| fi | ||||
|  | ||||
| ! [ -d "${ZAF_TMP_DIR}" ] && mkdir "${ZAF_TMP_DIR}" | ||||
| if ! [ -d "${ZAF_CACHE_DIR}" ]; then | ||||
| 	mkdir "${ZAF_CACHE_DIR}" | ||||
| if [ -n "$ZAF_PROXY" ]; then | ||||
| 	export ALL_PROXY="$ZAF_PROXY" | ||||
| 	export http_proxy="$ZAF_PROXY" | ||||
| 	export https_proxy="$ZAF_PROXY" | ||||
| fi | ||||
|  | ||||
| if [ -f ./lib/zaf.lib.sh ]; then | ||||
| . ./lib/zaf.lib.sh | ||||
| . ./lib/plugin.lib.sh | ||||
| . ./lib/os.lib.sh | ||||
| . ./lib/ctrl.lib.sh | ||||
| . ./lib/cache.lib.sh | ||||
| @@ -51,6 +43,7 @@ if [ -f ./lib/zaf.lib.sh ]; then | ||||
| [ -f ./lib/zaf.${ZAF_OS}.sh ] && . ./lib/zaf.${ZAF_OS}.sh | ||||
| else  | ||||
| . ${ZAF_LIB_DIR}/zaf.lib.sh | ||||
| . ${ZAF_LIB_DIR}/plugin.lib.sh | ||||
| . ${ZAF_LIB_DIR}/os.lib.sh | ||||
| . ${ZAF_LIB_DIR}/ctrl.lib.sh | ||||
| . ${ZAF_LIB_DIR}/cache.lib.sh | ||||
| @@ -58,39 +51,71 @@ else | ||||
| [ -f ${ZAF_LIB_DIR}/zaf.${ZAF_OS}.sh ] && . ${ZAF_LIB_DIR}/zaf.${ZAF_OS}.sh | ||||
| fi | ||||
|  | ||||
| if zaf_is_root; then | ||||
| 	chgrp zabbix "${ZAF_CACHE_DIR}" | ||||
| 	chmod g+w "${ZAF_CACHE_DIR}" | ||||
| fi | ||||
| zaf_debug_init stderr | ||||
| zaf_tmp_init | ||||
| zaf_cache_init | ||||
|  | ||||
| case $1 in | ||||
|  | ||||
| check-agent-config) | ||||
| 	zaf_check_agent_config | ||||
| 	;; | ||||
|  | ||||
| cache-clean) | ||||
| 	zaf_cache_clean | ||||
| 	;; | ||||
| cache-list) | ||||
| 	zaf_cache_list | ||||
| 	;; | ||||
| cache-test1) | ||||
| 	for i in test1 test2 test3; do | ||||
| 		echo "To cache:" | ||||
| 		echo "$i" | zaf_tocache_stdin "test" 10 | ||||
| 	done | ||||
| 	;; | ||||
| cache-test2) | ||||
| 	for i in test1 test2 test3; do | ||||
| 		echo "From cache:" | ||||
| 		zaf_fromcache "test" | ||||
| 	done | ||||
| 	;; | ||||
|  | ||||
| version) | ||||
| 	echo "$ZAF_VERSION<git $ZAF_GITBRANCH>" | ||||
| 	[ $ZAF_DEBUG -gt 1 ] && set |grep -E ^ZAF_  | ||||
| 	;; | ||||
|  | ||||
|  | ||||
| ###### Agent related commands | ||||
| userparms) | ||||
| 	for plugin in $(zaf_list_plugins); do | ||||
| 		plugindir=$ZAF_PLUGINS_DIR/$plugin | ||||
| 		control=$plugindir/control.zaf | ||||
| 		zaf_ctrl_generate_cfg "${control}" "${plugin}" \ | ||||
| 			  | zaf_far '{PLUGINDIR}' "${plugindir}" | ||||
| 		zaf_ctrl_generate_items_cfg "${control}" "${plugin}" "noscripts" \ | ||||
| 		 | zaf_far '{PLUGINDIR}' "${plugindir}" | ||||
| 	done | ||||
| 	;; | ||||
|  | ||||
| agent-config) | ||||
| 	[ -n "$2" ] && force=yes | ||||
| 	for p in $(zaf_list_plugins); do | ||||
| 		if [ -f "$ZAF_PLUGINS_DIR/$p/postinst.need" ]; then | ||||
| 			zaf_wrn "Calling postinstalation of plugin $p" | ||||
| 			zaf_postinstall_plugin $p && rm -f "$ZAF_PLUGINS_DIR/$p/postinst.need" | ||||
| 			force=yes | ||||
| 		fi | ||||
| 	done | ||||
| 	zaf_wrn "Generating config files in $ZAF_AGENT_CONFIGD ..." | ||||
| 	for plugin in $(zaf_list_plugins); do | ||||
| 		plugindir=$ZAF_PLUGINS_DIR/$plugin | ||||
| 		control=$plugindir/control.zaf | ||||
| 		zaf_ctrl_generate_cfg "${control}" "${plugin}" \ | ||||
| 			  | zaf_far '{PLUGINDIR}' "${plugindir}" >${ZAF_AGENT_CONFIGD}/zaf_${plugin}.conf | ||||
| 		if ! [ -f "${ZAF_AGENT_CONFIGD}/zaf_${plugin}.conf" ] || [ "$control" -nt "${ZAF_AGENT_CONFIGD}/zaf_${plugin}.conf" ] || [ -n "$force" ]; then | ||||
| 			zaf_dbg "Generating ${ZAF_AGENT_CONFIGD}/zaf_${plugin}.conf" | ||||
| 			zaf_ctrl_generate_items_cfg "${control}" "${plugin}" \ | ||||
| 			 | zaf_far '{PLUGINDIR}' "${plugindir}" >${ZAF_AGENT_CONFIGD}/zaf_${plugin}.conf | ||||
| 		fi | ||||
| 	done | ||||
| 	;; | ||||
| server-config) | ||||
| 	zaf_wrn "Not implemented yet" | ||||
| 	;; | ||||
|  | ||||
| ###### Plugins related commands | ||||
| update) | ||||
| 	zaf_wrn "Updating repository ${ZAF_REPO_GITURL}..." | ||||
| 	zaf_update_repo | ||||
| @@ -105,23 +130,25 @@ show) | ||||
| 			zaf_plugin_info $ZAF_PLUGINS_DIR/$plugin/control.zaf | ||||
| 		done | ||||
| 	else | ||||
| 		if zaf_list_plugins | grep -q "^$1"; then | ||||
| 			[ -f $ZAF_PLUGINS_DIR/$1/control.zaf ] && zaf_plugin_info $ZAF_PLUGINS_DIR/$1/control.zaf || zaf_err "Plugin $1 not installed." | ||||
| 		else | ||||
| 			if echo $1 |grep -q ^http; then | ||||
| 				zaf_prepare_plugin "$1" "$ZAF_TMP_DIR/plugin" | ||||
| 				zaf_plugin_info "$ZAF_TMP_DIR/plugin/control.zaf" | ||||
| 		if echo $1 | grep -vq "\."; then | ||||
| 			if zaf_list_plugins | grep -q "^$1"; then | ||||
| 				zaf_is_plugin $1 && zaf_plugin_info $ZAF_PLUGINS_DIR/$1/control.zaf || zaf_err "Plugin $1 not installed." | ||||
| 			else | ||||
| 				zaf_err "Plugin $1 not installed." | ||||
| 				if echo $1 |grep -q ^http; then | ||||
| 					zaf_prepare_plugin "$1" "$ZAF_TMP_DIR/plugin" | ||||
| 					zaf_plugin_info "$ZAF_TMP_DIR/plugin/control.zaf" | ||||
| 				else | ||||
| 					zaf_err "Plugin $1 not installed." | ||||
| 				fi | ||||
| 			fi | ||||
| 		else | ||||
| 			zaf_item_info "$1" | ||||
| 		fi | ||||
| 	fi | ||||
| 	;; | ||||
|  | ||||
| plugins) | ||||
| 	zaf_list_plugins | ||||
| 	;; | ||||
|  | ||||
| items) | ||||
| 	shift | ||||
| 	if [ -z "$1" ]; then | ||||
| @@ -130,7 +157,6 @@ items) | ||||
| 		zaf_list_plugin_items "$1" | ||||
| 	fi | ||||
| 	;; | ||||
|  | ||||
| test) | ||||
| 	[ "$USER" != "zabbix" ] && zaf_wrn "You are not zabbix user. Test will be run with your privileges and sudo access!" | ||||
| 	shift | ||||
| @@ -146,14 +172,40 @@ test) | ||||
| 	for p in $plugins; do | ||||
| 		! zaf_is_plugin $p && zaf_err "Unknown plugin $p" | ||||
| 		for i in $(zaf_list_plugin_items $p test); do  | ||||
| 			echo $i: $(zaf_test_item $i) | ||||
| 			zaf_test_item $i | ||||
| 			echo | ||||
| 		done | ||||
| 	done | ||||
| 	;; | ||||
| itemsh) | ||||
| 	shift | ||||
| 	if zaf_is_item "$1"; then | ||||
| 		plugin=$(zaf_get_plugin_name "$1") | ||||
| 		item=$(zaf_get_item_name "$1") | ||||
| 		params=$(zaf_get_item_params "$1") | ||||
| 		params2=$(zaf_paramstosh "[$params]") | ||||
| 		script=$(zaf_ctrl_generate_items_cfg "${ZAF_PLUGINS_DIR}/${plugin}/control.zaf" "${plugin}" "" "sh -i #"| grep "UserParameter=$plugin.$item" | cut -d ',' -f 2-) | ||||
| 		exec sh -c "$script" dummy $params2 | ||||
| 	else | ||||
| 		zaf_err "No such plugin/item $1" | ||||
| 	fi | ||||
| 	;; | ||||
| run) | ||||
| 	shift | ||||
| 	if zaf_is_item "$1"; then | ||||
| 		plugin=$(zaf_get_plugin_name "$1") | ||||
| 		item=$(zaf_get_item_name "$1") | ||||
| 		params=$(zaf_get_item_params "$1") | ||||
| 		params2=$(zaf_paramstosh "[$params]") | ||||
| 		script=$(zaf_ctrl_generate_items_cfg "${ZAF_PLUGINS_DIR}/${plugin}/control.zaf" "${plugin}" | grep "UserParameter=$plugin.$item" | cut -d ',' -f 2-) | ||||
| 		exec sh -c "$script" dummy $params2 | ||||
| 	else | ||||
| 		zaf_err "No such plugin/item $1" | ||||
| 	fi | ||||
| 	;; | ||||
| get) | ||||
| 	shift | ||||
| 	if echo $1|grep -q '\.'; then | ||||
| 	if zaf_is_item "$1"; then | ||||
| 		zaf_get_item "$1" | ||||
| 		exit | ||||
| 	fi | ||||
| @@ -169,7 +221,65 @@ get) | ||||
| 		done | ||||
| 	done | ||||
| 	;; | ||||
| send) | ||||
| 	shift | ||||
| 	if [ -z "$1" ]; then | ||||
| 		# No parameters - pipe to zabbix_sender | ||||
| 		zaf_dbg "Waiting for data on stdin (host item value) per line" | ||||
| 		zscmd="zabbix_sender -z '$ZAF_ZBXSRV_HOST' -p '$ZAF_ZBXSRV_PORT' -i -" | ||||
| 		zaf_dbg $zscmd | ||||
| 		eval $zscmd | ||||
| 		exit | ||||
| 	else | ||||
| 		if [ -n "$2" ]; then | ||||
| 			# Hostname as parameter - rerun with right hostname set | ||||
| 			exec $0 send "$2" "$3" ZAF_HOSTNAME="$1" | ||||
| 		else | ||||
| 			if echo "$1" | grep -q ':'; then | ||||
| 				# Hostname:item - rerun with right hostname set | ||||
| 				exec $0 send "$(echo $1 |cut -d ':' -f 2-)" "$3" ZAF_HOSTNAME="$(echo $1 |cut -d ':' -f 1)" | ||||
| 			fi | ||||
| 			if zaf_is_item "$1"; then | ||||
| 				# Item supported by zaf | ||||
| 				plugin=$(zaf_get_plugin_name "$1") | ||||
| 				item=$(zaf_get_item_name "$1") | ||||
| 				zscmd="zabbix_sender -z '$ZAF_ZBXSRV_HOST' -p '$ZAF_ZBXSRV_PORT' -s '$(zaf_hostname)' -k '$plugin.$item' -o '$(zaf_run_item $1)'" | ||||
| 				zaf_dbg $zscmd | ||||
| 				eval $zscmd | ||||
| 				exit | ||||
| 			else | ||||
| 				if echo $1 | grep -q '='; then | ||||
| 					item=$(echo $1 | cut -d '=' -f 1) | ||||
| 					value=$(echo $1 | cut -d '=' -f 2-) | ||||
| 				else | ||||
| 					item=$1 | ||||
| 					zaf_dbg "Waiting for value of $(zaf_hostname):$1 on stdin" | ||||
| 					value=$(cat) | ||||
| 				fi | ||||
| 				zscmd="zabbix_sender -z '$ZAF_ZBXSRV_HOST' -p '$ZAF_ZBXSRV_PORT' -s '$(zaf_hostname)' -k '$item' -o '$value'" | ||||
| 				zaf_dbg $zscmd | ||||
| 				eval $zscmd | ||||
| 				exit | ||||
| 			fi			 | ||||
| 		fi | ||||
| 	fi | ||||
| 	;; | ||||
| register) | ||||
| 	shift | ||||
| 	if [ -z "$1" ]; then | ||||
| 		hostname=$(zaf_hostname) | ||||
| 	else | ||||
| 		hostname="$1" | ||||
| 		if [ -z "$2" ]; then | ||||
| 			metadata="ZAF" | ||||
| 		else | ||||
| 			metadata="$2" | ||||
| 		fi | ||||
|  | ||||
| 	fi | ||||
| 	zaf_register "$hostname" "$metadata" | ||||
| 	exit; | ||||
| 	;; | ||||
| precache) | ||||
| 	shift | ||||
| 	for i in $*; do | ||||
| @@ -186,7 +296,6 @@ precache) | ||||
| 		fi | ||||
| 	done | ||||
| 	;; | ||||
|  | ||||
| install) | ||||
| 	shift | ||||
| 	[ -z "$1" ] && echo "$0 install plugin [plugin]..." | ||||
| @@ -200,13 +309,17 @@ install) | ||||
| 	done | ||||
| 	[ -n "$installed" ] && zaf_is_root && zaf_restart_agent | ||||
| 	;; | ||||
|  | ||||
| reinstall) | ||||
| 	shift | ||||
| 	[ -z "$1" ] && echo "$0 reinstall plugin [plugin]..." | ||||
| 	for p in $@; do | ||||
| 		if zaf_is_plugin "$p"; then | ||||
| 			zaf_remove_plugin "$(basename $p)" | ||||
| 			params=$(zaf_get_plugin_parameters $p) | ||||
| 			for param in $params; do  | ||||
| 				eval export ZAF_${p}_${param}=$(zaf_get_plugin_parameter "${ZAF_PLUGINS_DIR}/${p}" $param) | ||||
| 				zaf_dbg "Saving ZAF_${p}_${param}" | ||||
| 			done | ||||
| 			zaf_remove_plugin "$p" | ||||
| 			reinstalled=1 | ||||
| 		fi | ||||
| 		zaf_install_plugin "$p" | ||||
| @@ -214,8 +327,7 @@ reinstall) | ||||
| 	done | ||||
| 	[ -n "$reinstalled" ] && zaf_is_root && zaf_restart_agent | ||||
| 	;; | ||||
|  | ||||
| remove) | ||||
| remove|uninstall) | ||||
| 	shift | ||||
| 	[ -z "$1" ] && echo "$0 remove plugin [plugin]..." | ||||
| 	for p in $@; do | ||||
| @@ -226,112 +338,256 @@ remove) | ||||
| 	done | ||||
| 	[ -n "$removed" ] && zaf_is_root && zaf_restart_agent | ||||
| 	;; | ||||
| plugin-set) | ||||
| 	plugin="$2" | ||||
| 	param="$3" | ||||
| 	value="$4" | ||||
| 	if [ -z "$plugin" ] || [ -z "$param" ]; then | ||||
| 		zaf_err "$0 plugin-set plugin parameter value" | ||||
| 	else | ||||
| 		if zaf_is_plugin "$plugin"; then | ||||
| 			plugindir="${ZAF_PLUGINS_DIR}/${plugin}" | ||||
| 			zaf_set_plugin_parameter "$plugindir" "$param" "$value" | ||||
| 		else | ||||
| 			zaf_err "Plugin $plugin is not installed." | ||||
| 		fi | ||||
| 	fi  | ||||
| 	;; | ||||
|  | ||||
| ###### Zaf related commands | ||||
| self-upgrade) | ||||
| 	shift | ||||
| 	[ -z "$1" ] && auto=auto | ||||
| 	zaf_os_specific zaf_check_deps zaf && zaf_err "Zaf is installed as system package. Cannot self-upgrade." | ||||
| 	rm -rf /tmp/zaf-installer && mkdir /tmp/zaf-installer | ||||
| 	if ! which curl >/dev/null; | ||||
| 	if ! zaf_which curl >/dev/null; | ||||
| 	then | ||||
| 		zaf_err "Curl not found. Cannot continue. Please install it." | ||||
| 	fi | ||||
| 	zaf_fetch_url $ZAF_RAW_URL/$ZAF_GITBRANCH/install.sh | exec sh -s $auto "$@" | ||||
| 	exit | ||||
| 	;; | ||||
| 	 | ||||
| self-remove) | ||||
| 	shift | ||||
| 	zaf_os_specific zaf_check_deps zaf && zaf_err "Zaf is installed as system package. Cannot self-remove." | ||||
| 	. /etc/zaf.conf | ||||
| 	if [ "$1" = "force" ]; then | ||||
| 	  rm -rf /etc/zaf.conf ${ZAF_PLUGINS_DIR} ${ZAF_REPO_DIR} ${ZAF_LIB_DIR} \ | ||||
| 		${ZAF_BIN_DIR}/zaf ${ZAF_AGENT_CONFIGD}/zaf_* | ||||
| 		rm -rf /etc/zaf.conf ${ZAF_PLUGINS_DIR} ${ZAF_REPO_DIR} ${ZAF_LIB_DIR} \ | ||||
| 		 ${ZAF_BIN_DIR}/zaf ${ZAF_AGENT_CONFIGD}/zaf_* | ||||
| 	else | ||||
| 	  echo "This will remove zaf from this computer and erase all configuration." | ||||
| 	  echo "This command will be executed:" | ||||
| 	  echo "rm -rf /etc/zaf.conf ${ZAF_PLUGINS_DIR} ${ZAF_REPO_DIR} ${ZAF_LIB_DIR} \ | ||||
| 		echo "This will remove zaf from this computer and erase all configuration." | ||||
| 		echo "This command will be executed:" | ||||
| 		echo "rm -rf /etc/zaf.conf ${ZAF_PLUGINS_DIR} ${ZAF_REPO_DIR} ${ZAF_LIB_DIR} \ | ||||
| 		${ZAF_BIN_DIR}/zaf ${ZAF_AGENT_CONFIGD}/zaf_*" | ||||
| 	  echo  | ||||
| 	  echo "To continue, please do $0 self-remove force" | ||||
| 		echo  | ||||
| 		echo "To continue, please do $0 self-remove force" | ||||
| 	fi | ||||
|       	;; | ||||
| 	;; | ||||
|  | ||||
| ###### API related commands | ||||
| api) | ||||
| 	zaf_zbxapi_login | ||||
| 	case $2 in | ||||
| 	hostid) | ||||
| 		zaf_zbxapi_gethostid "$3" | ||||
| 	get-*-id) | ||||
| 		obj=$(echo $2|cut -d '-' -f 2) | ||||
| 		[ -z "$3" ] && zaf_err "$0 $1 $2 <$obj>" | ||||
| 		eval zaf_zbxapi_get${obj}id "$3" | ||||
| 		;; | ||||
| 	host) | ||||
| 		zaf_zbxapi_gethost "$3" | ||||
| 		;;	 | ||||
| 	hostgroupid) | ||||
| 		zaf_zbxapi_gethostgroupid "$3" | ||||
| 		;;	 | ||||
| 	hosts) | ||||
| 		gid=$(zaf_zbxapi_gethostgroupid "$3") | ||||
| 		zaf_zbxapi_gethostsingroup $gid | ||||
| 	get-byid-*|get-id-*) | ||||
| 		obj=$(echo $2|cut -d '-' -f 3) | ||||
| 		[ -z "$3" ] && zaf_err "$0 $1 $2 <id>" | ||||
| 		eval zaf_zbxapi_get${obj} "$3" "$4" | ||||
| 		;; | ||||
| 	backup-group) | ||||
| 	get-host-ids) | ||||
| 		if [ -n "$3" ]; then | ||||
| 			gid=$(zaf_zbxapi_gethostgroupid "$3") || exit 1 | ||||
| 			zaf_dbg "Selecting all hosts in group $3($gid)" | ||||
| 			zaf_zbxapi_gethostsingroup $gid | ||||
| 		else | ||||
| 			zaf_dbg "Selecting all hosts in system" | ||||
| 			zaf_zbxapi_gethostids | ||||
| 		fi | ||||
| 		;; | ||||
| 	get-inventory) | ||||
| 		[ -z "$3" ] && zaf_err "$0 $1 field [host]. If host unspecified, use hostname" | ||||
| 		if [ -z "$4" ]; then | ||||
| 			host=$(hostname) | ||||
| 		else | ||||
| 			host="$4" | ||||
| 		fi | ||||
| 		zaf_zbxapi_gethostinventory $host $3 | ||||
| 		;; | ||||
| 	get-template-ids) | ||||
| 		if [ -n "$3" ]; then | ||||
| 			gid=$(zaf_zbxapi_gethostgroupid "$3") || exit 1 | ||||
| 			zaf_dbg "Selecting all templates in group $3($gid)" | ||||
| 			zaf_zbxapi_gettemplatesingroup $gid | ||||
| 		else | ||||
| 			zaf_dbg "Selecting all templates in system" | ||||
| 			zaf_zbxapi_gettemplateids | ||||
| 		fi | ||||
| 		;; | ||||
| 	get-map-ids) | ||||
| 		zaf_zbxapi_getmapid | ||||
| 		;; | ||||
| 	export-hosts) | ||||
| 		shift; shift | ||||
| 		gid=$(zaf_zbxapi_gethostgroupid "$1") | ||||
| 		[ -z "$1" ] && zaf_err "$0 api export-hosts dir [hostgroup]" | ||||
| 		dir="$1" | ||||
| 		shift | ||||
| 		hosts=$(zaf_zbxapi_gethostsingroup $gid) | ||||
| 		dir="." | ||||
| 		[ -n "$1" ] && dir="$1" | ||||
| 		if [ -n "$1" ]; then | ||||
| 			gid=$(zaf_zbxapi_gethostgroupid "$1") || exit 1 | ||||
| 			shift | ||||
| 			hosts=$(zaf_zbxapi_gethostsingroup $gid) | ||||
| 		else | ||||
| 			hosts=$(zaf_zbxapi_gethostids) | ||||
| 		fi | ||||
| 		zaf_wrn "Will backup this hosts: $hosts" | ||||
| 		zaf_wrn "Output dir: $dir" | ||||
| 		for h in $hosts; do | ||||
| 			zaf_bglimit 5 | ||||
| 			(hn=$(zaf_zbxapi_gethost $h) | ||||
| 			zaf_wrn "Exporting host $hn($h)..." | ||||
| 			zaf_zbxapi_backuphost $h >$dir/$hn.xml ) | ||||
| 			if zaf_bglimit 5; then | ||||
| 				( | ||||
| 				hn=$(zaf_zbxapi_gethost $h name) | ||||
| 				zaf_wrn "Exporting host $hn($h)..." | ||||
| 				zaf_zbxapi_export_host $h >"$dir/$hn.xml" | ||||
| 				) & | ||||
| 			else | ||||
| 				hn=$(zaf_zbxapi_gethost $h name) | ||||
| 				zaf_wrn "Exporting host $hn($h)..." | ||||
| 				zaf_zbxapi_export_host $h >"$dir/$hn.xml" | ||||
| 			fi | ||||
| 		done | ||||
| 		wait | ||||
| 		;; | ||||
| 	backup-host) | ||||
| 	export-host) | ||||
| 		shift; shift | ||||
| 		hostid=$(zaf_zbxapi_gethostid "$1") | ||||
| 		hostid=$(zaf_zbxapi_gethostid "$1") || exit 1 | ||||
| 		zaf_wrn "Exporting host $3($hostid)..." | ||||
| 		zaf_zbxapi_backuphost $hostid | ||||
| 		zaf_zbxapi_export_host $hostid | ||||
| 		;; | ||||
| 	export-template) | ||||
| 		shift; shift | ||||
| 		templateid=$(zaf_zbxapi_gettemplateid "$1") || exit 1 | ||||
| 		zaf_wrn "Exporting template $3($hostid)..." | ||||
| 		zaf_zbxapi_export_template $templateid | ||||
| 		;; | ||||
| 	export-templates) | ||||
| 		shift; shift | ||||
| 		[ -z "$1" ] && zaf_err "$0 api export-templates dir" | ||||
| 		dir="$1" | ||||
| 		templates=$(zaf_zbxapi_gettemplateids) | ||||
| 		zaf_wrn "Will backup this templates: $templates" | ||||
| 		zaf_wrn "Output dir: $dir" | ||||
| 		for t in $templates; do | ||||
| 			if zaf_bglimit 5; then | ||||
| 				( | ||||
| 				tn=$(zaf_zbxapi_gettemplate $t name) | ||||
| 				zaf_wrn "Exporting template $tn($t)..." | ||||
| 				zaf_zbxapi_export_template $t >"$dir/$tn.xml" | ||||
| 				) & | ||||
| 			else | ||||
| 				tn=$(zaf_zbxapi_gettemplate $t name) | ||||
| 				zaf_wrn "Exporting template $tn($t)..." | ||||
| 				zaf_zbxapi_export_template $t >"$dir/$tn.xml" | ||||
| 			fi | ||||
| 		done | ||||
| 		wait | ||||
| 		;; | ||||
| 	import-template) | ||||
| 		shift; shift | ||||
| 		if zaf_is_plugin $1; then | ||||
| 			if [ -f "$ZAF_PLUGINS_DIR/$1/template.xml" ]; then | ||||
| 				template="$ZAF_PLUGINS_DIR/$1/template.xml" | ||||
| 				zaf_wrn "Importing template $template" | ||||
| 				zaf_zbxapi_import_config $template || zaf_err "Error importing template" | ||||
| 			else | ||||
| 				url="$(zaf_plugin_option $1 Template)" | ||||
| 				if [ -n "$url" ]; then | ||||
| 					zaf_fetch_url $url | zaf_zbxapi_import_config || zaf_err "Error importing template" | ||||
| 				else | ||||
| 					url="$(zaf_plugin_option $1 Url)" | ||||
| 					zaf_fetch_url $url/template.xml | zaf_zbxapi_import_config || zaf_err "Error importing template" | ||||
| 				fi | ||||
| 			fi | ||||
| 		else | ||||
| 			if [ -f $1 ]; then | ||||
| 				zaf_wrn "Importing template $1" | ||||
| 				zaf_zbxapi_import_config $1 || zaf_err "Error importing template" | ||||
| 			else | ||||
| 				zaf_err "Unknown plugin $1!" | ||||
| 			fi | ||||
| 		fi | ||||
| 		;; | ||||
| 	*) | ||||
| 		echo "$0 api command [parameters]" | ||||
| 		echo "hostid 'host'			Get hostid from hostname" | ||||
| 		echo "host 'hostid'			Get hostname from hostid" | ||||
| 		echo "hostgroupid 'hostgroup'		Get hostgroup id from hostgroup" | ||||
| 		echo "hosts 'hostgroup'			Get hosts in group" | ||||
| 		echo "backup-group 'hostgroup' [dir]	Backup all hosts in group (get their config from zabbix and save to dir/hostname.xml)"  | ||||
| 		echo "backup-host 'host'		Backup host (get config from zabbix to stdout)" | ||||
| 		for i in host template map; do | ||||
| 			zaf_hlp "get-${i}-id $i" "Get $i id" | ||||
| 			zaf_hlp "get-byid-${i} id [property]" "Get $i property from id. Leave empty property for JSON"  | ||||
| 		done | ||||
| 		zaf_hlp "get-inventory host [fields]"	"Get inventory fields [or all fields]" | ||||
| 		zaf_hlp "get-host-ids [hg]" "Get all hostids or hostids in group hg" | ||||
| 		zaf_hlp "get-template-ids [hg]" "Get all templateids or templateids in group hg" | ||||
| 		zaf_hlp "get-map-ids" "Get all mapids" | ||||
| 		zaf_hlp "export-hosts dir [hg]"	"Backup all hosts [in group hg] (get their config from zabbix and save to dir/hostname.xml)"  | ||||
| 		zaf_hlp "export-host host" "Backup host (get config from zabbix to stdout)" | ||||
| 		zaf_hlp "import-template {plugin|file}"	"Import template for plugin or from file" | ||||
| 		zaf_hlp "export-template name"	"Export template to stdout" | ||||
| 		zaf_hlp "export-templates dir"	"Export all template to dir" | ||||
| 		echo | ||||
| 		exit | ||||
| 		[ -n "$2" ] && zaf_err "Bad API command '$2'!" | ||||
| 		;; | ||||
| 	esac | ||||
| 	;; | ||||
|  | ||||
| *) | ||||
| 	if zaf_is_plugin "$1"; then | ||||
| 		if [ -z "$2" ]; then | ||||
| 			zaf_list_plugin_commands "$1" | ||||
| 		else | ||||
| 			zaf_plugin_run_command "$@" | ||||
| 		fi | ||||
| 		exit | ||||
| 	fi | ||||
| 	echo "$0 Version ${ZAF_VERSION}. Please use some of this commands:" | ||||
| 	echo "$0 Cmd [ZAF_OPTION=value] [ZAF_CTRL_Option=value] [ZAF_CTRLI_Item_Option=value] ..." | ||||
| 	echo "Commands:" | ||||
| 	echo "$0 update			To update repo (not plugins, similar to apt-get update)" | ||||
| 	echo "$0 upgrade		To upgrade installed plugins from repo"  | ||||
| 	echo "$0 plugins		To list installed plugins" | ||||
| 	echo "$0 show [plugin]		To show installed plugins or plugin info" | ||||
| 	echo "$0 items [plugin]		To list all suported items [for plugin]" | ||||
| 	echo "$0 test [plugin[.item]]	To test [all] suported items by zabbix_agentd [for plugin]" | ||||
| 	echo "$0 get [plugin[.item]]	To test [all] suported items by zabbix_get [for plugin]" | ||||
| 	echo "$0 precache [plugin[.item]]	To precache [all] suported items" | ||||
| 	echo "$0 install plugin		To install plugin" | ||||
| 	echo "$0 remove plugin		To remove plugin"  | ||||
| 	echo "$0 api			To zabbix API functions. See $0 api for more info." | ||||
| 	echo "$0 userparms		See userparms generated from zaf on stdout" | ||||
| 	echo "$0 agent-config		Reconfigure zabbix userparms in $ZAF_AGENT_CONFIGD" | ||||
|  | ||||
| 	echo "$0 self-upgrade		To self-upgrade zaf" | ||||
| 	echo "$0 self-remove		To self-remove zaf and its config" | ||||
| 	echo "$0 cache-clean		To remove all entries from cache" | ||||
| 	echo "Plugin manipulation commands:" | ||||
| 	zaf_hlp "$0 update" "To update repo (not plugins, similar to apt-get update)" | ||||
| 	zaf_hlp "$0 upgrade" "To upgrade installed plugins from repo"  | ||||
| 	zaf_hlp "$0 install plugin" "To install plugin" | ||||
| 	zaf_hlp "$0 remove plugin" "To remove plugin"  | ||||
| 	echo | ||||
| 	echo "Plugin info commands:" | ||||
| 	zaf_hlp "$0 plugins" "To list installed plugins" | ||||
| 	zaf_hlp "$0 show [plugin]"	"To show installed plugins or plugin info" | ||||
| 	zaf_hlp "$0 items [plugin]" "To list all suported items [for plugin]" | ||||
| 	echo | ||||
| 	echo "Plugin diagnostic commands:" | ||||
| 	zaf_hlp "$0 test [plugin[.item]]" "To test [all] suported items by zabbix_agentd [for plugin]" | ||||
| 	zaf_hlp "$0 get [plugin[.item]]" "To test [all] suported items by zabbix_get [for plugin]" | ||||
| 	zaf_hlp "$0 run [plugin[.item]]" "To test [all] suported items by directly runing command [for plugin]" | ||||
| 	zaf_hlp "$0 precache [plugin[.item]]" "To precache [all] suported items" | ||||
| 	zaf_hlp "$0 itemsh plugin.item" "To spawn interactive shell in item context (same as UserParameter)." | ||||
| 	echo | ||||
| 	echo "Zabbix API commands:" | ||||
| 	zaf_hlp "$0 api" "To zabbix API functions. See $0 api for more info." | ||||
| 	echo | ||||
| 	echo "Zabbix trapper commands:" | ||||
| 	zaf_hlp "$0 send plugin.item" "To send result of agent param directly to Zabbix server by zabbix_server." | ||||
| 	zaf_hlp "$0 send item" "To send value for any item from stdin." | ||||
| 	zaf_hlp "$0 send host:item" "To send value for any host:item from stdin." | ||||
| 	echo "Zabbix agent registration:" | ||||
| 	zaf_hlp "$0 register [hostname] [metadata]" "To register hostname on Zabbix server (autoregistration)." | ||||
| 	echo | ||||
| 	echo "Agent config info commands:" | ||||
| 	zaf_hlp "$0 userparms" "See userparms generated from zaf on stdout" | ||||
| 	zaf_hlp "$0 agent-config [force]" "Reconfigure zabbix userparms in $ZAF_AGENT_CONFIGD" | ||||
| 	echo | ||||
| 	echo "Zaf related commands:" | ||||
| 	zaf_hlp "$0 self-upgrade" "To self-upgrade zaf" | ||||
| 	zaf_hlp "$0 self-remove" "To self-remove zaf and its config" | ||||
| 	zaf_hlp "$0 cache-clean" "To remove all entries from cache" | ||||
| 	zaf_hlp "$0 cache-list" "To show all entries in cache" | ||||
| 	echo | ||||
| 	[ -n "$1" ] && zaf_err "Bad command '$1'!" | ||||
| 	;; | ||||
|  | ||||
| esac | ||||
|   | ||||
		Reference in New Issue
	
	Block a user