def decommission_asset_cp(updated_asset, asset_cp, change_plan):
    asset_data = RecursiveAssetSerializer(updated_asset).data
    asset_data["live_id"] = asset_data["id"]
    del asset_data["id"]
    asset_data["decommissioning_user"] = str(change_plan.owner)
    decommissioned_asset = AddDecommissionedAssetSerializer(data=asset_data)
    if not decommissioned_asset.is_valid(raise_exception=False):
        return JsonResponse(
            {
                "failure_message":
                Status.INVALID_INPUT.value +
                parse_serializer_errors(decommissioned_asset.errors),
                "errors":
                str(decommissioned_asset.errors),
            },
            status=HTTPStatus.BAD_REQUEST,
        )
    try:
        decommissioned_asset.save()
    except Exception as error:
        return JsonResponse(
            {
                "failure_message":
                Status.DECOMMISSION_ERROR.value +
                parse_save_validation_error(error, "Decommissioned Asset "),
                "errors":
                str(error),
            },
            status=HTTPStatus.BAD_REQUEST,
        )
    else:
        updated_asset.delete()
def change_plan_add(request):
    """
    Add a new change plan
    """
    data = JSONParser().parse(request)
    if "id" in data:
        return JsonResponse(
            {
                "failure_message": Status.CREATE_ERROR.value
                + GenericFailure.INTERNAL.value,
                "errors": "Don't include 'id' when creating a change planner",
            },
            status=HTTPStatus.BAD_REQUEST,
        )
    data["owner"] = request.user.id
    serializer = AddChangePlanSerializer(data=data)
    if not serializer.is_valid(raise_exception=False):
        return JsonResponse(
            {
                "failure_message": Status.INVALID_INPUT.value
                + parse_serializer_errors(serializer.errors),
                "errors": str(serializer.errors),
            },
            status=HTTPStatus.BAD_REQUEST,
        )
    try:
        change_plan = serializer.save()
    except Exception as error:
        return JsonResponse(
            {
                "failure_message": Status.CREATE_ERROR.value
                + parse_save_validation_error(error, "Change Plan"),
                "errors": str(error),
            },
            status=HTTPStatus.BAD_REQUEST,
        )
    return JsonResponse(
        {
            "success_message": Status.SUCCESS.value
            + "Change Plan "
            + str(change_plan.name)
            + " created",
            "related_id": str(change_plan.id),
        },
        status=HTTPStatus.OK,
    )
def change_plan_modify(request):
    """
    Modify single existing change plan
    """
    data = JSONParser().parse(request)
    if "id" not in data:
        return JsonResponse(
            {
                "failure_message": Status.MODIFY_ERROR.value
                + GenericFailure.INTERNAL.value,
                "errors": "Must include 'id' when modifying a change plan",
            },
            status=HTTPStatus.BAD_REQUEST,
        )
    id = data["id"]
    (existing_change_plan, failure_response) = get_change_plan(id)
    if failure_response:
        return failure_response
    failure_response = get_cp_already_executed_response(existing_change_plan)
    if failure_response:
        return failure_response
    for field in data.keys():
        value = data[field]
        setattr(existing_change_plan, field, value)
    try:
        existing_change_plan.save()
        return JsonResponse(
            {
                "success_message": Status.SUCCESS.value
                + "Change Plan "
                + str(existing_change_plan.name)
                + " modified",
                "related_id": str(existing_change_plan.id),
            },
            status=HTTPStatus.OK,
        )
    except Exception as error:
        return JsonResponse(
            {
                "failure_message": Status.MODIFY_ERROR.value
                + parse_save_validation_error(error, "Asset"),
                "errors": str(error),
            },
            status=HTTPStatus.BAD_REQUEST,
        )
Esempio n. 4
0
def save_all_field_data_live(data, asset):
    asset_id = data["id"]
    for field in data.keys():
        if field == "model" and data["model"]:
            value = ITModel.objects.get(id=data[field])
        elif field == "rack" and data["rack"]:
            value = Rack.objects.get(id=data[field])
        elif field == "chassis" and data["chassis"]:
            value = Asset.objects.get(id=data[field])
        elif field == "offline_storage_site" and data["offline_storage_site"]:
            value = Site.objects.get(id=data[field])
        elif field == "hostname" and data["hostname"]:
            assets_with_hostname = Asset.objects.filter(hostname__iexact=data[field])
            if len(assets_with_hostname) > 0 and assets_with_hostname[0].id != asset_id:
                return (
                    "Asset with hostname '" + data[field].lower() + "' already exists."
                )
            value = data[field]
        elif field == "asset_number":
            try: 
                int(data[field])
            except ValueError:
                return data[field] +  " is not a valid hostname. Asset number must be a number between 100000 and 999999"
            assets_with_asset_number = Asset.objects.filter(asset_number=data[field])
            if (
                data[field]
                and len(assets_with_asset_number) > 0
                and assets_with_asset_number[0].id != asset.id
            ):
                return (
                    "Asset with asset number '" + str(data[field]) + "' already exists."
                )
            value = data[field]
        else:
            value = data[field]

        if field is not "id":
            setattr(asset, field, value)
    try:
        asset.save()
    except Exception as error:
        return parse_save_validation_error(error, "Asset")
def asset_add(request):
    """
    Add a new asset.
    """
    data = JSONParser().parse(request)
    if "id" in data:
        return JsonResponse(
            {
                "failure_message": Status.CREATE_ERROR.value
                + GenericFailure.INTERNAL.value,
                "errors": "Don't include 'id' when creating an asset",
            },
            status=HTTPStatus.BAD_REQUEST,
        )
    (change_plan, failure_response) = get_change_plan(
        request.query_params.get("change_plan")
    )
    if failure_response:
        return failure_response
    chassis_id_live = None
    if change_plan:
        failure_response = get_cp_already_executed_response(change_plan)
        if failure_response:
            return failure_response
        data["change_plan"] = change_plan.id

        if data["chassis"] and not AssetCP.objects.filter(id=data["chassis"]).exists():
            # ignore the chassis because we will replace it with a new chassis on AssetCP later
            chassis_id_live = data["chassis"]
            del data["chassis"]

        serializer = AssetCPSerializer(data=data)
    else:
        serializer = AssetSerializer(data=data)
    if not serializer.is_valid(raise_exception=False):
        return JsonResponse(
            {
                "failure_message": Status.INVALID_INPUT.value
                + parse_serializer_errors(serializer.errors),
                "errors": str(serializer.errors),
            },
            status=HTTPStatus.BAD_REQUEST,
        )
    try:
        validate_user_permission_on_new_asset_data(
            request.user,
            serializer.validated_data,
            data_is_validated=True,
            change_plan=change_plan,
            chassis_id_live=chassis_id_live,
        )
    except UserAssetPermissionException as auth_error:
        return JsonResponse(
            {"failure_message": Status.AUTH_ERROR.value + str(auth_error)},
            status=HTTPStatus.UNAUTHORIZED,
        )
    except Exception as error:
        return JsonResponse(
            {"failure_message": Status.CREATE_ERROR.value + str(error)},
            status=HTTPStatus.BAD_REQUEST,
        )
    if not (
        "offline_storage_site" in serializer.validated_data
        and serializer.validated_data["offline_storage_site"]
    ):
        if serializer.validated_data["model"].is_rackmount():
            if (
                "rack" not in serializer.validated_data
                or not serializer.validated_data["rack"]
                or "rack_position" not in serializer.validated_data
                or not serializer.validated_data["rack_position"]
            ):
                return JsonResponse(
                    {
                        "failure_message": Status.INVALID_INPUT.value
                        + "Must include rack and rack position to add a rackmount asset. "
                    },
                    status=HTTPStatus.BAD_REQUEST,
                )
            rack_id = serializer.validated_data["rack"].id
            rack_position = serializer.validated_data["rack_position"]
            height = serializer.validated_data["model"].height
            try:
                validate_asset_location_in_rack(
                    rack_id, rack_position, height, change_plan=change_plan
                )
            except LocationException as error:
                return JsonResponse(
                    {"failure_message": Status.CREATE_ERROR.value + str(error)},
                    status=HTTPStatus.BAD_REQUEST,
                )
        else:
            if (
                (
                    (
                        "chassis" not in serializer.validated_data
                        or not serializer.validated_data["chassis"]
                    )
                    and not chassis_id_live
                )
                or "chassis_slot" not in serializer.validated_data
                or not serializer.validated_data["chassis_slot"]
            ):
                return JsonResponse(
                    {
                        "failure_message": Status.INVALID_INPUT.value
                        + "Must include chassis and chassis slot to add a blade asset. "
                    },
                    status=HTTPStatus.BAD_REQUEST,
                )

            if chassis_id_live:
                try:
                    chassis_live = Asset.objects.get(id=chassis_id_live)
                except ObjectDoesNotExist:
                    return JsonResponse(
                        {
                            "failure_message": Status.MODIFY_ERROR.value
                            + "Chassis"
                            + GenericFailure.DOES_NOT_EXIST.value,
                            "errors": "No existing chassis with id="
                            + str(chassis_id_live),
                        },
                        status=HTTPStatus.BAD_REQUEST,
                    )
                chassis_cp = add_chassis_to_cp(chassis_live, change_plan)
                chassis_id = chassis_cp.id
                serializer.validated_data["chassis"] = chassis_cp

            else:
                chassis_id = serializer.validated_data["chassis"].id
            chassis_slot = serializer.validated_data["chassis_slot"]
            try:
                validate_asset_location_in_chassis(
                    chassis_id, chassis_slot, change_plan=change_plan
                )
            except LocationException as error:
                return JsonResponse(
                    {"failure_message": Status.CREATE_ERROR.value + str(error)},
                    status=HTTPStatus.BAD_REQUEST,
                )
    try:
        asset = serializer.save()
    except Exception as error:
        return JsonResponse(
            {
                "failure_message": Status.CREATE_ERROR.value
                + parse_save_validation_error(error, "Asset"),
                "errors": str(error),
            },
            status=HTTPStatus.BAD_REQUEST,
        )

    warning_message = save_all_connection_data(
        data, asset, request.user, change_plan=change_plan
    )
    if warning_message:
        return JsonResponse({"warning_message": warning_message}, status=HTTPStatus.OK)
    if change_plan:
        return JsonResponse(
            {
                "success_message": Status.SUCCESS.value
                + "Asset created on change plan "
                + change_plan.name,
                "related_id": change_plan.id,
            },
            status=HTTPStatus.OK,
        )
    else:
        log_action(request.user, asset, Action.CREATE)
        return JsonResponse(
            {
                "success_message": Status.SUCCESS.value
                + "Asset "
                + str(asset.asset_number)
                + " created"
            },
            status=HTTPStatus.OK,
        )
def decommission_asset_parameterized(asset_id, query_params, user,
                                     change_plan):
    """
    Decommission a live asset
    """
    decommissioned_asset_cp = None
    if change_plan:
        response = get_cp_already_executed_response(change_plan)
        if response:
            return None, response
        assets, assets_cp = get_assets_for_cp(change_plan.id,
                                              show_decommissioned=True)
        if assets_cp.filter(related_asset=asset_id).exists():

            decommissioned_asset_cp = assets_cp.get(related_asset=asset_id)
            decommissioned_asset_cp.is_decommissioned = True
            asset_id = decommissioned_asset_cp.id
        elif assets_cp.filter(id=asset_id).exists():

            decommissioned_asset_cp = assets_cp.get(id=asset_id)
            decommissioned_asset_cp.is_decommissioned = True
            asset_id = decommissioned_asset_cp.id
        elif assets.filter(id=asset_id).exists():

            existing_asset = assets.get(id=asset_id)

            if existing_asset.model.is_blade_chassis():
                decommissioned_asset_cp = add_chassis_to_cp(
                    existing_asset, change_plan)

            else:
                chassis_cp = None
                if existing_asset.model.is_blade_asset(
                ) and existing_asset.chassis:
                    if not assets_cp.filter(
                            related_asset=existing_asset.chassis.id).exists():
                        chassis_cp = add_chassis_to_cp(
                            existing_asset.chassis,
                            change_plan,
                            ignore_blade_id=existing_asset.id,
                        )
                    else:
                        chassis_cp = assets_cp.get(
                            related_asset=existing_asset.chassis.id)

                decommissioned_asset_cp = copy_asset_to_new_asset_cp(
                    existing_asset, change_plan, chassis_cp=chassis_cp)
            decommissioned_asset_cp.is_decommissioned = True
            decommissioned_asset_cp.save()

        else:
            return (
                None,
                JsonResponse(
                    {
                        "failure_message":
                        Status.ERROR.value + "Asset" +
                        GenericFailure.DOES_NOT_EXIST.value,
                        "errors":
                        "No existing asset in change plan with id=" +
                        str(asset_id),
                    },
                    status=HTTPStatus.BAD_REQUEST,
                ),
            )
        try:
            validate_user_permission_on_existing_asset(
                user, decommissioned_asset_cp)
        except UserAssetPermissionException as auth_error:
            return (
                None,
                JsonResponse(
                    {
                        "failure_message":
                        Status.AUTH_ERROR.value + str(auth_error)
                    },
                    status=HTTPStatus.UNAUTHORIZED,
                ),
            )
        if asset_id != decommissioned_asset_cp.id:
            ## a new asset cp was created for decommissioning, blades are not on assetxp
            blades = assets.filter(chassis=asset_id)
        else:
            blades = assets_cp.filter(chassis=asset_id)
        for blade in blades:
            try:
                decommission_asset_parameterized(blade.id, query_params, user,
                                                 change_plan)
                # Assume that if this call doesn't raise an exception, it was successful
                # None of the failed responses above are possible
            except Exception as error:

                return (
                    None,
                    JsonResponse(
                        {
                            "failure_message":
                            Status.DECOMMISSION_ERROR.value +
                            "Unable to decommission blade: '" +
                            str(blade.asset_number) + "'. ",
                            "errors":
                            str(error),
                        },
                        status=HTTPStatus.BAD_REQUEST,
                    ),
                )
        try:
            decommissioned_asset_cp.save()

        except Exception as error:

            return (
                None,
                JsonResponse(
                    {
                        "failure_message":
                        Status.DECOMMISSION_ERROR.value +
                        parse_save_validation_error(error,
                                                    "Decommissioned Asset "),
                        "errors":
                        str(error),
                    },
                    status=HTTPStatus.BAD_REQUEST,
                ),
            )

        return (
            JsonResponse(
                {
                    "success_message":
                    "Asset successfully decommissioned on change plan: " +
                    change_plan.name
                },
                status=HTTPStatus.OK,
            ),
            None,
        )

    try:
        asset = Asset.objects.get(id=asset_id)
    except Asset.DoesNotExist:
        return (
            None,
            JsonResponse(
                {
                    "failure_message":
                    Status.ERROR.value + "Asset" +
                    GenericFailure.DOES_NOT_EXIST.value,
                    "errors":
                    "No existing asset with id=" + str(asset_id),
                },
                status=HTTPStatus.BAD_REQUEST,
            ),
        )
    try:
        validate_user_permission_on_existing_asset(user, asset)
    except UserAssetPermissionException as auth_error:
        return (
            None,
            JsonResponse(
                {"failure_message": Status.AUTH_ERROR.value + str(auth_error)},
                status=HTTPStatus.UNAUTHORIZED,
            ),
        )

    blades = Asset.objects.filter(chassis=asset.id)
    for blade in blades:
        try:
            decommission_asset_parameterized(blade.id, query_params, user,
                                             change_plan)
            # Assume that if this call doesn't raise an exception, it was successful
            # None of the failed responses above are possible
        except Exception as error:
            return (
                None,
                JsonResponse(
                    {
                        "failure_message":
                        Status.DECOMMISSION_ERROR.value +
                        "Unable to decommission blade: '" +
                        str(blade.asset_number) + "'. ",
                        "errors":
                        str(error),
                    },
                    status=HTTPStatus.BAD_REQUEST,
                ),
            )
    asset_data = RecursiveAssetSerializer(asset).data
    asset_data["live_id"] = asset_data["id"]
    del asset_data["id"]
    asset_data["decommissioning_user"] = str(user)
    decommissioned_asset = AddDecommissionedAssetSerializer(data=asset_data)
    if not decommissioned_asset.is_valid(raise_exception=False):
        return (
            None,
            JsonResponse(
                {
                    "failure_message":
                    Status.INVALID_INPUT.value +
                    parse_serializer_errors(decommissioned_asset.errors),
                    "errors":
                    str(decommissioned_asset.errors),
                },
                status=HTTPStatus.BAD_REQUEST,
            ),
        )
    try:
        decommissioned_asset_object = decommissioned_asset.save()
    except Exception as error:
        return (
            None,
            JsonResponse(
                {
                    "failure_message":
                    Status.DECOMMISSION_ERROR.value +
                    parse_save_validation_error(error,
                                                "Decommissioned Asset "),
                    "errors":
                    str(error),
                },
                status=HTTPStatus.BAD_REQUEST,
            ),
        )
    else:
        for assetcp in AssetCP.objects.filter(related_asset=asset_id):
            assetcp.related_decommissioned_asset = decommissioned_asset_object
            assetcp.save()
        log_action(
            user,
            asset,
            Action.DECOMMISSION,
        )
        return (
            JsonResponse(
                {"success_message": "Asset successfully decommissioned. "},
                status=HTTPStatus.OK,
            ),
            None,
        )
Esempio n. 7
0
def save_all_field_data_cp(data, asset, change_plan, create_asset_cp):
    asset_id = data["id"]
    for field in data.keys():
        if field == "model" and data["model"]:
            value = ITModel.objects.get(id=data[field])
        elif field == "rack" and data["rack"]:
            value = Rack.objects.get(id=data[field])
        elif field == "offline_storage_site" and data["offline_storage_site"]:
            value = Site.objects.get(id=data[field])
        elif field == "hostname" and data["hostname"]:
            assets, assets_cp = get_assets_for_cp(change_plan.id)
            assets_with_hostname = assets.filter(hostname__iexact=data[field])
            if not (
                len(assets_with_hostname) > 0 and assets_with_hostname[0].id != asset_id
            ):
                assets_with_hostname = assets_cp.filter(hostname__iexact=data[field])
            if len(assets_with_hostname) > 0 and assets_with_hostname[0].id != asset_id:
                return (
                    None,
                    "Asset with hostname '" + data[field].lower() + "' already exists.",
                )
            value = data[field]
        elif field == "asset_number":
            if create_asset_cp:
                related_asset = asset
            else:
                related_asset = asset.related_asset
            try:
                validate_asset_number_uniqueness(
                    data[field], asset_id, change_plan, related_asset,
                )
            except ValidationError:
                return (
                    None,
                    "Asset with asset number '"
                    + str(data[field])
                    + "' already exists.",
                )

            value = data[field]
        else:
            value = data[field]
        if field != "id" and field != "chassis":
            setattr(asset, field, value)
    chassis = None
    if data["chassis"]:
        try:
            chassis = AssetCP.objects.get(id=data["chassis"])
        except ObjectDoesNotExist:
            if Asset.objects.filter(id=data["chassis"]).exists():
                chassis_live = Asset.objects.get(id=data["chassis"])
                chassis = add_chassis_to_cp(
                    chassis_live, change_plan, ignore_blade_id=asset.id
                )
            else:
                return (
                    None,
                    "Chassis with id " + str(data["chassis"]) + " does not exist",
                )

    try:
        if create_asset_cp:
            if asset.model.is_blade_chassis():
                asset_cp = add_chassis_to_cp(asset, change_plan)
            else:
                asset_cp = copy_asset_to_new_asset_cp(
                    asset, change_plan, chassis_cp=chassis
                )
            asset_cp.save()
            return asset_cp, None

        else:
            asset.chassis = chassis
            asset.save()
            return asset, None
    except Exception as error:

        return None, parse_save_validation_error(error, "Asset")