Skip to content
Open
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ DEFAULT_HOST_SECRET=8201e33f60093f2ce49f1abe6be8*****
URL_LIST=[{"name":"localhost","url":"http://localhost","priority":4},{"name":"github.com","url":"https://github.com","priority":4}]
ZBX_CONFIG={"authentication_type":0,"ok_period":"1d"}
ZBX_ADMIN_USERS=[{"name":"user","password":"password"},{"name":"user1","password":"password"}]
GF_SECURITY_ADMIN_PASSWORD=grafana
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
- docker build -t ${TESTS_IMAGE} -f tests/Dockerfile ./tests/

script:
- docker-compose stop -t 0 && sudo rm -f ./data/
- cp .env.example .env
- docker-compose stop -t 0 && sudo rm -f ./data/
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

я понял, почему так сделано, но docker-compose.yml должен быть разработанный таким образом, чтобы .env не был обязательным. Он должен быть опциональным.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

в .env файле хранится пароль от графаны, который тянется в саму графану и в конфигуратор. Мне показалось что вариант хранения пароля в docker-compose.yml неправильный. Но только что я придумал ещё один вариант реализации... хм... Позже внесу его.

- sudo ./x-setup-server.sh
- docker images
- docker ps -a
Expand Down
7 changes: 7 additions & 0 deletions Dockerfile.grafana
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM grafana/grafana:latest
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Всегда фиксируем версию базового образа, никогда не привязываемся к latest

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Сделал


USER root

ENV GF_INSTALL_PLUGINS=alexanderzobnin-zabbix-app

RUN chown -R grafana:grafana /etc/grafana
3 changes: 2 additions & 1 deletion Vagrantfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/xenial64"
config.vm.network "private_network", ip: "192.168.33.102"
config.vm.network "forwarded_port", guest: 80, host: 8080
config.vm.network "forwarded_port", guest: 3000, host: 3000
config.vm.provider "virtualbox" do |vb|
vb.memory = "2048"
end
Expand Down Expand Up @@ -33,7 +34,7 @@ Vagrant.configure("2") do |config|
iotop \
htop \
mc
#

echo "Getting docker-compose from official repository..."
if [ ! -e "/usr/local/bin/docker-compose" ]; then
curl -L https://github.com/docker/compose/releases/download/1.16.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
Expand Down
39 changes: 39 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#

version: "3"


services:

server:
Expand Down Expand Up @@ -48,6 +50,8 @@ services:
- MYSQL_DATABASE=${MYSQL_DATABASE:-zabbix}
- MYSQL_USER=${MYSQL_USER:-zabbix}
- MYSQL_PASSWORD=${MYSQL_PASSWORD:-zabbix}
volumes:
- ./scripts/nginx.conf:/etc/zabbix/nginx.conf:ro
restart: unless-stopped
logging:
driver: "json-file"
Expand Down Expand Up @@ -88,8 +92,34 @@ services:
max-size: "10M"
max-file: "5"

grafana:
hostname: grafana
env_file:
- .env
build:
dockerfile: Dockerfile.grafana
context: ./
restart: always
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

поставь пожалуйста вместо always -> unless-stopped для restart policy

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Сделал

networks:
- zabbix_net
volumes:
- /data/grafana:/var/lib/grafana
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

точно /data а не ./data?
як по мені то краще б десь кучніше тримати данні

- /data/provisioning/dashboards:/etc/grafana/provisioning/dashboards
- /data/provisioning/datasources:/etc/grafana/provisioning/datasources
- ./scripts/zabbix_dashboards:/var/lib/grafana/dashboards
- ./scripts/grafana.ini:/etc/grafana/grafana.ini:ro
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Почему конфиг находится в каталоге со скриптами?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

исправлю.

- ./scripts/ldap.toml:/etc/grafana/ldap.toml:ro
restart: unless-stopped
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

вижу повтор restart: опции в сервисе, убери пожалуйста дубликат

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

уже и сам заметил... видимо случайно добавил, исправил...

logging:
driver: "json-file"
options:
max-size: "10M"
max-file: "5"

configurator:
hostname: configuration
env_file:
- .env
build:
dockerfile: Dockerfile.configurator
context: ./
Expand All @@ -98,6 +128,9 @@ services:
- ./scripts/configurator.py:/configurator.py:ro
- ./configuration:/configuration:ro
- /etc/zabbix:/etc/zabbix
- /data/provisioning/dashboards:/grafana/provisioning/dashboards
- /data/provisioning/datasources:/grafana/provisioning/datasources
- ./scripts/zabbix_dashboards:/grafana/zabbix_dashboards
links:
- db
- frontend
Expand Down Expand Up @@ -129,6 +162,12 @@ services:
- ZBX_CUSTOM_CONFIG=custom.json
# Usage: ZBX_ADDITIONAL_TEMPLATES=template1,template2
- ZBX_ADDITIONAL_TEMPLATES=Template Web Check, Template App Docker
#GRAFANA ENVIRONMENTS
- GRA_DSOURCE_YAML=/grafana/provisioning/datasources/datasource.yaml
- GRA_DBOARD_YAML=/grafana/provisioning/dashboards/dashboard.yaml
- GRA_ADMIN_PASS=${GF_SECURITY_ADMIN_PASSWORD}
- GRA_PATH_TO_DASHBOARDS=/grafana/zabbix_dashboards
- GRA_HOST=grafana
networks:
zabbix_net:
driver: bridge
Expand Down
4 changes: 2 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Requirements

### Preparing configuration file for server

If default options are not enough, then please use `.env.example` to create own environment configuration file.
Tou need to create configuration file `.env` from `.env.example`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Не понял суть изменения? В предыдущем сказано, что если дефолтных значений не достаточно, то можно использовать собственный конфиг. .env не обязательный должен быть, без него должно стартовать.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

у меня без него почему то не стартовало, связано с паролем админа от графаны, я ещё раз более тщательно проверю и сделаю исправление.


### Run Zabbix server

Expand All @@ -33,7 +33,7 @@ Zabbix agent on host machine, where Zabbix server works inside the docker enviro

#### Run and configured only server components
```shell
$ docker-compose up -d
$ docker-compose up -d && docker restart $(docker ps -q)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

зачем рестартовать все контейнеры после старта?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

это нужно для того что бы графана смогла подключить все файлы, без рестарта контейнера с графаной, например yml файлы не принимало, лишь после рестарта.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

может проблема в чем-то другом, должна заработать сразу же, такой подход не очень, нужно попытаться решить проблему как-то по другому.

```
Zabbix provisioned service is **configurator**, after succesfully configuring the server, configurator has to return exit code 0.
To be sure that it is precisely so, execute such command and look at state column:
Expand Down
86 changes: 85 additions & 1 deletion scripts/configurator.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ def error(msg=""):

class Configurator:
def __init__(self):
self.grafana_password = os.environ["GF_SECURITY_ADMIN_PASSWORD"]
self.grafana_datas_yaml = os.environ["GRA_DSOURCE_YAML"]
self.grafana_dashb_yaml = os.environ["GRA_DBOARD_YAML"]
self.grafana_hostname = os.environ["GRA_HOST"]
self.grafana_pt_dashboards = os.environ["GRA_PATH_TO_DASHBOARDS"]
self.url = os.environ["ZBX_SERVER_URL"]
self.server_host = os.environ["ZBX_SERVER_HOST"]
self.default_admin_username = "admin"
Expand Down Expand Up @@ -95,6 +100,85 @@ def __init__(self):
self.admin_users = json.loads(os.environ["ZBX_ADMIN_USERS"]) if "ZBX_ADMIN_USERS" in os.environ and os.environ["ZBX_ADMIN_USERS"].strip() != "" else []
self.additional_templates = [x.strip() for x in os.environ["ZBX_ADDITIONAL_TEMPLATES"].split(",")] if "ZBX_ADDITIONAL_TEMPLATES" in os.environ else []

def grafana_plugin_on(self):
logger.debug("Grafana Plugin Curl Start")
plugURL = ("{0}:3000/api/plugins/alexanderzobnin-zabbix-app/settings?enabled=true".format(self.grafana_hostname))
c = pycurl.Curl()
c.setopt(c.USERPWD, "%s:%s" % ("admin", self.grafana_password))
c.setopt(c.URL, plugURL)
c.setopt(c.POSTFIELDS, '{ '' }')
c.setopt(c.VERBOSE, True)
c.perform()

def grafana_dashboard_starred(self):
logger.debug("Grafana Dashboard Starred")
path, dirs, files = os.walk(self.grafana_pt_dashboards).next()
file_count = len(files)
print (file_count)

dashboard_id = 1
#Condition for find more then one dashboard.json file (need for add to favorite)
while dashboard_id <= file_count:
#print (dashboard_id)
plugURL = ("{0}:3000/api/user/stars/dashboard/{1}".format(self.grafana_hostname, dashboard_id))
c = pycurl.Curl()
c.setopt(c.USERPWD, "%s:%s" % ("admin", self.grafana_password))
c.setopt(c.URL, plugURL)
c.setopt(c.POSTFIELDS, '{ '' }')
c.setopt(c.VERBOSE, True)
c.perform()
dashboard_id = dashboard_id + 1 #So simply :)

def grafana_configurator(self):
#DATASOURCE.YAML
yaml_file_ds = open(self.grafana_datas_yaml, 'w')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Я думаю, что может есть чучуть получшее формат создания yaml объекта. Посмотри пожалуйста и переформатируй этот блок.

Copy link
Author

@Antom91 Antom91 Jun 13, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Да , есть модули для создания YAML, но они либо создают как то криво, либо не создают то что нужно. я потратил на них пол дня, но я ещё раз на свежую голову посмотрю что там есть..

yaml_file_ds.write('apiVersion: 1\n\n')
yaml_file_ds.write('datasources:\n')
yaml_file_ds.write('- name: Zabbix\n')
yaml_file_ds.write(' type: alexanderzobnin-zabbix-datasource\n')
yaml_file_ds.write(' access: proxy\n')
yaml_file_ds.write(' url: {}/api_jsonrpc.php\n'.format(self.url))
yaml_file_ds.write(' isDefault: true\n')
yaml_file_ds.write(' jsonData:\n')
yaml_file_ds.write(' username: admin\n')
yaml_file_ds.write(' password: {0}\n'.format(self.admin_password))
yaml_file_ds.write(' trends: true\n')
yaml_file_ds.write(' trendsFrom: 7d\n')
yaml_file_ds.write(' trendsRange: 4d\n')
yaml_file_ds.write(' cacheTTL: 1h\n')
yaml_file_ds.write(' alerting: true\n')
yaml_file_ds.write(' version: 1\n')
yaml_file_ds.write(' editable: false\n')
yaml_file_ds.close()

#DASHBOARD.YAML
yaml_file_db = open(self.grafana_dashb_yaml, 'w')
yaml_file_db.write('apiVersion: 1\n\n')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

тоже самое ^^^

yaml_file_db.write('providers:\n')
yaml_file_db.write(' - name: Zabbix\n')
yaml_file_db.write(' folder:\n')
yaml_file_db.write(' folderUid: \n')
yaml_file_db.write(' type: file\n')
yaml_file_db.write(' updateIntervalSeconds: 60\n')
yaml_file_db.write(' options:\n')
yaml_file_db.write(' path: /var/lib/grafana/dashboards')
yaml_file_db.close()
#Grafana Port Checker (need for check, if server start?)
while True:
time.sleep(1)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Сколько ты будешь ждать, пока графана заработает?, Я так понимаю тут бесконечный цикл. Правильно?

Copy link
Author

@Antom91 Antom91 Jun 13, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

не бесконечный цикл, тут идет порт чек. как только графана доступна цикл завершается. Иногда бывало так , что графана загружалась позже выполнения скриптов и выдавало ошибку. Допишу кое что, что бы в случаи если графана не подымится, цикл закончился через какое то время))

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Можно ли избежать создание сокета при каждой итерации, можно ли использовать только sock.connect_ex при пробе конекшена?

result = sock.connect_ex((self.grafana_hostname,3000))
if result == 0:
logger.debug("Grafana Server is Started")
self.grafana_plugin_on() #Enable Plugin
self.grafana_dashboard_starred() #Add all dashboards to favorite
sock.close()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

тоже самое касается закрытие сокета, желательно закрыть его в конце всей процедуры, а не при каждой итерации

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Нет реакции на коментарий. по поводу закрытия порта при каждой итерации

break
else:
logger.debug("Grafana Server still not start, Try...")
sock.close()


def login(self):
logger.debug("Login into Zabbix server (%s)."%(self.url))
login_error = False
Expand Down Expand Up @@ -580,7 +664,7 @@ def assign_template(self, host_id, template_name):
return 1

def main(self):

self.grafana_configurator()
if self.authentication_type != self.default_authentication_type:
logger.debug("Changing authentication_type to default to use api with basic credentials.")
self.update_configuration(config={"authentication_type":self.default_authentication_type})
Expand Down
Loading