<s> import json <EOL> import os <EOL> import StringIO <EOL> import chef <EOL> import opencenter <EOL> import opencenter . backends <EOL> import time <EOL> import mako . template <EOL> class ChefClientBackend ( opencenter . backends . Backend ) : <EOL> def __init__ ( self ) : <EOL> super ( ChefClientBackend , self ) . __init__ ( __file__ ) <EOL> def additional_constraints ( self , api , node_id , action , ns ) : <EOL> if action == '<STR_LIT>' : <EOL> return None <EOL> return [ ] <EOL> def _represent_node_attributes ( self , api , node_id ) : <EOL> node = api . _model_get_by_id ( '<STR_LIT>' , node_id ) <EOL> node_attributes = { } <EOL> cluster_attributes = { } <EOL> if '<STR_LIT>' in node : <EOL> for fact in node [ '<STR_LIT>' ] : <EOL> fact_info = opencenter . backends . fact_by_name ( fact ) <EOL> if fact_info is None or '<STR_LIT>' not in fact_info : <EOL> self . logger . debug ( '<STR_LIT>' % fact ) <EOL> else : <EOL> if isinstance ( node [ '<STR_LIT>' ] [ fact ] , basestring ) : <EOL> fact_serialized = node [ '<STR_LIT>' ] [ fact ] <EOL> else : <EOL> fact_serialized = json . dumps ( node [ '<STR_LIT>' ] [ fact ] ) <EOL> if fact_info [ '<STR_LIT>' ] is True : <EOL> if fact in cluster_attributes : <EOL> raise KeyError ( '<STR_LIT>' ) <EOL> cluster_attributes [ fact ] = fact_serialized <EOL> else : <EOL> if fact in node_attributes : <EOL> raise KeyError ( '<STR_LIT>' ) <EOL> node_attributes [ fact ] = fact_serialized <EOL> environment_template = os . path . join ( os . path . dirname ( __file__ ) , <EOL> '<STR_LIT>' ) <EOL> node_template = os . path . join ( os . path . dirname ( __file__ ) , <EOL> '<STR_LIT>' ) <EOL> chef_node_attrs = mako . template . Template ( <EOL> filename = node_template ) . render ( facts = node_attributes ) <EOL> chef_env_attrs = mako . template . Template ( <EOL> filename = environment_template ) . render ( facts = cluster_attributes ) <EOL> return ( json . loads ( chef_node_attrs ) , json . loads ( chef_env_attrs ) ) <EOL> def _entity_exists ( self , entity_type , key , <EOL> value , chef_api ) : <EOL> result = chef . Search ( entity_type , '<STR_LIT>' % ( key , value ) , <EOL> <NUM_LIT:1> , <NUM_LIT:0> , chef_api ) <EOL> return len ( result ) == <NUM_LIT:1> <EOL> def _environment_exists ( self , environment_name , <EOL> chef_api ) : <EOL> return self . _entity_exists ( '<STR_LIT>' , '<STR_LIT:name>' , <EOL> environment_name , chef_api ) <EOL> def _node_exists ( self , node_name , chef_api ) : <EOL> return self . _entity_exists ( '<STR_LIT>' , '<STR_LIT:name>' , <EOL> node_name , chef_api ) <EOL> def _map_roles ( self , role ) : <EOL> if role == '<STR_LIT>' : <EOL> return [ '<STR_LIT>' ] <EOL> elif role == '<STR_LIT>' : <EOL> return [ '<STR_LIT>' ] <EOL> elif role == '<STR_LIT>' : <EOL> return [ '<STR_LIT>' ] <EOL> elif role == '<STR_LIT>' : <EOL> return [ '<STR_LIT>' ] <EOL> return [ ] <EOL> def _get_nodes_in_env ( self , env , api ) : <EOL> """<STR_LIT>""" <EOL> final_nodelist = [ ] <EOL> self . logger . debug ( '<STR_LIT>' % env ) <EOL> query = '<STR_LIT>' % env <EOL> nodelist = api . nodes_query ( query ) <EOL> for node in nodelist : <EOL> should_add = True <EOL> if not '<STR_LIT>' in node [ '<STR_LIT>' ] : <EOL> should_add = False <EOL> else : <EOL> if '<STR_LIT>' in node [ '<STR_LIT>' ] [ '<STR_LIT>' ] : <EOL> should_add = False <EOL> if not '<STR_LIT>' in node [ '<STR_LIT>' ] [ '<STR_LIT>' ] : <EOL> should_add = False <EOL> else : <EOL> ocaom = '<STR_LIT>' <EOL> if not ocaom in node [ '<STR_LIT>' ] and not '<STR_LIT>' in node [ '<STR_LIT>' ] [ ocaom ] : <EOL> should_add = False <EOL> if should_add is True : <EOL> node_id = node [ '<STR_LIT:id>' ] <EOL> final_nodelist . append ( node_id ) <EOL> self . logger . debug ( '<STR_LIT>' % final_nodelist ) <EOL> return final_nodelist <EOL> def _serialize_node_blob ( self , blob ) : <EOL> result = { } <EOL> for key , value in blob . items ( ) : <EOL> if isinstance ( value , chef . node . NodeAttributes ) : <EOL> result [ key ] = self . _serialize_node_blob ( value ) <EOL> else : <EOL> result [ key ] = value <EOL> return result <EOL> def _watch_converge_task ( self , api , nodelist ) : <EOL> """<STR_LIT>""" <EOL> if len ( nodelist ) == <NUM_LIT:0> : <EOL> return True , '<STR_LIT>' <EOL> query = '<STR_LIT>' <EOL> adventurator = api . _model_get_first_by_query ( '<STR_LIT>' , query ) <EOL> if adventurator is None : <EOL> return False , '<STR_LIT>' <EOL> dsl = [ { '<STR_LIT>' : '<STR_LIT>' , '<STR_LIT>' : { } } ] <EOL> node_task = api . _model_create ( <EOL> '<STR_LIT>' , <EOL> { '<STR_LIT:action>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : adventurator [ '<STR_LIT:id>' ] , <EOL> '<STR_LIT>' : { '<STR_LIT>' : nodelist , <EOL> '<STR_LIT>' : dsl } } ) <EOL> while node_task [ '<STR_LIT:state>' ] not in [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] : <EOL> time . sleep ( <NUM_LIT:5> ) <EOL> node_task = api . _model_get_by_id ( '<STR_LIT>' , node_task [ '<STR_LIT:id>' ] ) <EOL> if node_task [ '<STR_LIT:state>' ] != '<STR_LIT>' : <EOL> return False , '<STR_LIT>' % node_task [ '<STR_LIT:id>' ] <EOL> if '<STR_LIT>' in node_task [ '<STR_LIT:result>' ] and node_task [ '<STR_LIT:result>' ] [ '<STR_LIT>' ] != <NUM_LIT:0> : <EOL> return False , '<STR_LIT>' % node_task [ '<STR_LIT:id>' ] <EOL> return True , '<STR_LIT>' <EOL> def converge_chef ( self , state_data , api , <EOL> node_id , ** kwargs ) : <EOL> def safe_get_fact ( node , fact ) : <EOL> if not fact in node [ '<STR_LIT>' ] : <EOL> return None <EOL> return node [ '<STR_LIT>' ] [ fact ] <EOL> def verify_facts ( node , facts ) : <EOL> for fact in facts : <EOL> if not fact in node [ '<STR_LIT>' ] : <EOL> return False <EOL> return True <EOL> self . logger . info ( '<STR_LIT>' % ( <EOL> node_id , ) ) <EOL> node = api . _model_get_by_id ( '<STR_LIT>' , node_id ) <EOL> api . apply_expression ( node_id , '<STR_LIT>' ) <EOL> if not '<STR_LIT>' in node [ '<STR_LIT>' ] : <EOL> return self . _fail ( msg = '<STR_LIT>' ) <EOL> chef_server_consumed = node [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> cs = api . _model_get_by_id ( '<STR_LIT>' , chef_server_consumed ) <EOL> if not cs : <EOL> return self . _fail ( msg = '<STR_LIT>' ) <EOL> if not verify_facts ( cs , [ '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' ] ) : <EOL> return self . _fail ( msg = '<STR_LIT>' ) <EOL> chef_server_uri = cs [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> chef_server_client_name = cs [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> chef_server_client_pem = cs [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> self . logger . debug ( '<STR_LIT>' ) <EOL> pem = StringIO . StringIO ( chef_server_client_pem ) <EOL> rsa_key = chef . rsa . Key ( pem ) <EOL> chef_api = chef . ChefAPI ( chef_server_uri , <EOL> rsa_key , <EOL> chef_server_client_name ) <EOL> pem . close ( ) <EOL> if not '<STR_LIT>' in node [ '<STR_LIT>' ] : <EOL> api . apply_expression ( node_id , '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> if self . _node_exists ( node [ '<STR_LIT:name>' ] , chef_api ) : <EOL> chef_node = chef . Node ( node [ '<STR_LIT:name>' ] , chef_api ) <EOL> chef_node . delete ( ) <EOL> return self . _ok ( ) <EOL> node_attrs , env_attrs = self . _represent_node_attributes ( api , node_id ) <EOL> self . logger . debug ( '<STR_LIT>' % node_attrs ) <EOL> self . logger . debug ( '<STR_LIT>' % env_attrs ) <EOL> nova_role = node [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> chef_environment = node [ '<STR_LIT>' ] [ '<STR_LIT>' ] . replace ( '<STR_LIT:U+0020>' , '<STR_LIT:_>' ) <EOL> env = None <EOL> if not self . _environment_exists ( chef_environment , chef_api ) : <EOL> self . logger . debug ( '<STR_LIT>' % <EOL> chef_environment ) <EOL> env = chef . Environment . create ( chef_environment , <EOL> api = chef_api ) <EOL> env . save ( ) <EOL> else : <EOL> env = chef . Environment ( chef_environment , chef_api ) <EOL> if env is None : <EOL> self . logger . error ( '<STR_LIT>' ) <EOL> return self . _fail ( ) <EOL> old_env_overrides = env . override_attributes <EOL> self . logger . debug ( '<STR_LIT>' % old_env_overrides ) <EOL> for i in range ( <NUM_LIT:3> ) : <EOL> if self . _node_exists ( node [ '<STR_LIT:name>' ] , chef_api ) : <EOL> break <EOL> else : <EOL> self . logger . info ( "<STR_LIT>" <EOL> "<STR_LIT>" % ( <EOL> node [ '<STR_LIT:name>' ] , i + <NUM_LIT:1> ) ) <EOL> time . sleep ( <NUM_LIT:10> ) <EOL> if i == <NUM_LIT:3> : <EOL> msg = ( "<STR_LIT>" <EOL> "<STR_LIT>" % node [ '<STR_LIT:name>' ] ) <EOL> self . logger . error ( msg ) <EOL> return self . _fail ( msg = msg ) <EOL> chef_node = chef . Node ( node [ '<STR_LIT:name>' ] , chef_api ) <EOL> old_node_overrides = self . _serialize_node_blob ( chef_node . normal ) <EOL> self . logger . debug ( '<STR_LIT>' % old_node_overrides ) <EOL> need_node_converge = False <EOL> need_env_converge = False <EOL> query = '<STR_LIT>' <EOL> adventurator = api . _model_get_first_by_query ( '<STR_LIT>' , query ) <EOL> if not adventurator : <EOL> self . logger . error ( '<STR_LIT>' ) <EOL> return self . _fail ( msg = '<STR_LIT>' ) <EOL> self . logger . debug ( '<STR_LIT>' ) <EOL> self . logger . debug ( '<STR_LIT>' % chef_environment ) <EOL> chef_node . chef_environment = chef_environment <EOL> chef_node . normal = node_attrs <EOL> old_runlist = chef_node . run_list <EOL> chef_node . run_list = self . _map_roles ( nova_role ) <EOL> chef_node . save ( ) <EOL> if old_runlist != chef_node . run_list : <EOL> need_node_converge = True <EOL> if old_env_overrides != env_attrs : <EOL> self . logger . debug ( '<STR_LIT>' ) <EOL> need_env_converge = True <EOL> env . override_attributes = env_attrs <EOL> env . save ( ) <EOL> if need_node_converge : <EOL> self . logger . debug ( '<STR_LIT>' % node_id ) <EOL> result_b , result_s = self . _watch_converge_task ( <EOL> api , [ node_id ] ) <EOL> if result_b is not True : <EOL> return self . _fail ( msg = '<STR_LIT>' % result_s ) <EOL> nodelist = self . _get_nodes_in_env ( chef_environment , api ) <EOL> if node_id in nodelist : <EOL> nodelist . remove ( node_id ) <EOL> self . logger . debug ( '<STR_LIT>' % <EOL> ( chef_environment , nodelist ) ) <EOL> result_b , result_s = self . _watch_converge_task ( <EOL> api , nodelist ) <EOL> if result_b is not True : <EOL> return self . _fail ( msg = '<STR_LIT>' % result_s ) <EOL> if need_env_converge : <EOL> nodelist = self . _get_nodes_in_env ( chef_environment , api ) <EOL> self . logger . debug ( '<STR_LIT>' % nodelist ) <EOL> result_b , result_s = self . _watch_converge_task ( <EOL> api , nodelist ) <EOL> if result_b is not True : <EOL> return self . _fail ( msg = '<STR_LIT>' % result_s ) <EOL> return self . _ok ( ) <EOL> def add_backend ( self , api , node_id , ** kwargs ) : <EOL> return self . _fail ( msg = '<STR_LIT>' ) </s>
