Exemple #1
0
class NetworkSerializer(serializers.Serializer):
    id = serializers.CharField(read_only=True)
    url = CustomHyperlinkedIdentityField(view_name='network-detail',
                                         lookup_field='id',
                                         lookup_url_kwarg='pk',
                                         parent_url_kwargs=['cloud_pk'])
    name = serializers.CharField()
    state = serializers.CharField(read_only=True)
    cidr_block = serializers.CharField(read_only=True)
    subnets = CustomHyperlinkedIdentityField(view_name='subnet-list',
                                             lookup_field='id',
                                             lookup_url_kwarg='network_pk',
                                             parent_url_kwargs=['cloud_pk'])

    def create(self, validated_data):
        provider = view_helpers.get_cloud_provider(self.context.get('view'))
        return provider.network.create(name=validated_data.get('name'))

    def update(self, instance, validated_data):
        try:
            if instance.name != validated_data.get('name'):
                instance.name = validated_data.get('name')
            return instance
        except Exception as e:
            raise serializers.ValidationError("{0}".format(e))
Exemple #2
0
class CloudSerializer(serializers.ModelSerializer):
    slug = serializers.CharField(read_only=True)
    compute = CustomHyperlinkedIdentityField(view_name='compute-list',
                                             lookup_field='slug',
                                             lookup_url_kwarg='cloud_pk')
    security = CustomHyperlinkedIdentityField(view_name='security-list',
                                              lookup_field='slug',
                                              lookup_url_kwarg='cloud_pk')
    block_store = CustomHyperlinkedIdentityField(view_name='block_store-list',
                                                 lookup_field='slug',
                                                 lookup_url_kwarg='cloud_pk')
    object_store = CustomHyperlinkedIdentityField(
        view_name='object_store-list',
        lookup_field='slug',
        lookup_url_kwarg='cloud_pk')
    networks = CustomHyperlinkedIdentityField(view_name='network-list',
                                              lookup_field='slug',
                                              lookup_url_kwarg='cloud_pk')

    region_name = serializers.SerializerMethodField()

    def get_region_name(self, obj):
        if hasattr(obj, 'aws'):
            return obj.aws.compute.ec2_region_name
        elif hasattr(obj, 'openstack'):
            return obj.openstack.region_name
        else:
            return "Cloud provider not recognized"

    class Meta:
        model = models.Cloud
        exclude = ('kind', )
class CredentialsSerializer(serializers.Serializer):
    aws = CustomHyperlinkedIdentityField(view_name='awscredentials-list')
    openstack = CustomHyperlinkedIdentityField(
        view_name='openstackcredentials-list')
    azure = CustomHyperlinkedIdentityField(
        view_name='azurecredentials-list')
    gce = CustomHyperlinkedIdentityField(
        view_name='gcecredentials-list')
Exemple #4
0
class ComputeSerializer(serializers.Serializer):
    machine_images = CustomHyperlinkedIdentityField(
        view_name='machine_image-list', parent_url_kwargs=['cloud_pk'])
    instance_types = CustomHyperlinkedIdentityField(
        view_name='instance_type-list', parent_url_kwargs=['cloud_pk'])
    instances = CustomHyperlinkedIdentityField(view_name='instance-list',
                                               parent_url_kwargs=['cloud_pk'])
    regions = CustomHyperlinkedIdentityField(view_name='region-list',
                                             parent_url_kwargs=['cloud_pk'])
Exemple #5
0
class RegionSerializer(serializers.Serializer):
    id = serializers.CharField(read_only=True)
    url = CustomHyperlinkedIdentityField(view_name='region-detail',
                                         lookup_field='id',
                                         lookup_url_kwarg='pk',
                                         parent_url_kwargs=['cloud_pk'])
    name = serializers.CharField()
    zones = CustomHyperlinkedIdentityField(view_name='zone-list',
                                           lookup_field='id',
                                           lookup_url_kwarg='region_pk',
                                           parent_url_kwargs=['cloud_pk'])
Exemple #6
0
class SecurityGroupRuleSerializer(serializers.Serializer):
    ip_protocol = serializers.CharField(label="IP protocol", allow_blank=True)
    from_port = serializers.CharField(allow_blank=True)
    to_port = serializers.CharField(allow_blank=True)
    cidr_ip = serializers.CharField(label="CIDR IP", allow_blank=True)
    group = ProviderPKRelatedField(label="Source group",
                                   queryset='security.security_groups',
                                   display_fields=['name', 'id'],
                                   display_format="{0} (ID: {1})",
                                   required=False,
                                   allow_null=True)
    url = CustomHyperlinkedIdentityField(
        view_name='security_group_rule-detail',
        lookup_field='id',
        lookup_url_kwarg='pk',
        parent_url_kwargs=['cloud_pk', 'security_group_pk'])

    def create(self, validated_data):
        view = self.context.get('view')
        provider = view_helpers.get_cloud_provider(view)
        sg_pk = view.kwargs.get('security_group_pk')
        if sg_pk:
            sg = provider.security.security_groups.get(sg_pk)
            if sg and validated_data.get('group'):
                return sg.add_rule(src_group=validated_data.get('group'))
            elif sg:
                return sg.add_rule(validated_data.get('ip_protocol'),
                                   validated_data.get('from_port'),
                                   validated_data.get('to_port'),
                                   validated_data.get('cidr_ip'))
        return None
Exemple #7
0
class UserSerializer(UserDetailsSerializer):
    credentials = CustomHyperlinkedIdentityField(
        view_name='credentialsroute-list', lookup_field=None)
    aws_creds = serializers.SerializerMethodField()
    openstack_creds = serializers.SerializerMethodField()

    def get_aws_creds(self, obj):
        """
        Include a URL for listing this bucket's contents
        """
        try:
            creds = obj.userprofile.credentials.filter(
                awscredentials__isnull=False).select_subclasses()
            return AWSCredsSerializer(instance=creds,
                                      many=True,
                                      context=self.context).data
        except models.UserProfile.DoesNotExist:
            return ""

    def get_openstack_creds(self, obj):
        """
        Include a URL for listing this bucket's contents
        """
        try:
            creds = obj.userprofile.credentials.filter(
                openstackcredentials__isnull=False).select_subclasses()
            return OpenstackCredsSerializer(instance=creds,
                                            many=True,
                                            context=self.context).data
        except models.UserProfile.DoesNotExist:
            return ""

    class Meta(UserDetailsSerializer.Meta):
        fields = UserDetailsSerializer.Meta.fields + \
            ('aws_creds', 'openstack_creds', 'credentials')
Exemple #8
0
class MachineImageSerializer(serializers.Serializer):
    id = serializers.CharField(read_only=True)
    url = CustomHyperlinkedIdentityField(view_name='machine_image-detail',
                                         lookup_field='id',
                                         lookup_url_kwarg='pk',
                                         parent_url_kwargs=['cloud_pk'])
    name = serializers.CharField()
    description = serializers.CharField()
Exemple #9
0
class BucketSerializer(serializers.Serializer):
    id = serializers.CharField(read_only=True)
    url = CustomHyperlinkedIdentityField(view_name='bucket-detail',
                                         lookup_field='id',
                                         lookup_url_kwarg='pk',
                                         parent_url_kwargs=['cloud_pk'])
    name = serializers.CharField()
    objects = CustomHyperlinkedIdentityField(view_name='bucketobject-list',
                                             lookup_field='id',
                                             lookup_url_kwarg='bucket_pk',
                                             parent_url_kwargs=['cloud_pk'])

    def create(self, validated_data):
        provider = view_helpers.get_cloud_provider(self.context.get('view'))
        try:
            return provider.object_store.create(validated_data.get('name'))
        except Exception as e:
            raise serializers.ValidationError("{0}".format(e))
class SecurityGroupSerializer(serializers.Serializer):
    id = serializers.CharField(read_only=True)
    url = CustomHyperlinkedIdentityField(view_name='security_group-detail',
                                         lookup_field='id',
                                         lookup_url_kwarg='pk',
                                         parent_url_kwargs=['cloud_pk'])
    name = serializers.CharField()
    # Technically, the description is required but when wanting to reuse an
    # existing security group with a different resource (eg, creating an
    # instance), we need to be able to call this serializer w/o it.
    description = serializers.CharField(required=False)
    rules = CustomHyperlinkedIdentityField(view_name='security_group_rule-list',
                                           lookup_field='id',
                                           lookup_url_kwarg='security_group_pk',
                                           parent_url_kwargs=['cloud_pk'])

    def create(self, validated_data):
        provider = view_helpers.get_cloud_provider(self.context.get('view'))
        return provider.security.security_groups.create(
            validated_data.get('name'), validated_data.get('description'))
Exemple #11
0
class KeyPairSerializer(serializers.Serializer):
    id = serializers.CharField(read_only=True)
    url = CustomHyperlinkedIdentityField(view_name='keypair-detail',
                                         lookup_field='id',
                                         lookup_url_kwarg='pk',
                                         parent_url_kwargs=['cloud_pk'])
    name = serializers.CharField()
    material = serializers.CharField(read_only=True)

    def create(self, validated_data):
        provider = view_helpers.get_cloud_provider(self.context.get('view'))
        return provider.security.key_pairs.create(validated_data.get('name'))
Exemple #12
0
class AttachmentInfoSerializer(serializers.Serializer):
    device = serializers.CharField(read_only=True)
    instance_id = ProviderPKRelatedField(label="Instance ID",
                                         queryset='compute.instances',
                                         display_fields=['name', 'id'],
                                         display_format="{0} (ID: {1})",
                                         required=False,
                                         allow_null=True)

    instance = CustomHyperlinkedIdentityField(view_name='instance-detail',
                                              lookup_field='instance_id',
                                              lookup_url_kwarg='pk',
                                              parent_url_kwargs=['cloud_pk'])
Exemple #13
0
class InstanceTypeSerializer(serializers.Serializer):
    id = serializers.CharField(read_only=True)
    url = CustomHyperlinkedIdentityField(view_name='instance_type-detail',
                                         lookup_field='pk',
                                         parent_url_kwargs=['cloud_pk'])
    name = serializers.CharField()
    family = serializers.CharField()
    vcpus = serializers.CharField()
    ram = serializers.CharField()
    size_root_disk = serializers.CharField()
    size_ephemeral_disks = serializers.CharField()
    num_ephemeral_disks = serializers.CharField()
    size_total_disk = serializers.CharField()
    extra_data = serializers.DictField(serializers.CharField())
class VolumeSerializer(serializers.Serializer):
    id = serializers.CharField(read_only=True)
    url = CustomHyperlinkedIdentityField(view_name='volume-detail',
                                         lookup_field='id',
                                         lookup_url_kwarg='pk',
                                         parent_url_kwargs=['cloud_pk'])
    name = serializers.CharField()
    description = serializers.CharField(allow_blank=True)
    size = serializers.IntegerField(min_value=0)
    create_time = serializers.CharField(read_only=True)
    zone_id = PlacementZonePKRelatedField(label="Zone",
                                          queryset='non_empty_value',
                                          display_fields=[
                                              'id'],
                                          display_format="{0}",
                                          required=True)
    state = serializers.CharField(read_only=True)
    snapshot_id = ProviderPKRelatedField(label="Snapshot ID",
                                         queryset='block_store.snapshots',
                                         display_fields=[
                                             'name', 'id', 'size'],
                                         display_format="{0} (ID: {1},"
                                         " Size: {2} GB)",
                                         write_only=True,
                                         required=False,
                                         allow_null=True)

    attachments = AttachmentInfoSerializer()

    def create(self, validated_data):
        provider = view_helpers.get_cloud_provider(self.context.get('view'))
        try:
            return provider.block_store.volumes.create(
                validated_data.get('name'),
                validated_data.get('size'),
                validated_data.get('zone_id'),
                description=validated_data.get('description'),
                snapshot=validated_data.get('snapshot_id'))
        except Exception as e:
            raise serializers.ValidationError("{0}".format(e))

    def update(self, instance, validated_data):
        try:
            if instance.name != validated_data.get('name'):
                instance.name = validated_data.get('name')
            if instance.description != validated_data.get('description'):
                instance.description = validated_data.get('description')
            return instance
        except Exception as e:
            raise serializers.ValidationError("{0}".format(e))
class SubnetSerializer(serializers.Serializer):
    id = serializers.CharField(read_only=True)
    url = CustomHyperlinkedIdentityField(view_name='subnet-detail',
                                         lookup_field='id',
                                         lookup_url_kwarg='pk',
                                         parent_url_kwargs=['cloud_pk',
                                                            'network_pk'])
    name = serializers.CharField(allow_blank=True)
    cidr_block = serializers.CharField()
    network_id = serializers.CharField(read_only=True)

    def create(self, validated_data):
        provider = view_helpers.get_cloud_provider(self.context.get('view'))
        net_id = self.context.get('view').kwargs.get('network_pk')
        return provider.network.subnets.create(
            net_id, validated_data.get('cidr_block'),
            name=validated_data.get('name'))
Exemple #16
0
class BucketObjectSerializer(serializers.Serializer):
    id = serializers.CharField(read_only=True)
    name = serializers.CharField(allow_blank=True)
    size = serializers.IntegerField(read_only=True)
    last_modified = serializers.CharField(read_only=True)
    url = CustomHyperlinkedIdentityField(
        view_name='bucketobject-detail',
        lookup_field='id',
        lookup_url_kwarg='pk',
        parent_url_kwargs=['cloud_pk', 'bucket_pk'])
    download_url = serializers.SerializerMethodField()
    upload_content = serializers.FileField(write_only=True)

    def get_download_url(self, obj):
        """Create a URL for accessing a single instance."""
        kwargs = self.context['view'].kwargs.copy()
        kwargs.update({'pk': obj.id})
        obj_url = reverse('bucketobject-detail',
                          kwargs=kwargs,
                          request=self.context['request'])
        return urllib.parse.urljoin(obj_url, '?format=binary')

    def create(self, validated_data):
        provider = view_helpers.get_cloud_provider(self.context.get('view'))
        bucket_id = self.context.get('view').kwargs.get('bucket_pk')
        bucket = provider.object_store.get(bucket_id)
        try:
            name = validated_data.get('name')
            content = validated_data.get('upload_content')
            if name:
                object = bucket.create_object(name)
            else:
                object = bucket.create_object(content.name)
            if content:
                object.upload(content.file.getvalue())
            return object
        except Exception as e:
            raise serializers.ValidationError("{0}".format(e))

    def update(self, instance, validated_data):
        try:
            instance.upload(
                validated_data.get('upload_content').file.getvalue())
            return instance
        except Exception as e:
            raise serializers.ValidationError("{0}".format(e))
class SnapshotSerializer(serializers.Serializer):
    id = serializers.CharField(read_only=True)
    url = CustomHyperlinkedIdentityField(view_name='snapshot-detail',
                                         lookup_field='id',
                                         lookup_url_kwarg='pk',
                                         parent_url_kwargs=['cloud_pk'])
    name = serializers.CharField()
    description = serializers.CharField()
    state = serializers.CharField(read_only=True)
    volume_id = ProviderPKRelatedField(label="Volume ID",
                                       queryset='block_store.volumes',
                                       display_fields=[
                                             'name', 'id', 'size'],
                                       display_format="{0} (ID: {1},"
                                       " Size: {2} GB)",
                                       required=True)
    create_time = serializers.CharField(read_only=True)
    size = serializers.IntegerField(min_value=0, read_only=True)

    def create(self, validated_data):
        provider = view_helpers.get_cloud_provider(self.context.get('view'))
        try:
            return provider.block_store.snapshots.create(
                validated_data.get('name'),
                validated_data.get('volume_id'),
                description=validated_data.get('description'))
        except Exception as e:
            raise serializers.ValidationError("{0}".format(e))

    def update(self, instance, validated_data):
        try:
            if instance.name != validated_data.get('name'):
                instance.name = validated_data.get('name')
            if instance.description != validated_data.get('description'):
                instance.description = validated_data.get('description')
            return instance
        except Exception as e:
            raise serializers.ValidationError("{0}".format(e))
Exemple #18
0
class BlockStoreSerializer(serializers.Serializer):
    volumes = CustomHyperlinkedIdentityField(view_name='volume-list',
                                             parent_url_kwargs=['cloud_pk'])
    snapshots = CustomHyperlinkedIdentityField(view_name='snapshot-list',
                                               parent_url_kwargs=['cloud_pk'])
Exemple #19
0
class SecuritySerializer(serializers.Serializer):
    keypairs = CustomHyperlinkedIdentityField(view_name='keypair-list',
                                              parent_url_kwargs=['cloud_pk'])
    security_groups = CustomHyperlinkedIdentityField(
        view_name='security_group-list', parent_url_kwargs=['cloud_pk'])
Exemple #20
0
class CloudSerializer(serializers.ModelSerializer):
    slug = serializers.CharField(read_only=True)
    compute = CustomHyperlinkedIdentityField(view_name='compute-list',
                                             lookup_field='slug',
                                             lookup_url_kwarg='cloud_pk')
    security = CustomHyperlinkedIdentityField(view_name='security-list',
                                              lookup_field='slug',
                                              lookup_url_kwarg='cloud_pk')
    block_store = CustomHyperlinkedIdentityField(view_name='block_store-list',
                                                 lookup_field='slug',
                                                 lookup_url_kwarg='cloud_pk')
    object_store = CustomHyperlinkedIdentityField(
        view_name='object_store-list',
        lookup_field='slug',
        lookup_url_kwarg='cloud_pk')
    networks = CustomHyperlinkedIdentityField(view_name='network-list',
                                              lookup_field='slug',
                                              lookup_url_kwarg='cloud_pk')
    static_ips = CustomHyperlinkedIdentityField(view_name='static_ip-list',
                                                lookup_field='slug',
                                                lookup_url_kwarg='cloud_pk')
    cloudman = CustomHyperlinkedIdentityField(view_name='cloudman-list',
                                              lookup_field='slug',
                                              lookup_url_kwarg='cloud_pk')
    region_name = serializers.SerializerMethodField()

    cloud_type = serializers.SerializerMethodField()
    extra_data = serializers.SerializerMethodField()

    def get_region_name(self, obj):
        if hasattr(obj, 'aws'):
            return obj.aws.compute.ec2_region_name
        elif hasattr(obj, 'openstack'):
            return obj.openstack.region_name
        elif hasattr(obj, 'azure'):
            return obj.azure.region_name
        else:
            return "Cloud provider not recognized"

    def get_cloud_type(self, obj):
        if hasattr(obj, 'aws'):
            return 'aws'
        elif hasattr(obj, 'openstack'):
            return 'openstack'
        elif hasattr(obj, 'azure'):
            return 'azure'
        else:
            return 'unknown'

    def get_extra_data(self, obj):
        if hasattr(obj, 'aws'):
            aws = obj.aws
            extra_data = {}
            if aws.compute:
                compute = aws.compute
                extra_data['ec2_region_name'] = compute.ec2_region_name
                extra_data['ec2_region_endpoint'] = compute.ec2_region_endpoint
                extra_data['ec2_conn_path'] = compute.ec2_conn_path
                extra_data['ec2_port'] = compute.ec2_port
                extra_data['ec2_is_secure'] = compute.ec2_is_secure
            if aws.object_store:
                s3 = aws.object_store
                extra_data['s3_host'] = s3.s3_host
                extra_data['s3_conn_path'] = s3.s3_conn_path
                extra_data['s3_port'] = s3.s3_port
                extra_data['s3_is_secure'] = s3.s3_is_secure
            return extra_data
        elif hasattr(obj, 'openstack'):
            os = obj.openstack
            return {
                'auth_url': os.auth_url,
                'region_name': os.region_name,
                'identity_api_version': os.identity_api_version
            }
        elif hasattr(obj, 'azure'):
            azure = obj.azure
            return {
                'region_name': azure.region_name,
                'resource_group': azure.resource_group,
                'storage_account': azure.storage_account,
                'azure_vm_default_user_name': azure.azure_vm_default_user_name
            }
        else:
            return {}

    class Meta:
        model = models.Cloud
        exclude = ('kind', )
class DeploymentSerializer(serializers.ModelSerializer):
    owner = serializers.CharField(read_only=True)
    name = serializers.CharField(required=True)
    provider_settings = serializers.CharField(read_only=True)
    application_config = StoredJSONField(read_only=True)
    application = serializers.CharField(write_only=True, required=True)
    config_app = serializers.JSONField(write_only=True, required=False)
    app_version_details = DeploymentAppVersionSerializer(source="application_version", read_only=True)
    latest_task = serializers.SerializerMethodField()
    tasks = CustomHyperlinkedIdentityField(view_name='deployment_task-list',
                                           lookup_field='id',
                                           lookup_url_kwarg='deployment_pk')

    class Meta:
        model = models.ApplicationDeployment
        fields = ('id','name', 'application', 'application_version', 'target_cloud', 'provider_settings',
                  'application_config', 'added', 'updated', 'owner', 'config_app', 'app_version_details',
                  'tasks', 'latest_task')

    def get_latest_task(self, obj):
        """Provide task info about the most recenly updated deployment task."""
        try:
            task = models.ApplicationDeploymentTask.objects.filter(
                deployment=obj.id).latest('updated')
            return DeploymentTaskSerializer(
                task, context={'request': self.context['request'],
                               'deployment_pk': obj.id}).data
        except models.ApplicationDeploymentTask.DoesNotExist:
            return None

    def to_internal_value(self, data):
        application = data.get('application')
        version = data.get('application_version')
        if version:
            version = models.ApplicationVersion.objects.get(application=application, version=version)
            data['application_version'] = version.id
        return super(DeploymentSerializer, self).to_internal_value(data)

    def create(self, validated_data):
        """
        Create a new ApplicationDeployment object.

        Called automatically by the DRF following a POST request.
        """
        name = validated_data.get("name")
        cloud = validated_data.get("target_cloud")
        version = validated_data.get("application_version")
        cloud_version_config = models.ApplicationVersionCloudConfig.objects.get(
            application_version=version.id, cloud=cloud.slug)
        default_combined_config = cloud_version_config.compute_merged_config()
        request = self.context.get('view').request
        provider = view_helpers.get_cloud_provider(
            self.context.get('view'), cloud_id=cloud.slug)
        credentials = view_helpers.get_credentials(cloud, request)
        try:
            handler = util.import_class(version.backend_component_name)()
            app_config = validated_data.get("config_app", {})

            merged_config = jsonmerge.merge(default_combined_config, app_config)
            cloud_config = util.serialize_cloud_config(cloud_version_config)
            final_ud_config = handler.process_app_config(
                provider, name, cloud_config, merged_config)
            sanitised_app_config = handler.sanitise_app_config(merged_config)
            async_result = tasks.launch_appliance.delay(
                name, cloud_version_config, credentials, merged_config,
                final_ud_config)

            del validated_data['application']
            del validated_data['config_app']
            validated_data['owner_id'] = request.user.id
            validated_data['application_config'] = json.dumps(merged_config)
            app_deployment = super(DeploymentSerializer, self).create(validated_data)
            self.log_usage(cloud_version_config, app_deployment, sanitised_app_config, request.user)
            models.ApplicationDeploymentTask.objects.create(
                action=models.ApplicationDeploymentTask.LAUNCH,
                deployment=app_deployment, celery_id=async_result.task_id)
            return app_deployment
        except serializers.ValidationError as ve:
            raise ve
        except Exception as e:
            raise serializers.ValidationError({ "error" : str(e) })

    def log_usage(self, app_version_cloud_config, app_deployment, sanitised_app_config, user):
        u = models.Usage(app_version_cloud_config=app_version_cloud_config,
                         app_deployment=app_deployment, app_config=sanitised_app_config, user=user)
        u.save()
Exemple #22
0
class ObjectStoreSerializer(serializers.Serializer):
    buckets = CustomHyperlinkedIdentityField(view_name='bucket-list',
                                             parent_url_kwargs=['cloud_pk'])
Exemple #23
0
class InstanceSerializer(serializers.Serializer):
    id = serializers.CharField(read_only=True)
    url = CustomHyperlinkedIdentityField(view_name='instance-detail',
                                         lookup_field='id',
                                         lookup_url_kwarg='pk',
                                         parent_url_kwargs=['cloud_pk'])
    name = serializers.CharField()
    public_ips = serializers.ListField(serializers.IPAddressField())
    private_ips = serializers.ListField(serializers.IPAddressField())
    instance_type_id = ProviderPKRelatedField(
        label="Instance Type",
        queryset='compute.instance_types',
        display_fields=['name'],
        display_format="{0}",
        required=True)
    instance_type_url = CustomHyperlinkedIdentityField(
        view_name='instance_type-detail',
        lookup_field='instance_type_id',
        lookup_url_kwarg='pk',
        parent_url_kwargs=['cloud_pk'])
    image_id = ProviderPKRelatedField(label="Image",
                                      queryset='compute.images',
                                      display_fields=['name', 'id'],
                                      display_format="{0} ({1})",
                                      required=True)
    image_id_url = CustomHyperlinkedIdentityField(
        view_name='machine_image-detail',
        lookup_field='image_id',
        lookup_url_kwarg='pk',
        parent_url_kwargs=['cloud_pk'])
    key_pair_name = ProviderPKRelatedField(label="Keypair Name",
                                           queryset='security.key_pairs',
                                           display_fields=['id'],
                                           display_format="{0}",
                                           required=True)
    zone_id = PlacementZonePKRelatedField(label="Placement Zone",
                                          queryset='non_empty_value',
                                          display_fields=['id'],
                                          display_format="{0}",
                                          required=True)
    security_group_ids = ProviderPKRelatedField(
        label="Security Groups",
        queryset='security.security_groups',
        display_fields=['name'],
        display_format="{0}",
        many=True)
    user_data = serializers.CharField(write_only=True,
                                      style={'base_template': 'textarea.html'})

    def create(self, validated_data):
        provider = view_helpers.get_cloud_provider(self.context.get('view'))
        name = validated_data.get('name')
        image_id = validated_data.get('image_id')
        instance_type = validated_data.get('instance_type_id')
        kp_name = validated_data.get('key_pair_name')
        zone_id = validated_data.get('zone_id')
        security_group_ids = validated_data.get('security_group_ids')
        user_data = validated_data.get('user_data')
        try:
            return provider.compute.instances.create(
                name,
                image_id,
                instance_type,
                zone=zone_id,
                key_pair=kp_name,
                security_groups=security_group_ids,
                user_data=user_data)
        except Exception as e:
            raise serializers.ValidationError("{0}".format(e))

    def update(self, instance, validated_data):
        try:
            if instance.name != validated_data.get('name'):
                instance.name = validated_data.get('name')
            return instance
        except Exception as e:
            raise serializers.ValidationError("{0}".format(e))
class DeploymentTaskSerializer(serializers.ModelSerializer):
    url = CustomHyperlinkedIdentityField(view_name='deployment_task-detail',
                                         lookup_field='id',
                                         lookup_url_kwarg='pk',
                                         parent_url_kwargs=['deployment_pk',
                                                            'deployment_task_pk'])
    deployment = serializers.CharField(read_only=True)
    celery_id = serializers.CharField(read_only=True)
    action = serializers.ChoiceField(
        choices=models.ApplicationDeploymentTask.ACTION_CHOICES,
        initial=models.ApplicationDeploymentTask.HEALTH_CHECK)
    status = serializers.CharField(read_only=True)
    result = serializers.CharField(read_only=True)
    traceback = serializers.CharField(read_only=True)

    class Meta:
        model = models.ApplicationDeploymentTask
        exclude = ('deployment', '_result', '_status')

    def create(self, validated_data):
        """
        Fire off a new task for the supplied action.

        Called automatically by the DRF following a POST request.

        :type validated_data: ``dict``
        :param validated_data: Dict containing action the task should perform.
                               Valid actions are `HEALTH_CHECK`, `DELETE`.
        """
        print("deployment task data: %s" % validated_data)
        action = getattr(models.ApplicationDeploymentTask,
                         validated_data.get(
                            'action',
                            models.ApplicationDeploymentTask.HEALTH_CHECK))
        request = self.context.get('view').request
        dpk = self.context['view'].kwargs.get('deployment_pk')
        dpl = models.ApplicationDeployment.objects.get(id=dpk)
        credentials = view_helpers.get_credentials(dpl.target_cloud, request)
        try:
            if action == models.ApplicationDeploymentTask.HEALTH_CHECK:
                async_result = tasks.health_check.delay(dpl, credentials)
            elif action == models.ApplicationDeploymentTask.RESTART:
                async_result = tasks.manage_appliance.delay('restart', dpl,
                                                            credentials)
            elif action == models.ApplicationDeploymentTask.DELETE:
                async_result = tasks.manage_appliance.delay('delete', dpl,
                                                            credentials)
            return models.ApplicationDeploymentTask.objects.create(
                action=action, deployment=dpl, celery_id=async_result.task_id)
        except serializers.ValidationError as ve:
            raise ve
        except Exception as e:
            raise serializers.ValidationError({"error": str(e)})

    def validate_action(self, value):
        """Make sure only one LAUNCH task exists per deployment."""
        if value == models.ApplicationDeploymentTask.LAUNCH:
            dpk = self.context['view'].kwargs.get('deployment_pk')
            dpl = models.ApplicationDeployment.objects.get(id=dpk)
            if models.ApplicationDeploymentTask.objects.filter(
                    deployment=dpl,
                    action=models.ApplicationDeploymentTask.LAUNCH):
                raise serializers.ValidationError(
                    "Duplicate LAUNCH action for deployment %s" % dpl.name)
        return value.upper()