OpenStackの各コンポーネントの設定ファイルを規程外のパスに置く場合はpolicy_file設定を忘れずに
ハマったのでメモしておく。
1台のノードに複数バージョンのOpenStackコンポーネント(例えばneutron)などをインストールして選択起動するような場合、インストールパスも設定ファイル群のパスも当然ながら分けることになるはず。
例えば、
- grizzly /usr/local/grizzly/quantum/etc/ - folsom /usr/local/folsom/quantum/etc/
みたいな感じに。
この時、quantum.confは
quantum-server --config-file /usr/local/grizzly/quantum/etc/quantum.conf
のように指定してやれば良いんだけれど、policy.jsonは起動時に指定できない(たぶん)。
ポリシーチェックが入ると、quantumクライアント側でこんなエラーが...
$ quantum --os-user=admin --os-password=adminpasswd --os-tenant-name=admin agent-list Policy configuration policy.json could not be found <-- くっ...orz
どこを参照するかというと、例えばneutronではAPIのControllerクラスでポリシーチェックをする(※1)際に都度呼ばれているみたい。
quantum/api/v2/base.py
class Controller(object): <...省略...> def _items(self, request, do_authz=False, parent_id=None): <...省略...> obj_list = [obj for obj in obj_list if policy.check(request.context, self._plugin_handlers[self.SHOW], obj, plugin=self._plugin)] <...省略...>
quantum/policy.py
policyモジュールではcheck()が呼ばれる度にpolicy.jsonがチェックされる。
<...省略...> 45 def init(): <--※1 定義 46 global _POLICY_PATH 47 global _POLICY_CACHE 48 if not _POLICY_PATH: 49 _POLICY_PATH = utils.find_config_file({}, cfg.CONF.policy_file) <--※2 50 if not _POLICY_PATH: 51 raise exceptions.PolicyNotFound(path=cfg.CONF.policy_file) 52 # pass _set_brain to read_cached_file so that the policy brain 53 # is reset only if the file has changed 54 LOG.debug(_("loading policy file at %s"), _POLICY_PATH) 55 utils.read_cached_file(_POLICY_PATH, _POLICY_CACHE, 56 reload_func=_set_rules) <...省略...> 162 def check(context, action, target, plugin=None): 163 """Verifies that the action is valid on the target in this context. 164 165 :param context: quantum context 166 :param action: string representing the action to be checked 167 this should be colon separated for clarity. 168 :param target: dictionary representing the object of the action 169 for object creation this should be a dictionary representing the 170 location of the object e.g. ``{'project_id': context.project_id}`` 171 :param plugin: quantum plugin used to retrieve information required 172 for augmenting the target 173 174 :return: Returns True if access is permitted else False. 175 """ 176 init() <--※1 呼び出し 177 real_target = _build_target(action, target, plugin, context) 178 match_rule = _build_match_rule(action, real_target) 179 credentials = context.to_dict() 180 return policy.check(match_rule, real_target, credentia <...省略...>
では設定ファイル(ここではquantum.conf)のpolicy_fileに何も指定しないときの動きは?
utils.pyのfind_config_file()が呼ばれて規程のパス上からpolicy.jsonをロードする(※2)
という動きになって、例えば/usr/local/grizzly/quantum/etc/policy.jsonのような規程から外れたパスからは当然ながら拾ってくれず、
Traceback (most recent call last): File "/home/saitou/grizzly/quantum/quantum/api/v2/resource.py", line 82, in resource result = method(request=request, **args) File "/home/saitou/grizzly/quantum/quantum/api/v2/base.py", line 240, in index return self._items(request, True, parent_id) File "/home/saitou/grizzly/quantum/quantum/api/v2/base.py", line 206, in _items plugin=self._plugin)] File "/home/saitou/grizzly/quantum/quantum/policy.py", line 182, in check init() File "/home/saitou/grizzly/quantum/quantum/policy.py", line 56, in init raise exceptions.PolicyNotFound(path=cfg.CONF.policy_file) PolicyNotFound: Policy configuration policy.json could not be found
というようにエラーになり、クライアント側では
Policy configuration policy.json could not be found
というエラーになると。
policy_fileの指定方法
- quantum.confの場合はこんな感じ
[DEFAULT] policy_file = /usr/local/grizzly/quantum/etc/policy.json
これで解決。
先は長いぜ...最初はクライアント側の問題かと思った...