Repository: softlayer/softlayer-python
Pull request #2091 (2023-09-15 17:38:09)

added force feature for hardware poweron and poweroff
Hi @allmightyspiff,

Fixes: #2038 

Title:
Sub feature was missing in slcli hardware power-off, slcli hardware power-on please add it.

Description:
I have added force feature for slcli hardware power-off, slcli hardware power-on commands.

Please review it.

Thanks,
Ramkishor Chaladi.


Patch:
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index adc5408b..19d4bd81 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -39,11 +39,11 @@ jobs:
 
     steps:
     - name: Checkout repository
-      uses: actions/checkout@v4
+      uses: actions/checkout@v2
 
     # Initializes the CodeQL tools for scanning.
     - name: Initialize CodeQL
-      uses: github/codeql-action/init@v2
+      uses: github/codeql-action/init@v1
       with:
         languages: ${{ matrix.language }}
         # If you wish to specify custom queries, you can do so here or in a config file.
@@ -54,7 +54,7 @@ jobs:
     # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).
     # If this step fails, then you should remove it and run the build manually (see below)
     - name: Autobuild
-      uses: github/codeql-action/autobuild@v2
+      uses: github/codeql-action/autobuild@v1
 
     # ℹ️ Command-line programs to run using the OS shell.
     # 📚 https://git.io/JvXDl
@@ -68,4 +68,4 @@ jobs:
     #   make release
 
     - name: Perform CodeQL Analysis
-      uses: github/codeql-action/analyze@v2
+      uses: github/codeql-action/analyze@v1
diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml
index f0935473..d307fd93 100644
--- a/.github/workflows/documentation.yml
+++ b/.github/workflows/documentation.yml
@@ -10,12 +10,12 @@ jobs:
     runs-on: ubuntu-latest
     strategy:
       matrix:
-        python-version: [3.11]
+        python-version: [3.8]
 
     steps:
-    - uses: actions/checkout@v4
+    - uses: actions/checkout@v2
     - name: Set up Python ${{ matrix.python-version }}
-      uses: actions/setup-python@v4
+      uses: actions/setup-python@v1
       with:
         python-version: ${{ matrix.python-version }}
     - name: Install dependencies
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 95afeced..f307200d 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -1,6 +1,3 @@
-# https://packaging.python.org/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/
-# Trusted Publisher stuff: https://docs.pypi.org/trusted-publishers/adding-a-publisher/
-
 name: Release to PyPi
 
 on:
@@ -11,17 +8,12 @@ jobs:
   build-n-publish:
     name: Build and publish Python 🐍 distributions 📦 to PyPI and TestPyPI
     runs-on: ubuntu-latest
-    environment:
-      name: pypi
-      url: https://pypi.org/project/SoftLayer/
-    permissions:
-      id-token: write
     steps:
-    - uses: actions/checkout@v4
-    - name: Set up Python 3.11
-      uses: actions/setup-python@v4
+    - uses: actions/checkout@master
+    - name: Set up Python 3.8
+      uses: actions/setup-python@v2
       with:
-        python-version: 3.11
+        python-version: 3.8
     - name: Install pypa/build
       run: >-
         python -m
@@ -36,6 +28,10 @@ jobs:
         --wheel
         --outdir dist/
         .
-    - name: 📦 to PyPI
+    - name: Publish 📦 to Test PyPI
       uses: pypa/gh-action-pypi-publish@release/v1
+      with:
+        user: __token__
+        password: ${{ secrets.CGALLO_PYPI }}
+        repository_url: https://upload.pypi.org/legacy/
 
diff --git a/SoftLayer/CLI/file/cancel.py b/SoftLayer/CLI/file/cancel.py
index 9837f9fa..34077fbb 100644
--- a/SoftLayer/CLI/file/cancel.py
+++ b/SoftLayer/CLI/file/cancel.py
@@ -16,21 +16,14 @@
               is_flag=True,
               help="Cancels the file storage volume immediately instead "
                    "of on the billing anniversary")
-@click.option('--force', default=False, is_flag=True, help="Force modify")
 @environment.pass_env
-def cli(env, volume_id, reason, immediate, force):
-    """Cancel an existing file storage volume.
-
-    EXAMPLE::
-        slcli file volume-cancel 12345678 --immediate -f
-        This command cancels volume with ID 12345678 immediately and without asking for confirmation.
-    """
+def cli(env, volume_id, reason, immediate):
+    """Cancel an existing file storage volume."""
 
     file_storage_manager = SoftLayer.FileStorageManager(env.client)
 
-    if not force:
-        if not (env.skip_confirmations or formatting.no_going_back(volume_id)):
-            raise exceptions.CLIAbort('Aborted.')
+    if not (env.skip_confirmations or formatting.no_going_back(volume_id)):
+        raise exceptions.CLIAbort('Aborted')
 
     cancelled = file_storage_manager.cancel_file_volume(volume_id,
                                                         reason, immediate)
diff --git a/SoftLayer/CLI/file/duplicate.py b/SoftLayer/CLI/file/duplicate.py
index 50c7c6ea..b8b5983b 100644
--- a/SoftLayer/CLI/file/duplicate.py
+++ b/SoftLayer/CLI/file/duplicate.py
@@ -5,7 +5,6 @@
 import SoftLayer
 from SoftLayer.CLI import environment
 from SoftLayer.CLI import exceptions
-from SoftLayer.CLI import formatting
 
 
 CONTEXT_SETTINGS = {'token_normalize_func': lambda x: x.upper()}
@@ -59,17 +58,11 @@
               show_default=True,
               help='Whether or not this duplicate will be a dependent duplicate'
                    'of the origin volume.')
-@click.option('--force', default=False, is_flag=True, help="Force modify")
 @environment.pass_env
 def cli(env, origin_volume_id, origin_snapshot_id, duplicate_size,
         duplicate_iops, duplicate_tier, duplicate_snapshot_size, billing,
-        dependent_duplicate, force):
-    """Order a duplicate file storage volume.
-
-    EXAMPLE::
-        slcli file volume-duplicate 12345678
-        This command shows order a new volume by duplicating the volume with ID 12345678.
-    """
+        dependent_duplicate):
+    """Order a duplicate file storage volume."""
     file_manager = SoftLayer.FileStorageManager(env.client)
 
     hourly_billing_flag = False
@@ -79,11 +72,6 @@ def cli(env, origin_volume_id, origin_snapshot_id, duplicate_size,
     if duplicate_tier is not None:
         duplicate_tier = float(duplicate_tier)
 
-    if not force:
-        if not (env.skip_confirmations or formatting.confirm("This action will incur charges on your account."
-                                                             "Continue?")):
-            raise exceptions.CLIAbort('Aborted.')
-
     try:
         order = file_manager.order_duplicate_volume(
             origin_volume_id,
diff --git a/SoftLayer/CLI/file/limit.py b/SoftLayer/CLI/file/limit.py
index 1437578c..e0243ddc 100644
--- a/SoftLayer/CLI/file/limit.py
+++ b/SoftLayer/CLI/file/limit.py
@@ -18,12 +18,7 @@
 @click.option('--datacenter', '-d', help='Filter by datacenter')
 @environment.pass_env
 def cli(env, sortby, datacenter):
-    """List number of block storage volumes limit per datacenter.
-
-    EXAMPLE:
-        slcli file volume-limits
-        This command lists the storage limits per datacenter for this account.
-    """
+    """List number of block storage volumes limit per datacenter."""
     file_manager = SoftLayer.FileStorageManager(env.client)
     file_volumes = file_manager.list_file_volume_limit()
 
diff --git a/SoftLayer/CLI/file/replication/order.py b/SoftLayer/CLI/file/replication/order.py
index ae9e517d..14e4ae15 100644
--- a/SoftLayer/CLI/file/replication/order.py
+++ b/SoftLayer/CLI/file/replication/order.py
@@ -5,7 +5,6 @@
 import SoftLayer
 from SoftLayer.CLI import environment
 from SoftLayer.CLI import exceptions
-from SoftLayer.CLI import formatting
 from SoftLayer.CLI import helpers
 from SoftLayer import utils
 
@@ -28,47 +27,21 @@
               help='Endurance Storage Tier (IOPS per GB) of the primary'
               ' volume for which a replicant is ordered [optional]',
               type=click.Choice(['0.25', '2', '4', '10']))
-@click.option('--iops', '-i', type=int,
-              help='Performance Storage IOPs, between 100 and 6000 in multiples of 100,'
-              'if no IOPS value is specified, the IOPS value of the original volume will be used',
-              )
-@click.option('--force', default=False, is_flag=True, help="Force cancel block volume without confirmation")
 @environment.pass_env
-def cli(env, volume_id, snapshot_schedule, location, tier, iops, force):
-    """Order a file storage replica volume.
-
-    Example::
-        slcli file replica-order 12345678 -s DAILY -d dal09 --tier 4 --os-type LINUX
-        This command orders a replica for volume with ID 12345678, which performs DAILY
-        replication, is located at dal09, tier level is 4, OS type is Linux.
-    """
+def cli(env, volume_id, snapshot_schedule, location, tier):
+    """Order a file storage replica volume."""
     file_manager = SoftLayer.FileStorageManager(env.client)
     file_volume_id = helpers.resolve_id(file_manager.resolve_ids, volume_id, 'File Storage')
 
     if tier is not None:
         tier = float(tier)
 
-    if iops is not None:
-        if iops < 100 or iops > 6000:
-            raise exceptions.CLIHalt("-i|--iops must be between 100 and 6000, inclusive. "
-                                     "Run 'slcli block volume-options' to check available options.")
-
-        if iops % 100 != 0:
-            raise exceptions.CLIHalt("-i|--iops must be a multiple of 100. "
-                                     "Run 'slcli block volume-options' to check available options.")
-
-    if not force:
-        if not (env.skip_confirmations or
-                formatting.confirm(f"This will Order a file storage replica volume: {volume_id} "
-                                   "and cannot be undone. Continue?")):
-            raise exceptions.CLIAbort('Aborted.')
-
     try:
         order = file_manager.order_replicant_volume(
             file_volume_id,
             snapshot_schedule=snapshot_schedule,
             location=location,
-            tier=tier, iops=iops,
+            tier=tier,
         )
     except ValueError as ex:
         raise exceptions.ArgumentError(str(ex))
diff --git a/SoftLayer/CLI/file/replication/partners.py b/SoftLayer/CLI/file/replication/partners.py
index 6305cbf7..e4eb971d 100644
--- a/SoftLayer/CLI/file/replication/partners.py
+++ b/SoftLayer/CLI/file/replication/partners.py
@@ -21,12 +21,7 @@
               default=','.join(DEFAULT_COLUMNS))
 @environment.pass_env
 def cli(env, columns, sortby, volume_id):
-    """List existing replicant volumes for a file volume.
-
-    Example::
-        slcli file replica-partners 12345678
-        This command lists existing replicant volumes for block volume with ID 12345678.
-    """
+    """List existing replicant volumes for a file volume."""
     file_storage_manager = SoftLayer.FileStorageManager(env.client)
 
     legal_volumes = file_storage_manager.get_replication_partners(
diff --git a/SoftLayer/CLI/file/snapshot/cancel.py b/SoftLayer/CLI/file/snapshot/cancel.py
index ea78f138..d2b9f815 100644
--- a/SoftLayer/CLI/file/snapshot/cancel.py
+++ b/SoftLayer/CLI/file/snapshot/cancel.py
@@ -16,21 +16,14 @@
               is_flag=True,
               help="Cancels the snapshot space immediately instead "
                    "of on the billing anniversary")
-@click.option('--force', default=False, is_flag=True, help="Force cancel block volume without confirmation")
 @environment.pass_env
-def cli(env, volume_id, reason, immediate, force):
-    """Cancel existing snapshot space for a given volume.
-
-    Example::
-        slcli file snapshot-cancel 12345678 --immediate -f
-        This command cancels snapshot with ID 12345678 immediately without asking for confirmation.
-    """
+def cli(env, volume_id, reason, immediate):
+    """Cancel existing snapshot space for a given volume."""
 
     file_storage_manager = SoftLayer.FileStorageManager(env.client)
 
-    if not force:
-        if not (env.skip_confirmations or formatting.no_going_back(volume_id)):
-            raise exceptions.CLIAbort('Aborted.')
+    if not (env.skip_confirmations or formatting.no_going_back(volume_id)):
+        raise exceptions.CLIAbort('Aborted')
 
     cancelled = file_storage_manager.cancel_snapshot_space(
         volume_id, reason, immediate)
diff --git a/SoftLayer/CLI/hardware/cancel.py b/SoftLayer/CLI/hardware/cancel.py
index ed8633fc..8af07787 100644
--- a/SoftLayer/CLI/hardware/cancel.py
+++ b/SoftLayer/CLI/hardware/cancel.py
@@ -20,9 +20,8 @@
               help="An optional comment to add to the cancellation ticket")
 @click.option('--reason',
               help="An optional cancellation reason. See cancel-reasons for a list of available options")
-@click.option('--force',  default=False, is_flag=True, help="Force modify")
 @environment.pass_env
-def cli(env, identifier, immediate, comment, reason, force):
+def cli(env, identifier, immediate, comment, reason):
     """Cancel a dedicated server."""
 
     mgr = SoftLayer.HardwareManager(env.client)
@@ -31,9 +30,4 @@ def cli(env, identifier, immediate, comment, reason, force):
     if not (env.skip_confirmations or formatting.no_going_back(hw_id)):
         raise exceptions.CLIAbort('Aborted')
 
-    if not force:
-        if not (env.skip_confirmations or
-                formatting.confirm("This action will incur charges on your account. Continue?")):
-            raise exceptions.CLIAbort('Aborted')
-
     mgr.cancel_hardware(hw_id, reason, comment, immediate)
diff --git a/SoftLayer/CLI/hardware/create.py b/SoftLayer/CLI/hardware/create.py
index eaa9e0a2..3547344a 100644
--- a/SoftLayer/CLI/hardware/create.py
+++ b/SoftLayer/CLI/hardware/create.py
@@ -37,9 +37,8 @@
               help="The ID of the private ROUTER on which you want the virtual server placed")
 @helpers.multi_option('--key', '-k', help="SSH keys to add to the root user")
 @helpers.multi_option('--extra', '-e', help="Extra option Key Names")
-@click.option('--force',  default=False, is_flag=True, help="Force modify")
 @environment.pass_env
-def cli(env, force, **args):
+def cli(env, **args):
     """Order/create a dedicated server."""
     mgr = SoftLayer.HardwareManager(env.client)
     network = SoftLayer.NetworkManager(env.client)
@@ -106,10 +105,9 @@ def cli(env, force, **args):
         for pod in pods:
             if args.get('datacenter') in pod['name']:
                 click.secho(f"Warning: Closed soon: {pod['name']}", fg='yellow')
-        if not force:
-            if not (env.skip_confirmations or formatting.confirm(
-                    "This action will incur charges on your account. Continue?")):
-                raise exceptions.CLIAbort('Aborting dedicated server order.')
+        if not (env.skip_confirmations or formatting.confirm(
+                "This action will incur charges on your account. Continue?")):
+            raise exceptions.CLIAbort('Aborting dedicated server order.')
 
         result = mgr.place_order(**order)
 
diff --git a/SoftLayer/CLI/hardware/power.py b/SoftLayer/CLI/hardware/power.py
index 4947535f..06ccc384 100644
--- a/SoftLayer/CLI/hardware/power.py
+++ b/SoftLayer/CLI/hardware/power.py
@@ -12,16 +12,18 @@
 
 @click.command(cls=SoftLayer.CLI.command.SLCommand, )
 @click.argument('identifier')
+@click.option('--force', default=False, is_flag=True, help="Force modify")
 @environment.pass_env
-def power_off(env, identifier):
+def power_off(env, identifier, force):
     """Power off an active server."""
 
     mgr = SoftLayer.HardwareManager(env.client)
     hw_id = helpers.resolve_id(mgr.resolve_ids, identifier, 'hardware')
-    if not (env.skip_confirmations or
-            formatting.confirm('This will power off the server with id %s '
-                               'Continue?' % hw_id)):
-        raise exceptions.CLIAbort('Aborted.')
+    if not force:
+        if not (env.skip_confirmations or
+                formatting.confirm('This will power off the server with id %s '
+                                   'Continue?' % hw_id)):
+            raise exceptions.CLIAbort('Aborted.')
 
     env.client['Hardware_Server'].powerOff(id=hw_id)
 
@@ -53,12 +55,20 @@ def reboot(env, identifier, hard):
 
 @click.command(cls=SoftLayer.CLI.command.SLCommand, )
 @click.argument('identifier')
+@click.option('--force', default=False, is_flag=True, help="Force modify")
 @environment.pass_env
-def power_on(env, identifier):
+def power_on(env, identifier, force):
     """Power on a server."""
 
     mgr = SoftLayer.HardwareManager(env.client)
     hw_id = helpers.resolve_id(mgr.resolve_ids, identifier, 'hardware')
+
+    if not force:
+        if not (env.skip_confirmations or
+                formatting.confirm('This will power off the server with id %s. '
+                                   'Continue?' % hw_id)):
+            raise exceptions.CLIAbort('Aborted.')
+
     env.client['Hardware_Server'].powerOn(id=hw_id)
 
 
diff --git a/SoftLayer/CLI/image/__init__.py b/SoftLayer/CLI/image/__init__.py
index 14a4dc5f..d53152d0 100644
--- a/SoftLayer/CLI/image/__init__.py
+++ b/SoftLayer/CLI/image/__init__.py
@@ -5,10 +5,9 @@
 
 MASK = ('id,createDate,note,accountId,name,globalIdentifier,parentId,publicFlag,flexImageFlag,'
         'imageType,children[blockDevices[diskImage[softwareReferences[softwareDescription]]]]')
-DETAIL_MASK = ('id,createDate,note,accountId,name,globalIdentifier,parentId,publicFlag,flexImageFlag,'
-               'imageType,firstChild,children[id,blockDevicesDiskSpaceTotal,datacenter,'
-               'transaction[transactionGroup,transactionStatus],'
-               'blockDevices[diskImage[capacity,name,units,softwareReferences[softwareDescription]],diskSpace]],'
-               'status,transaction,accountReferences')
+DETAIL_MASK = MASK + (',firstChild,children[id,blockDevicesDiskSpaceTotal,datacenter,'
+                      'transaction[transactionGroup,transactionStatus],'
+                      'blockDevices[diskImage[capacity,name,units,softwareReferences[softwareDescription]],diskSpace]],'
+                      'note,createDate,status,transaction,accountReferences')
 PUBLIC_TYPE = formatting.FormattedItem('PUBLIC', 'Public')
 PRIVATE_TYPE = formatting.FormattedItem('PRIVATE', 'Private')
diff --git a/SoftLayer/CLI/loadbal/health.py b/SoftLayer/CLI/loadbal/health.py
index 10619d94..00107229 100644
--- a/SoftLayer/CLI/loadbal/health.py
+++ b/SoftLayer/CLI/loadbal/health.py
@@ -17,13 +17,7 @@
 @click.option('--url', '-u', help="Url path for HTTP/HTTPS checks.")
 @environment.pass_env
 def cli(env, identifier, uuid, interval, retry, timeout, url):
-    """Manage LBaaS health checks.
-
-    Example::
-
-        slcli loadbal health-edit (--lb-id LOADBAL_ID) (--health-uuid HEALTH_CHECK_UUID) [-i, --interval INTERVAL]
-        [-r, --retry RETRY] [-t, --timeout TIMEOUT] [-u, --url URL]
-    """
+    """Manage LBaaS health checks."""
 
     if not any([interval, retry, timeout, url]):
         raise exceptions.ArgumentError("Specify either interval, retry, timeout, url")
diff --git a/SoftLayer/CLI/loadbal/layer7_policy_list.py b/SoftLayer/CLI/loadbal/layer7_policy_list.py
index d304def1..60c93897 100644
--- a/SoftLayer/CLI/loadbal/layer7_policy_list.py
+++ b/SoftLayer/CLI/loadbal/layer7_policy_list.py
@@ -13,12 +13,7 @@
               help="Front-end Protocol identifier")
 @environment.pass_env
 def policies(env, protocol_id):
-    """List policies of the front-end protocol (listener).
-
-    Example::
-
-        slcli loadbal l7policies (--protocol-id PROTOCOL_ID)
-    """
+    """List policies of the front-end protocol (listener)."""
     mgr = SoftLayer.LoadBalancerManager(env.client)
 
     if protocol_id:
diff --git a/SoftLayer/CLI/loadbal/order.py b/SoftLayer/CLI/loadbal/order.py
index 9fe7cf44..532bd3ba 100644
--- a/SoftLayer/CLI/loadbal/order.py
+++ b/SoftLayer/CLI/loadbal/order.py
@@ -153,19 +153,13 @@ def order_options(env, datacenter):
 
 @click.command(cls=SoftLayer.CLI.command.SLCommand, )
 @click.argument('identifier')
-@click.option('--force', default=False, is_flag=True, help="Force cancel LBaaS Instance without confirmation")
 @environment.pass_env
-def cancel(env, identifier, force):
+def cancel(env, identifier):
     """Cancels a LBaaS instance"""
 
     mgr = SoftLayer.LoadBalancerManager(env.client)
     uuid, _ = mgr.get_lbaas_uuid_id(identifier)
 
-    if not force:
-        if not (env.skip_confirmations or
-                formatting.confirm("This will cancel the LBaaS Instance and cannot be undone. Continue?")):
-            raise exceptions.CLIAbort('Aborted')
-
     try:
         mgr.cancel_lbaas(uuid)
         click.secho(f"LB {identifier} canceled succesfully.", fg='green')
diff --git a/SoftLayer/CLI/loadbal/pools.py b/SoftLayer/CLI/loadbal/pools.py
index 8ef46737..e33f2696 100644
--- a/SoftLayer/CLI/loadbal/pools.py
+++ b/SoftLayer/CLI/loadbal/pools.py
@@ -169,13 +169,6 @@ def l7pool_add(env, identifier, **args):
     """Adds a new l7 pool
 
     -S is in colon deliminated format to make grouping IP:port:weight a bit easier.
-
-    Example::
-
-        slcli loadbal l7pool-add (--id LOADBAL_ID) (-n, --name NAME) [-m, --method METHOD]
-        [-s, --server BACKEND_IP:PORT] [-p, --protocol PROTOCOL] [--health-path PATH]
-        [--health-interval INTERVAL] [--health-retry RETRY]
-        [--health-timeout TIMEOUT] [--sticky cookie | source-ip]
     """
 
     mgr = SoftLayer.LoadBalancerManager(env.client)
diff --git a/SoftLayer/CLI/vpn/ipsec/cancel.py b/SoftLayer/CLI/vpn/ipsec/cancel.py
index 05688a10..66006991 100644
--- a/SoftLayer/CLI/vpn/ipsec/cancel.py
+++ b/SoftLayer/CLI/vpn/ipsec/cancel.py
@@ -5,8 +5,6 @@
 
 import SoftLayer
 from SoftLayer.CLI import environment
-from SoftLayer.CLI import exceptions
-from SoftLayer.CLI import formatting
 
 
 @click.command(cls=SoftLayer.CLI.command.SLCommand, )
@@ -17,9 +15,8 @@
               help="Cancels the service  immediately (instead of on the billing anniversary)")
 @click.option('--reason',
               help="An optional cancellation reason. See cancel-reasons for a list of available options")
-@click.option('--force', default=False, is_flag=True, help="Force cancel ipsec vpn without confirmation")
 @environment.pass_env
-def cli(env, identifier, immediate, reason, force):
+def cli(env, identifier, immediate, reason):
     """Cancel a IPSEC VPN tunnel context."""
 
     manager = SoftLayer.IPSECManager(env.client)
@@ -28,11 +25,6 @@ def cli(env, identifier, immediate, reason, force):
     if 'billingItem' not in context:
         raise SoftLayer.SoftLayerError("Cannot locate billing. May already be cancelled.")
 
-    if not force:
-        if not (env.skip_confirmations or
-                formatting.confirm("This will cancel the Ipsec Vpn and cannot be undone. Continue?")):
-            raise exceptions.CLIAbort('Aborted')
-
     result = manager.cancel_item(context['billingItem']['id'], immediate, reason)
 
     if result:
diff --git a/SoftLayer/CLI/vpn/ipsec/list.py b/SoftLayer/CLI/vpn/ipsec/list.py
index 652bd833..a9f8c703 100644
--- a/SoftLayer/CLI/vpn/ipsec/list.py
+++ b/SoftLayer/CLI/vpn/ipsec/list.py
@@ -9,10 +9,8 @@
 
 
 @click.command(cls=SoftLayer.CLI.command.SLCommand, )
-@click.option('--sortby', help='Column to sort by',
-              default='created')
 @environment.pass_env
-def cli(env, sortby):
+def cli(env):
     """List IPSec VPN tunnel contexts"""
     manager = SoftLayer.IPSECManager(env.client)
     contexts = manager.get_tunnel_contexts()
@@ -23,8 +21,6 @@ def cli(env, sortby):
                               'internal peer IP address',
                               'remote peer IP address',
                               'created'])
-    table.sortby = sortby
-
     for context in contexts:
         table.add_row([context.get('id', ''),
                        context.get('name', ''),
diff --git a/SoftLayer/consts.py b/SoftLayer/consts.py
index 0af80d99..4ed36b83 100644
--- a/SoftLayer/consts.py
+++ b/SoftLayer/consts.py
@@ -5,7 +5,7 @@
 
     :license: MIT, see LICENSE for more details.
 """
-VERSION = 'v6.1.8'
+VERSION = 'v6.1.7'
 API_PUBLIC_ENDPOINT = 'https://api.softlayer.com/xmlrpc/v3.1/'
 API_PRIVATE_ENDPOINT = 'https://api.service.softlayer.com/xmlrpc/v3.1/'
 API_PUBLIC_ENDPOINT_REST = 'https://api.softlayer.com/rest/v3.1/'
diff --git a/setup.py b/setup.py
index 46080cad..f2efcd9d 100644
--- a/setup.py
+++ b/setup.py
@@ -16,7 +16,7 @@
 
 setup(
     name='SoftLayer',
-    version='6.1.8',
+    version='6.1.7',
     description=DESCRIPTION,
     long_description=LONG_DESCRIPTION,
     long_description_content_type='text/x-rst',


Test patch:
diff --git a/.github/workflows/test_pypi_release.yml b/.github/workflows/test_pypi_release.yml
index 70245307..12443d25 100644
--- a/.github/workflows/test_pypi_release.yml
+++ b/.github/workflows/test_pypi_release.yml
@@ -1,27 +1,21 @@
 # https://packaging.python.org/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/
-# Trusted Publisher stuff: https://docs.pypi.org/trusted-publishers/adding-a-publisher/
 
-name: TEST Publish 📦 to TestPyPI
+name: Publish 📦 to TestPyPI
 
 on:
   push:
-    branches: [test-pypi]
+    branches: [test-pypi ]
 
 jobs:
   build-n-publish:
-    name: TEST Build and publish Python 🐍 distributions 📦 to PyPI and TestPyPI
+    name: Build and publish Python 🐍 distributions 📦 to PyPI and TestPyPI
     runs-on: ubuntu-latest
-    environment:
-      name: pypi-test
-      url: https://test.pypi.org/project/SoftLayer/
-    permissions:
-      id-token: write
     steps:
     - uses: actions/checkout@master
-    - name: Set up Python 3.11
-      uses: actions/setup-python@v4
+    - name: Set up Python 3.8
+      uses: actions/setup-python@v2
       with:
-        python-version: 3.11
+        python-version: 3.8
     - name: Install pypa/build
       run: >-
         python -m
@@ -37,6 +31,7 @@ jobs:
         --outdir dist/
         .
     - name: Publish 📦 to Test PyPI
-      uses: pypa/gh-action-pypi-publish@release/v1
+      uses: pypa/gh-action-pypi-publish@master
       with:
-        repository-url: https://test.pypi.org/legacy/
+        password: ${{ secrets.CGALLO_TEST_PYPI }}
+        repository_url: https://test.pypi.org/legacy/
\ No newline at end of file
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 9b079350..a9827899 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -13,9 +13,9 @@ jobs:
         python-version: [3.7,3.8,3.9,'3.10',3.11]
 
     steps:
-    - uses: actions/checkout@v4
+    - uses: actions/checkout@v2
     - name: Set up Python ${{ matrix.python-version }}
-      uses: actions/setup-python@v4
+      uses: actions/setup-python@v1
       with:
         python-version: ${{ matrix.python-version }}
     - name: Install dependencies
@@ -27,9 +27,9 @@ jobs:
   coverage:
     runs-on: ubuntu-latest
     steps:
-    - uses: actions/checkout@v4
+    - uses: actions/checkout@v2
     - name: Set up Python
-      uses: actions/setup-python@v4
+      uses: actions/setup-python@v1
       with:
         python-version: 3.9
     - name: Install dependencies
@@ -41,9 +41,9 @@ jobs:
   analysis:
     runs-on: ubuntu-latest
     steps:
-    - uses: actions/checkout@v4
+    - uses: actions/checkout@v2
     - name: Set up Python
-      uses: actions/setup-python@v4
+      uses: actions/setup-python@v1
       with:
         python-version: 3.9
     - name: Install dependencies
diff --git a/tests/CLI/modules/file_tests.py b/tests/CLI/modules/file_tests.py
index 5aafbbee..b9222574 100644
--- a/tests/CLI/modules/file_tests.py
+++ b/tests/CLI/modules/file_tests.py
@@ -828,39 +828,3 @@ def test_modify_order_no_force(self, confirm_mock):
 
         self.assertEqual(2, result.exit_code)
         self.assertEqual('Aborted', result.exception.message)
-
-    def test_file_replica_order_iops(self):
-        result_1 = self.run_command(['file', 'replica-order', '4917309', '-s', 'HOURLY', '-l', 'dal09', '-i', '121'])
-        self.assertEqual("-i|--iops must be a multiple of 100. "
-                         "Run 'slcli block volume-options' to check available options.\n", result_1.output)
-        result_2 = self.run_command(['file', 'replica-order', '4917309', '-s', 'HOURLY', '-l', 'dal09', '-i', '90'])
-        self.assertEqual("-i|--iops must be between 100 and 6000, inclusive. "
-                         "Run 'slcli block volume-options' to check available options.\n", result_2.output)
-
-    @mock.patch('SoftLayer.CLI.formatting.confirm')
-    def test_file_replica_order_force(self, confirm_mock):
-        confirm_mock.return_value = False
-        result = self.run_command(['file', 'replica-order', '4917309', '-s', 'HOURLY', '-l', 'dal09'])
-        self.assertEqual(2, result.exit_code)
-        self.assertEqual('Aborted.', result.exception.message)
-
-    @mock.patch('SoftLayer.CLI.formatting.confirm')
-    def test_file_snapshot_cancel_force(self, confirm_mock):
-        confirm_mock.return_value = False
-        result = self.run_command(['file', 'snapshot-cancel', '4917309'])
-        self.assertEqual(2, result.exit_code)
-        self.assertEqual('Aborted.', result.exception.message)
-
-    @mock.patch('SoftLayer.CLI.formatting.confirm')
-    def test_file_volume_cancel_force(self, confirm_mock):
-        confirm_mock.return_value = False
-        result = self.run_command(['file', 'volume-cancel', '1234'])
-        self.assertEqual(2, result.exit_code)
-        self.assertEqual('Aborted.', result.exception.message)
-
-    @mock.patch('SoftLayer.CLI.formatting.confirm')
-    def test_file_volume_duplicate_force(self, confirm_mock):
-        confirm_mock.return_value = False
-        result = self.run_command(['file', 'volume-duplicate', '100'])
-        self.assertEqual(2, result.exit_code)
-        self.assertEqual('Aborted.', result.exception.message)
diff --git a/tests/CLI/modules/server_tests.py b/tests/CLI/modules/server_tests.py
index 7a4d1de3..33c12567 100644
--- a/tests/CLI/modules/server_tests.py
+++ b/tests/CLI/modules/server_tests.py
@@ -321,6 +321,20 @@ def test_server_power_on(self):
         self.assert_called_with('SoftLayer_Hardware_Server', 'powerOn',
                                 identifier=12345)
 
+    @mock.patch('SoftLayer.CLI.formatting.confirm')
+    def test_harware_power_on_force(self, confirm_mock):
+        confirm_mock.return_value = False
+        result = self.run_command(['hardware', 'power-on', '12345'])
+        self.assertEqual(2, result.exit_code)
+        self.assertEqual('Aborted.', result.exception.message)
+
+    @mock.patch('SoftLayer.CLI.formatting.confirm')
+    def test_harware_power_off_force(self, confirm_mock):
+        confirm_mock.return_value = False
+        result = self.run_command(['hardware', 'power-off', '12345'])
+        self.assertEqual(2, result.exit_code)
+        self.assertEqual('Aborted.', result.exception.message)
+
     def test_server_power_cycle(self):
         result = self.run_command(['--really', 'server', 'power-cycle',
                                    '12345'])
@@ -922,7 +936,6 @@ def test_create_hw_no_confirm(self, confirm_mock):
                                    '--network=TEST_NETWORK', '--os=UBUNTU_12_64'])
 
         self.assertEqual(result.exit_code, 2)
-        self.assertEqual('Aborting dedicated server order.', result.exception.message)
 
     @mock.patch('SoftLayer.CLI.formatting.confirm')
     def test_authorize_hw_no_confirm(self, confirm_mock):
diff --git a/tests/managers/hardware_tests.py b/tests/managers/hardware_tests.py
index 05790469..e8f70840 100644
--- a/tests/managers/hardware_tests.py
+++ b/tests/managers/hardware_tests.py
@@ -1052,11 +1052,3 @@ def test_is_private(self):
         item_public = {'attributes': [{'attributeTypeKeyName': 'NOT_PRIVATE_NETWORK_ONLY'}]}
         self.assertTrue(managers.hardware._is_private_port_speed_item(item_private))
         self.assertFalse(managers.hardware._is_private_port_speed_item(item_public))
-
-    @mock.patch('SoftLayer.CLI.formatting.confirm')
-    def test_hardware_cancel_no_force(self, confirm_mock):
-        confirm_mock.return_value = False
-        result = self.run_command(['hardware', 'cancel', '102'])
-
-        self.assertEqual(2, result.exit_code)
-        self.assertEqual('Aborted', result.exception.message)