[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/stackmate/stackmate/master/utils/cloudstackfactory.rb [Back]  [Original]

$LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../")
require 'json'
require 'yaml'

module StackMate

  class CloudStackFactory

    def self.print_class(class_name,create_tag,required_fields,optional_fields,create_async,delete_tag,delete_id_tag,delete_async)
      async={}
      async[true] = 'make_async_request'
      async[false] = 'make_sync_request'
      create_request = async[create_async]
      delete_request = async[delete_async]
      api_name = class_name
      tag_name = class_name
      resource_tag = "result_obj['#{class_name}'.downcase]"
      class_name = class_name+"Ops" if ((class_name.include?("VirtualMachine") && create_tag.include?("start")) || (class_name.include?("Volume") && create_tag.include?("attach")))
      tag_name = "UserVM" if class_name.include?("VirtualMachine")
      id_tag = 'id'
      if (class_name.eql?("SecurityGroupIngress") || class_name.include?("SecurityGroupEgress"))
        gress = class_name.gsub("SecurityGroup","").downcase
        id_tag = 'ruleid'
        resource_tag = "result_obj['securitygroup']['#{gress}rule'.downcase][0]"
      end
      if(class_name.eql?("EgressFirewallRule"))
        resource_tag = "result_obj['firewallrule']"
      end
      str = ""
      str = str + "require 'stackmate/participants/cloudstack'\n"
      str = str + "\nmodule StackMate\n"
      str = str + "  class CloudStack" + class_name + " < CloudStackResource\n"
      #puts str
      str = str + "
    include Logging
    include Intrinsic
    include Resolver
      def create
        logger.debug(\"Creating resource \#{@name}\")
        workitem[@name] = {}
        name_cs = workitem['StackName'] + '-' + @name
        args={}
        begin\n"
      #get required fields
      #treat maps differently
      required_fields.each do |required,type|
        if required.eql?("name")
          str = str + "          args['#{required}'] = workitem['StackName'] +'-' +get_#{required}\n"
        else
          str = str + "          args['#{required}'] = get_#{required}\n"
        end
      end
      #populate optional fields
      optional_fields.each do |optional,type|
        if optional.eql?("name")
          str = str + "          args['#{optional}'] = workitem['StackName'] +'-' +get_#{optional} if @props.has_key?('#{optional}')\n"
        elsif optional.eql?("iptonetworklist")
          str = str + "
          if @props.has_key?('iptonetworklist')
            ipnetworklist = get_iptonetworklist
            #split
            list_params = ipnetworklist.split(\"&\")
            list_params.each do |p|
              fields = p.split(\"=\")
              args[fields[0]] = fields[1]
            end
          end\n"
        else
          str = str + "          args['#{optional}'] = get_#{optional} if @props.has_key?('#{optional}')\n"
        end
      end

      #make API call, populate workitem object
      str = str + "
          logger.info(\"Creating resource \#{@name} with following arguments\")
          p args
          result_obj = #{create_request}('#{create_tag}#{api_name}',args)
          resource_obj = " + resource_tag + "\n
          #doing it this way since it is easier to change later, rather than cloning whole object
          resource_obj.each_key do |k|
            val = resource_obj[k]
            if('#{id_tag}'.eql?(k))
              k = 'physical_id'
            end
            workitem[@name][k] = val
          end
          set_tags(@props['tags'],workitem[@name]['physical_id'],\"#{tag_name}\") if @props.has_key?('tags')
          set_metadata if workitem['Resources'][@name].has_key?('Metadata')
          workitem['ResolvedNames'][@name] = name_cs
          workitem['IdMap'][workitem[@name]['physical_id']] = @name
        "
      #set ip address for VMs
      str = str + "workitem[@name][:PrivateIp] = resource_obj['nic'][0]['ipaddress']\n" if class_name.eql?("VirtualMachine")
      #raise error if some required field is missing
      str = str + "
        rescue NoMethodError => nme
          logger.error(\"Create request failed for resource #{@name}. Cleaning up the stack\")
          raise nme
        rescue Exception => e
          logger.error(e.message)
          raise e
        end
        "
      #end method
      str = str +"
      end
      "
      str = str + "
      def delete
        logger.debug(\"Deleting resource \#{@name}\")
        begin
          physical_id = workitem[@name]['physical_id'] if !workitem[@name].nil?
          if(!physical_id.nil?)
            args = {'#{delete_id_tag}' => physical_id
                  }
            result_obj = #{delete_request}('#{delete_tag}#{class_name}',args)
            if (!(result_obj['error'] == true))
              logger.info(\"Successfully deleted resource \#{@name}\")
            else
              workitem[@name]['delete_error'] = true
              logger.info(\"CloudStack error while deleting resource \#{@name}\")
            end
          else
            logger.info(\"Resource #{@name} not created in CloudStack. Skipping delete...\")
          end
        rescue Exception => e
          logger.error(\"Unable to delete resorce \#{@name}\")
        end
      end

      def on_workitem
        @name = workitem.participant_name
        @props = workitem['Resources'][@name]['Properties']
        @props.downcase_key
        @resolved_names = workitem['ResolvedNames']
        if workitem['params']['operation'] == 'create'
          create
        else
          delete
        end
        reply
      end
      "
      #resolve
      required_fields.each do |required,type|
        str = str + "
      def get_#{required}
        resolved_#{required} = get_resolved(@props[\"#{required}\"],workitem)
        if resolved_#{required}.nil? || !validate_param(resolved_#{required},\"#{type}\")
          raise \"Missing mandatory parameter #{required} for resource \#{@name}\"
        end
        resolved_#{required}
      end      
      "
      end
      #Just keep separate for now
      optional_fields.each do |optional,type|
        str = str +"
      def get_#{optional}
        resolved_#{optional} = get_resolved(@props['#{optional}'],workitem)
        if resolved_#{optional}.nil? || !validate_param(resolved_#{optional},\"#{type}\")
          raise \"Malformed optional parameter #{optional} for resource \#{@name}\"
        end
        resolved_#{optional}
      end\n"
      end
      str = str + "  end
end
    "
      File.open("lib/stackmate/participants/cloudstack_" + class_name.downcase + ".rb" ,"w") { |file| file.write(str)}
    end

    def self.meta_class(class_name,create_tag,required_fields,optional_fields,create_async,delete_tag,delete_id_tag,delete_async)
      async={}
      async[true] = 'make_async_request'
      async[false] = 'make_sync_request'
      create_request = async[create_async]
      delete_request = async[delete_async]
      str = "   class CloudStack" + class_name + " < CloudStackResource"
      str = str + "\n
    include Logging
    include Intrinsic
    include Resolver
      def create
        logger.debug(\"Creating resource \#{@name}\")
        workitem[@name] = {}
        name_cs = workitem['StackName'] + '-' + @name
        args={}
        begin
        "
      #get required fields
      required_fields.each do |required,type|
        str = str + "          args['#{required}'] = get_#{required}\n"
      end
      #populate optional fields
      optional_fields.each do |optional,type|
        str = str + "          args['#{optional}'] = get_#{optional} if @props.has_key?('#{optional}')\n"
      end
      #raise error if some required field is missing
      str = str + "
        rescue Exception => e
          #logging.error(\"Missing required parameter for resource \#{@name}\")
          logger.error(e.message)
          raise e
        end
        "

      #make API call, populate workitem object
      str = str + "
        logger.info(\"Creating resource \#{@name} with following arguments\")
        p args
        result_obj = #{create_request}('#{create_tag}#{class_name}',args)
        resource_obj = result_obj['#{class_name}'.downcase]
        #doing it this way since it is easier to change later, rather than cloning whole object
        resource_obj.each_key do |k|
          val = resource_obj[k]
          if('id'.eql?(k))
            k = 'physical_id'
          end
          workitem[@name][k] = val
        end
        workitem['ResolvedNames'][@name] = name_cs
        workitem['IdMap'][workitem[@name]['physical_id']] = @name
      end
      "
      str = str + "
      def delete
        logger.debug(\"Deleting resource \#{@name}\")
        begin
          physical_id = workitem[@name]['physical_id']
          if(!physical_id.nil?)
            args = {'#{delete_id_tag}' => physical_id
                  }
            result_obj = #{delete_request}('#{delete_tag}#{class_name}',args)
            if (!result_obj.empty?)
              logger.info(\"Successfully deleted resource \#{@name}\")
            else
              logger.info(\"CloudStack error while deleting resource \#{@name}\")
            end
          else
            logger.info(\"Resource #{@name} not created in CloudStack. Skipping delete...\")
          end
        rescue Exception => e
          logger.error(\"Unable to delete resorce \#{@name}\")
        end
      end

      def on_workitem
        @name = workitem.participant_name
        @props = workitem['Resources'][@name]['Properties']
        @resolved_names = workitem['ResolvedNames']
        if workitem['params']['operation'] == 'create'
          create
        else
          delete
        end
        reply
      end
      "
      #resolve
      required_fields.each do |required,type|
        str = str + "
      def get_#{required}
        resolved_#{required} = get_resolved(@props[\"#{required}\"],workitem)
        if resolved_#{required}.nil? || !validate_param(resolved_#{required},\"#{type}\")
          raise \"Missing mandatory parameter #{required} for resource \#{@name}\"
        end
        resolved_#{required}
      end      
      "
      end
      #Just keep separate for now
      optional_fields.each do |optional,type|
        str = str + "
      def get_#{optional}
        resolved_#{optional} = get_resolved(@props['#{optional}'],workitem)
        if resolved_#{optional}.nil? || !validate_param(resolved_#{optional},\"#{type}\")
          raise \"Malformed optional parameter #{optional} for resource \#{@name}\"
        end
        resolved_#{optional}
      end
      "
      end
      str = str + "end
    "
      eval(str)
    end
    #CloudStackFactory.create_class("VPC",{},{})
    #CloudStackFactory.print_class("VPC","create",["name","networkdomain","cidr"],["displaytext","account"],"delete","vpcid")
  end

end

Web Proxy Viewer  |  New URL  |  Original Page