[openstack-dev] [heat] Problems with software config and Heat standalone configurations

Steve Baker sbaker at redhat.com
Fri Apr 4 02:10:34 UTC 2014


On 04/04/14 14:26, Michael Elder wrote:
> Hello,
>
> While adopting the latest from the software configurations in
> Icehouse, we discovered an issue with the new software configuration
> type and its assumptions about using the heat client to perform behavior.
>
> The change was introduced in:
>
> commit 21f60b155e4b65396ebf77e05a0ef300e7c3c1cf
> Author: Steve Baker <sbaker at redhat.com>
> Change: https://review.openstack.org/#/c/67621/
>
> The net is that the software config type in software_config.py lines
> 147-152 relies on the heat client to create/clone software
> configuration resources in the heat database:
>
>     def *handle_create*(/self/):
>         props = dict(/self/.properties)
>         props[/self/.NAME] = /self/.physical_resource_name()
>
>         sc = /self/.heat().software_configs.create(**props) ## HERE
> THE HEAT CLIENT IS CREATING A NEW SOFTWARE_CONFIG TO MAKE EACH ONE
> IMMUTABLE
>         /self/.resource_id_set(sc.id)
>
> My concerns with this approach:
>
> When used in standalone mode, the Heat engine receives headers which
> are used to drive authentication (X-Auth-Url, X-Auth-User, X-Auth-Key,
> ..):
>
> curl -i -X POST -H 'X-Auth-Key: password' -H 'Accept:
> application/json' -H 'Content-Type: application/json' -H 'X-Auth-Url:
> http://[host]:5000/v2.0' <http://10.10.0.101:5000/v2.0%27>-H
> 'X-Auth-User: admin' -H 'User-Agent: python-heatclient' -d '{...}'
> http://10.0.2.15:8004/v1/{tenant_id}
>
> In this mode, the heat config file indicates standalone mode and can
> also indicate multicloud support:
>
> # /etc/heat/heat.conf
> [paste_deploy]
> flavor = standalone
>
> [auth_password]
> allowed_auth_uris = http://[host1]:5000/v2.0,http://[host2]:5000/v2.0
> multi_cloud = true
>
> Any keystone URL which is referenced is unaware of the orchestration
> engine which is interacting with it. Herein lies the design flaw.
Its not so much a design flaw, its a bug where a new piece of code
interacts poorly with a mode that currently has few users and no
integration test coverage.

>
> When software_config calls self.heat(), it resolves clients.py's heat
> client:
>
>     def *heat*(/self/):
>         if /self/._heat:
>             return /self/._heat
>        
>         con = /self/.context
>         if /self/.auth_token is None:
>             logger.error(_(/"Heat connection failed, no auth_token!"/))
>             return None
>         # try the token
>         args = {
>                 /'auth_url'/: con.auth_url,
>                 /'token'/: /self/.auth_token,
>                 /'_username_'/: None,
>                 /'password'/: None,
>                 /'ca_file'/: /self/._get_client_option(/'heat'/,
> /'ca_file'/),
>                 /'cert_file'/: /self/._get_client_option(/'heat'/,
> /'cert_file'/),
>                 /'key_file'/: /self/._get_client_option(/'heat'/,
> /'key_file'/),
>                 /'insecure'/: /self/._get_client_option(/'heat'/,
> /'insecure'/)  
>          }
>
>         endpoint_type = /self/._get_client_option(/'heat'/,
> /'endpoint_type'/)
>         endpoint = /self/._get_heat_url()
>         if not endpoint:
>             endpoint = /self/.url_for(service_type=/'_orchestration_'/,
>                                     endpoint_type=endpoint_type)
>         /self/._heat = heatclient.Client(/'1'/, endpoint, **args)
>
>         return /self/._heat
>
> Here, an attempt to look up the orchestration URL (which is already
> executing in the context of the heat engine) comes up wrong because
> Keystone doesn't know about this remote standalone Heat engine.
>
If you look at self._get_heat_url() you'll see that the heat.conf
[clients_heat] url will be used for the heat endpoint if it is set. I
would recommend setting that for standalone mode. A devstack change for
HEAT_STANDALONE would be helpful here.

> Further, at this point, the username and password are null, and when
> the auth_password standza is applied in the config file, Heat will
> deny any attempts at authorization which only provide a token. As I
> understand it today, that's because it doesn't have individual
> keystone admin users for all remote keystone services in the list of
> allowed_auth_urls. Hence, if only provided with a token, I don't think
> the heat engine can validate the token against the remote keystone.
>
> One workaround that I've implemented locally is to change the logic to
> check for standalone mode and send the username and password.
>
>        flavor = /'default'/
>         try:
>             logger.info(/"Configuration is %s"/ % str(cfg.CONF))
>             flavor = cfg.CONF.paste_deploy.flavor
>         except cfg.NoSuchOptError as _nsoe_:
>             flavor = /'default'/
>         logger.info(/"Flavor is %s"/ % flavor)
>        
>         # We really should examine the pipeline to determine whether
> we're using _authtoken_ or _authpassword_.
>         if flavor == /'_standalone_'/:
>            
>             context_map = /self/.context.to_dict()
>            
>             if /'_username_'/ in context_map.keys():
>                 username = context_map[/'_username_'/]
>             else:
>                 username = None
>    
>             if /'password'/ in context_map.keys():
>                 password = context_map[/'password'/]
>             else:
>                 password = None
>            
>             logger.info(/"Configuring _username_='%s' and
> password='%s'"/ % (username, password))
>             args = {
>                 /'auth_url'/: con.auth_url,
>                 /'token'/: None,
>                 /'_username_'/: username,
>                 /'password'/: password,
>                 /'ca_file'/: /self/._get_client_option(/'heat'/,
> /'ca_file'/),
>                 /'cert_file'/: /self/._get_client_option(/'heat'/,
> /'cert_file'/),
>                 /'key_file'/: /self/._get_client_option(/'heat'/,
> /'key_file'/),
>                 /'insecure'/: /self/._get_client_option(/'heat'/,
> /'insecure'/)
>             }  
>         else:
>             if /self/.auth_token is None:
>                 logger.error(_(/"Heat connection failed, no
> auth_token!"/))
>                 return None
> ...
>
> Is this a known issue?
This is a great summary of the problem, but it really belongs in a
launchpad bug. Lets discuss potential solutions there.

https://bugs.launchpad.net/heat/+filebug

cheers
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openstack.org/pipermail/openstack-dev/attachments/20140404/9e510e43/attachment.html>


More information about the OpenStack-dev mailing list