summaryrefslogtreecommitdiffstats
path: root/application/forms/ImportSourceForm.php
blob: b547a3204c8d553253058e2f2a98d9de8d171c11 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
<?php

namespace Icinga\Module\Director\Forms;

use Icinga\Module\Director\Hook\ImportSourceHook;
use Icinga\Module\Director\Objects\ImportSource;
use Icinga\Module\Director\Web\Form\DirectorObjectForm;
use Icinga\Web\Hook;

class ImportSourceForm extends DirectorObjectForm
{
    public function setup()
    {
        $this->addElement('text', 'source_name', array(
            'label'       => $this->translate('Import source name'),
            'description' => $this->translate(
                'A short name identifying this import source. Use something meaningful,'
                . ' like "Hosts from Puppet", "Users from Active Directory" or similar'
            ),
            'required'    => true,
        ));

        $this->addElement('textarea', 'description', array(
            'label'       => $this->translate('Description'),
            'description' => $this->translate(
                'An extended description for this Import Source. This should explain'
                . " what kind of data you're going to import from this source."
            ),
            'rows'        => '3',
        ));

        $this->addElement('select', 'provider_class', array(
            'label'        => $this->translate('Source Type'),
            'required'     => true,
            'multiOptions' => $this->optionalEnum($this->enumSourceTypes()),
            'description'  => $this->translate(
                'These are different data providers fetching data from various sources.'
                . ' You didn\'t find what you\'re looking for? Import sources are implemented'
                . ' as a hook in Director, so you might find (or write your own) Icinga Web 2'
                . ' module fetching data from wherever you want'
            ),
            'class'        => 'autosubmit'
        ));

        $this->addSettings();
        $this->setButtons();
    }

    public function getSentOrObjectSetting($name, $default = null)
    {
        if ($this->hasObject()) {
            $value = $this->getSentValue($name);
            if ($value === null) {
                /** @var ImportSource $object */
                $object = $this->getObject();

                return $object->getSetting($name, $default);
            } else {
                return $value;
            }
        } else {
            return $this->getSentValue($name, $default);
        }
    }

    public function hasChangedSetting($name)
    {
        if ($this->hasBeenSent() && $this->hasObject()) {
            /** @var ImportSource $object */
            $object = $this->getObject();
            return $object->getStoredSetting($name)
                !== $this->getSentValue($name);
        } else {
            return false;
        }
    }

    protected function addSettings()
    {
        if (! ($class = $this->getProviderClass())) {
            return;
        }

        $defaultKeyCol = $this->getDefaultKeyColumnName();

        $this->addElement('text', 'key_column', array(
            'label' => $this->translate('Key column name'),
            'description' => $this->translate(
                'This must be a column containing unique values like hostnames. Unless otherwise'
                . ' specified this will then be used as the object_name for the syncronized'
                . ' Icinga object. Especially when getting started with director please make'
                . ' sure to strictly follow this rule. Duplicate values for this column on different'
                . ' rows will trigger a failure, your import run will not succeed. Please pay attention'
                . ' when synching services, as "purge" will only work correctly with a key_column'
                . ' corresponding to host!name. Check the "Combine" property modifier in case your'
                . ' data source cannot provide such a field'
            ),
            'placeholder' => $defaultKeyCol,
            'required'    => $defaultKeyCol === null,
        ));

        if (array_key_exists($class, $this->enumSourceTypes())) {
            $class::addSettingsFormFields($this);
            foreach ($this->object()->getSettings() as $key => $val) {
                if ($el = $this->getElement($key)) {
                    $el->setValue($val);
                }
            }
        }
    }

    protected function getDefaultKeyColumnName()
    {
        if (! ($class = $this->getProviderClass())) {
            return null;
        }

        if (! class_exists($class)) {
            return null;
        }

        return $class::getDefaultKeyColumnName();
    }

    protected function getProviderClass()
    {
        if ($this->hasBeenSent()) {
            $class = $this->getRequest()->getPost('provider_class');
        } else {
            if (! ($class = $this->object()->get('provider_class'))) {
                return null;
            }
        }

        return $class;
    }

    public function onSuccess()
    {
        if (! $this->getValue('key_column')) {
            if ($default = $this->getDefaultKeyColumnName()) {
                $this->setElementValue('key_column', $default);
                $this->object()->set('key_column', $default);
            }
        }

        parent::onSuccess();
    }

    protected function enumSourceTypes()
    {
        /** @var ImportSourceHook[] $hooks */
        $hooks = Hook::all('Director\\ImportSource');

        $enum = array();
        foreach ($hooks as $hook) {
            $enum[get_class($hook)] = $hook->getName();
        }
        asort($enum);

        return $enum;
    }
}