require 'workers/stack_bootstrap/chef_node_name_builder' # Fetches info about stack servers from provider and then persist them in mongo. class StackServersPersister include PutsAndFlush attr_reader :stack, :out, :deleted, :servers_info NEW = 'new' DELETED = 'deleted' PERSISTED = 'persisted' JUST_PERSISTED = 'just_persisted' def initialize(stack, out) @stack, @out = stack, out @project = mongo.project(stack.project) @deploy_env = @project.deploy_env(stack.deploy_env) fetch_provider_servers_info set_servers_states end def persist_new_servers with_state(NEW).each do |info| info[:server] = persist_stack_server(info[:provider_info]) info[:state] = JUST_PERSISTED end end # returns: { priority_as_integer => [Servers] } def just_persisted_by_priority stack_servers_with_priority = {} with_state(JUST_PERSISTED).each do |info| stack_servers_with_priority[info[:priority]] ||= [] stack_servers_with_priority[info[:priority]] << info[:server] end stack_servers_with_priority end private def fetch_provider_servers_info @servers_info = stack.provider_instance.stack_servers(stack).map do |provider_info| { id: provider_info['id'], provider_info: provider_info, priority: provider_info['tags']['cid:priority'].to_i } end end def set_servers_states persisted = Devops::Db.connector.stack_servers(stack.id) persisted_ids = persisted.map(&:id) in_cloud_ids = @servers_info.map {|info| info[:id]} new_ids = in_cloud_ids - persisted_ids deleted_ids = persisted_ids - in_cloud_ids @servers_info.each do |info| if new_ids.include?(info[:id]) info[:state] = NEW else info[:state] = PERSISTED end end @deleted = persisted.select { |server| deleted_ids.include?(server.id) } end def with_state(state) @servers_info.select { |info| info[:state] == state } end # takes a hash, returns Server model def persist_stack_server(server_info) server_attrs = { '_id' => server_info['id'], 'chef_node_name' => get_name_builder(server_info).build_node_name!(incrementers_values), 'created_by' => stack.owner, 'deploy_env' => @deploy_env.identifier, 'key' => server_info['key_name'] || stack.provider_instance.ssh_key, 'project' => @project.id, 'provider' => @stack.provider, 'provider_account' => @stack.provider_account, 'remote_user' => mongo.image(@deploy_env.image).remote_user, 'private_ip' => server_info['private_ip'], 'public_ip' => server_info['public_ip'], 'run_list' => stack.run_list || [], 'stack' => stack.name } server = ::Devops::Model::Server.new(server_attrs) mongo.server_insert(server) server end def get_name_builder(server_info) ChefNodeNameBuilder.new( provider_server_info: server_info, project_id: @project.id, env_id: @deploy_env.identifier, owner: stack.owner ) end def incrementers_values @incrementers_values ||= {} end def mongo Devops::Db.connector end end