Global Administration#

Instantiate a Global Admin object#

class cterasdk.object.Portal.GlobalAdmin(host=None, port=None, https=True, *, url=None)

Class for Global Administrator Functions

Variables:
__init__(host=None, port=None, https=True, *, url=None)
Parameters:
  • host (str) – The fully qualified domain name, hostname or an IPv4 address of the Portal

  • port (int,optional) – Set a custom port number (0 - 65535), If not set defaults to 80 for http and 443 for https

  • https (bool,optional) – Set to True to require HTTPS, defaults to True

admin = GlobalAdmin('portal.ctera.com') # will use HTTPS over port 443

Warning

for any certificate related error, this library will prompt for your consent in order to proceed. to avoid the prompt, you may configure this library to automatically trust the server’s certificate, using: config.http['ssl'] = 'Trust'

Setup#

Setup.init_master(name, email, first_name, last_name, password, domain)

Initialize the CTERA Portal master server.

Parameters:
  • name (str) – User name for the new user

  • email (str) – E-mail address of the new user

  • first_name (str) – The first name of the new user

  • last_name (str) – The last name of the new user

  • password (str) – Password for the new user

  • domain (str) – The domain suffix for CTERA Portal

admin.init_master('admin', 'bruce.wayne@we.com', 'Bruce', 'Wayne', 'password1!', 'ctera.me')
Setup.init_application_server(ipaddr, secret)

Initialize a CTERA Portal Application Server.

Parameters:
  • ipaddr (str) – The CTERA Portal master server IP address

  • secret (str) – A password or a PEM-encoded private key

"""Connect a secondary Portal server using a password"""
master_ipaddr = '172.31.53.246'
master_password = 'secret'
admin.init_application_server(master_ipaddr, master_password)

"""Connect a secondary Portal server using a private key"""
master_ipaddr = '172.31.53.246'
master_pk = """...PEM-encoded private key..."""
admin.init_application_server(master_ipaddr, master_pk)
Setup.init_replication_server(ipaddr, secret, replicate_from=None)

Initialize a CTERA Portal Database Replication Server.

Parameters:
  • ipaddr (str) – The CTERA Portal master server IP address

  • secret (str) – A password or a PEM-encoded private key

  • replicate_from (str) – The name of a CTERA Portal server to replicate from

Logging in#

GlobalAdmin.test()

Verification check to ensure the target host is a Portal.

admin.test()
GlobalAdmin.login(username, password)

Log in

Parameters:
  • username (str) – User name to log in

  • password (str) – User password

admin.login('admin', 'G3neralZ0d!')
GlobalAdmin.logout()

Log out

admin.logout()
GlobalAdmin.whoami()

Return the name of the logged in user.

Return cterasdk.common.object.Object:

The session object of the current user

admin.whoami()

Core Methods#

GlobalAdmin.show(path, use_file_url=False)

Print a schema object as a JSON string.

GlobalAdmin.show_multi(path, paths, use_file_url=False)

Print one or more schema objects as a JSON string.

GlobalAdmin.get(path, params=None, use_file_url=False)

Retrieve a schema object as a Python object.

GlobalAdmin.put(path, value, use_file_url=False)

Update a schema object or attribute.

GlobalAdmin.execute(path, name, param=None, use_file_url=False)

Execute a schema object method.

GlobalAdmin.query(path, name, param)
GlobalAdmin.show_query(path, name, param)

Licenses#

Licenses.all()

Retrieve a list of installed licenses

Returns:

A list of licenses

Return type:

list[cterasdk.common.object.Object]

Licenses.add(*keys)

Add license keys

Parameters:

keys (list[str]) – List of license keys

admin.licenses.add('ABCD', 'EFGH', 'IJKL')
Licenses.remove(*keys)

Remove license keys

Returns:

A list of installed licenses

Return type:

list[cterasdk.common.object.Object]

admin.licenses.remove('ABCD')

Storage Classes#

StorageClasses.add(name)

Add a storage class

Parameters:

name (str) – Name

admin.storage_classes.add('Archive')
StorageClasses.all()

Get storage classes

Returns:

List of storage classes

Return type:

list(cterasdk.common.object.Object)

for storage_class in admin.storage_classes.all():
    print(storage_class)
StorageClasses.get(name)

Get storage class

Parameters:

name (str) – Storage class name, defaults to None

Returns:

Storage class

Return type:

cterasdk.common.object.Object

print(admin.storage_classes.get('Archive'))

Storage Nodes#

Buckets.get(name, include=None)

Get a Bucket

Parameters:
  • name (str) – Name of the bucket

  • include (list[str]) – List of fields to retrieve, defaults to ['name']

bucket = admin.buckets.get('MainStorage')
print(bucket)

bucket = admin.buckets.get('MainStorage', include=['bucket', 'driver'])
print(bucket.name, bucket.bucket, bucket.driver)
Buckets.add(name, bucket, read_only=False, dedicated_to=None)

Add a Bucket

Parameters:
  • name (str) – Name of the bucket

  • bucket (cterasdk.core.types.Bucket) – Storage bucket to add

  • read_only (bool,optional) – Set bucket to read-delete only, defaults to False

  • dedicated_to (str,optional) – Name of a tenant, defaults to None

"""Add an Amazon S3 bucket called 'mybucket'"""
bucket = portal_types.AmazonS3('mybucket', 'access-key', 'secret-key')
admin.buckets.add('cterabucket', bucket)

"""Add an Amazon S3 bucket called 'mybucket', dedicated to a tenant called 'mytenant'"""
bucket = portal_types.AmazonS3('mybucket', 'access-key', 'secret-key')
admin.buckets.add('cterabucket', bucket, dedicated_to='mytenant')

"""Add a bucket in read-delete only mode"""
bucket = portal_types.AmazonS3('mybucket', 'access-key', 'secret-key')
admin.buckets.add('cterabucket', bucket, read_only=True)
Buckets.modify(current_name, new_name=None, read_only=None, dedicated_to=None)

Modify a Bucket

Parameters:
  • current_name (str) – The current bucket name

  • new_name (str,optional) – New name

  • read_only (bool,optional) – Set bucket to read-delete only

  • dedicated (bool,optional) – Dedicate bucket to a tenant

  • dedicated_to (str,optional) – Tenant name

"""Modify an existing bucket, set it to read-delete only and dedicate it to 'mytenant'"""
admin.buckets.modify('MainStorage', read_only=True, dedicated_to='mytenant')
Buckets.list_buckets(include=None)

List Buckets.

To retrieve buckets, you must first browse the Global Administration Portal, using: GlobalAdmin.portals.browse_global_admin()

Parameters:

include (list[str],optional) – List of fields to retrieve, defaults to ['name']

for bucket in admin.buckets.list_buckets():
    print(bucket)
Buckets.delete(name)

Delete a Bucket

Parameters:

name (str) – Name of the bucket

admin.buckets.delete('MainStorage')
Buckets.read_write(name)

Set bucket to Read Write

Parameters:

name (str) – Name of the bucket

admin.buckets.read_write('MainStorage')
Buckets.read_only(name)

Set bucket to Read Only

Parameters:

name (str) – Name of the bucket

admin.buckets.read_only('MainStorage')

Portals#

Retrieve Portals#

Portals.list_tenants(include=None, portal_type=None)

List tenants.

To retrieve tenants, you must first browse the Global Administration Portal, using: GlobalAdmin.portals.browse_global_admin()

Parameters:
  • include (list[str],optional) – List of fields to retrieve, defaults to [‘name’]

  • portal_type (cterasdk.core.enum.PortalType) – The Portal type

"""List all tenants"""
for tenant in admin.portals.list_tenants():
    print(tenant)

"""List Team Portals. For each tenant, retrieve its creation date, subscription plan and activation status"""
for tenant in admin.portals.list_tenants(include=['createDate', 'plan', 'activationStatus'], portal_type=portal_enum.PortalType.Team):
    print(tenant)
Portals.tenants(include_deleted=False)

Get all tenants

Parameters:

include_deleted (bool,optional) – Include deleted tenants, defaults to False

for tenant in admin.portals.tenants():
    print(tenant.name, tenant.usedStorageQuota, tenant.totalStorageQuota)

Create a Team Portal#

Portals.add(name, display_name=None, billing_id=None, company=None, plan=None, comment=None)

Add a new tenant

Parameters:
  • name (str) – Name of the new tenant

  • display_name (str,optional) – Display Name of the new tenant, defaults to None

  • billing_id (str,optional) – Billing ID of the new tenant, defaults to None

  • company (str,optional) – Company Name of the new tenant, defaults to None

  • plan (str,optional) – Subscription plan name to assign to the new tenant, defaults to None

  • comment (str,optional) – Assign a comment to the new tenant, defaults to None

Return str:

A relative url path to the Team Portal

"""Create a Team Portal"""

admin.portals.add('acme')

"""Create a Team Portal, including a display name, billing id and a company name"""

admin.portals.add('ctera', 'CTERA', 'Tz9YRDSd8LNfaouzr3Db', 'CTERA Networks')

"""Create a Team Portal and assign it to a pre-configured subscription plan"""
admin.portals.add('ctera', plan = 'Default')

Subscribe a Team Portal to a Plan#

Portals.subscribe(tenant, plan)

Subscribe a tenant to a plan

Parameters:
  • name (str) – Name of the tenant

  • str,plan – Name of the subscription plan

admin.portals.subscribe('ctera', '10tb')

Apply Provisioning Changes#

Portals.apply_changes(wait=False)

Apply provisioning changes.

Parameters:

wait (bool,optional) – Wait for all changes to apply

"""Apply Portal Provisioning Changes"""
admin.portals.apply_changes()
admin.portals.apply_changes(wait=True)  # wait for all changes to apply

"""Apply User Provisioning Changes"""
admin.users.apply_changes()
admin.users.apply_changes(wait=True)  # wait for all changes to apply

Delete a Team Portal#

Portals.delete(name)

Delete an existing tenant

Parameters:

name (str) – Name of the tenant to delete

admin.portals.delete_tenant('acme')

Recover a Team Portal#

Portals.undelete(name)

Undelete a previously deleted tenant

Parameters:

name (str) – Name of the tenant to undelete

admin.portals.undelete_tenant('acme')

Plans#

Plans.get(name, include=None)

Retrieve subscription plan properties

Parameters:
  • name (str) – Name of the subscription plan

  • include (list[str]) – List of fields to retrieve, defaults to [‘name’]

Returns:

The subscription plan, including the requested fields

plan = admin.plans.get('good_plan', ['createDate', 'modifiedDate'])
Plans.list_plans(include=None, filters=None)

List Plans

Parameters:
  • include (list[str],optional) – List of fields to retrieve, defaults to [‘name’]

  • filters (list[],optional) – List of additional filters, defaults to None

Returns:

Iterator for all matching Plans

Return type:

cterasdk.lib.iterator.Iterator

"""List plans and include their creation date"""
for plan in admin.plans.list_plans(['createDate']):
    print(plan)
Plans.by_name(names, include=None)

Get Plans by their names

Parameters:
  • names (list[str],optional) – List of names of plans

  • include (list[str],optional) – List of fields to retrieve, defaults to [‘name’]

  • filters (list[cterasdk.core.query.FilterBuilder],optional) – List of additional filters, defaults to None

Returns:

Iterator for all matching Plans

Return type:

cterasdk.lib.iterator.Iterator

"""List plans 'PlanOne' and 'PlanTwo'; and retrieve the 'modifiedDate', 'uid' and 'isDefault' properties"""
for plan in admin.plans.by_name(['PlanOne', 'PlanTwo'], ['modifiedDate', 'uid', 'isDefault']):
    print(plan)
Plans.add(name, retention=None, quotas=None)

Add a subscription plan

Parameters:
  • retention (dict,optional) – The data retention policy

  • quotas (dict,optional) – The items included in the plan and their respective quota

"""
Retention Policy (portal_enum.PlanRetention):
- All: All Versions
- Hourly: Hourly Versions
- Daily: Daily Versions
- Weekly: Weekly Versions
- Monthly: Monthly Versions
- Quarterly: Quarterly Versions
- Yearly: Yearly Versions
- Deleted: Recycle Bin

Quotas (portal_enum.PlanItem):
- Storage: Storage Quota, in Gigabytes
- EV4: CTERA Edge Filer, Up to 4 TB of Local Cache
- EV8: CTERA Edge Filer, Up to 8 TB of Local Cache
- EV16: CTERA Edge Filer, Up to 16 TB of Local Cache
- EV32: CTERA Edge Filer, Up to 32 TB of Local Cache
- EV64: CTERA Edge Filer, Up to 64 TB of Local Cache
- EV128: CTERA Edge Filer, Up to 128 TB of Local Cache
- WA: Workstation Backup Agent
- SA: Server Agent
- Share: CTERA Drive Share
- Connect: CTERA Drive Connect
"""

"""
Create the 'good_plan' subscription plan:
1) Retention: 7 daily versions, 12 monthly versions
2) Quotas: 10 x EV16, 5 x EV32, 100 x Cloud Drive (Share)
"""

name = 'good_plan'
retention = {portal_enum.PlanRetention.Daily: 7, portal_enum.PlanRetention.Monthly: 12}
quotas = {portal_enum.PlanItem.EV16: 10, portal_enum.PlanItem.EV32: 5, portal_enum.PlanItem.Share: 100}
admin.plans.add(name, retention, quotas)
Plans.modify(name, retention=None, quotas=None, apply_changes=True)

Modify a subscription plan

Parameters:
  • retention (dict,optional) – The data retention policy

  • quotas (dict,optional) – The items included in the plan and their respective quota

  • apply_changes (bool,optional) – Apply provisioning changes immediately

"""
Modify 'good_plan' subscription plan:
1) Retention: 30 daily versions, 36 monthly versions
2) Quotas: 20 x EV16, 10 x EV32, 200 x Cloud Drive (Share)
"""

name = 'good_plan'
retention = {portal_enum.PlanRetention.Daily: 30, portal_enum.PlanRetention.Monthly: 36}
quotas = {portal_enum.PlanItem.EV16: 20, portal_enum.PlanItem.EV32: 10, portal_enum.PlanItem.Share: 200}
admin.plans.modify(name, retention, quotas)
Plans.delete(name)

Delete a subscription plan

Parameters:

username (str) – The name of the subscription plan

name = 'good_plan'
admin.plan.delete(name)

Plan Auto Assignment Rules#

PlanAutoAssignPolicy.get_policy()

Get plans auto assignment policy

PlanAutoAssignPolicy.set_policy(rules, apply_default=None, default=None, apply_changes=True)

Set plans auto assignment policy

Parameters:
  • rules (list[cterasdk.common.types.PolicyRule]) – List of policy rules

  • apply_default (bool,optional) – If no match found, apply default plan. If not passed, the current config will be kept

  • default (str,optional) – Name of a plan to assign if no match found. Ignored unless the apply_default is set to True

  • apply_changes (bool,optional) – Apply provisioning changes upon update, defaults to True

"""Apply the '100GB' plan to all user names that start with 'adm'"""
c1 = portal_types.PlanCriteriaBuilder.username().startswith('adm').build()
r1 = PolicyRule('100GB', c1)

"""Apply the '200GB' plan to all user names that end with 'inc'"""
c2 = portal_types.PlanCriteriaBuilder.username().endswith('inc').build()
r2 = PolicyRule('200GB', c2)

"""Apply the 'Bingo' plan to all user names that contain 'bing'"""
c3 = portal_types.PlanCriteriaBuilder.username().contains('bing').build()
r3 = PolicyRule('Bingo', c3)

"""Apply the 'ABC' plan to 'alice', 'bob' and 'charlie'"""
c4 = portal_types.PlanCriteriaBuilder.username().isoneof(['alice', 'bob', 'charlie']).build()
r4 = PolicyRule('ABC', c4)

"""Apply the '10TB' plan to read write, read only and support administrators"""
roles = [portal_enum.Role.ReadWriteAdmin, portal_enum.Role.ReadOnlyAdmin, portal_enum.Role.Support]
c5 = portal_types.PlanCriteriaBuilder.role().include(roles).build()
r5 = PolicyRule('10TB', c5)

"""Apply the 'TechStaff' plan to the 'Product' and 'Support' groups"""
c6 = portal_types.PlanCriteriaBuilder.user_groups().include(['Product', 'Support']).build()
r6 = PolicyRule('TechStaff', c6)

admin.plans.auto_assign.set_policy([r1, r2, r3, r4, r5, r6])

"""Remove all policy rules"""
admin.plans.auto_assign.set_policy([])

"""Do not assign a default plan if no match applies"""
admin.plans.auto_assign.set_policy([], False)

"""Assign 'Default' if no match applies"""
admin.plans.auto_assign.set_policy([], True, 'Default')

Configuration Templates#

Templates.get(name, include=None)

Get a Configuration Template

Parameters:
  • name (str) – Name of the template

  • include (list[str]) – List of fields to retrieve, defaults to ['name']

admin.templates.get('MyTemplate')
Templates.list_templates(include=None, filters=None)

List Configuration Templates.

To retrieve templates, you must first browse the tenant, using: GlobalAdmin.portals.browse()

Parameters:
  • include (list[str],optional) – List of fields to retrieve, defaults to ['name']

  • filters (list[],optional) – List of additional filters, defaults to None

for template in admin.templates.list_templates(include=['name', 'description', 'modifiedDate']):
    print(template.name, template.description, template.modifiedDate)
Templates.add(name, description=None, include_sets=None, exclude_sets=None, apps=None, backup_schedule=None, versions=None, update_settings=None, scripts=None, cli_commands=None, consent_page=None)

Add a Configuration Template

Parameters:

This library provides several classes, methods and enumerators to assist in creating configuration templates: #. Builder class for filtered backup sets. cterasdk.common.types.FileFilterBuilder #. A class representing a backup include or exclude set. cterasdk.common.types.FilterBackupSet #. Builder class for defining backup schedule. cterasdk.common.types.BackupScheduleBuilder #. A time-range class, used to configure backups to run at a specific time. cterasdk.common.types.TimeRange #. Enumerator containing applications supported for backup. cterasdk.common.enum.Application #. A named tuple defining a platform and a software version. cterasdk.core.types.PlatformVersion #. Enumerator containing a list of platforms. cterasdk.core.enum.Platform

"""Include all 'pptx', 'xlsx' and 'docx' file types for all users"""
docs = common_types.FileFilterBuilder.extensions().include(['pptx', 'xlsx', 'docx']).build()
include_sets = common_types.FilterBackupSet('Documents', filter_rules=[docs],
                                                      template_dirs=[portal_enum.EnvironmentVariables.ALLUSERSPROFILE])

"""Exclude all 'cmd', 'exe' and 'bat' file types for all users"""
programs = common_types.FileFilterBuilder.extensions().include(['cmd', 'exe', 'bat']).build()
exclude_sets = common_types.FilterBackupSet('Programs', filter_rules=[programs],
                                                        template_dirs=[portal_enum.EnvironmentVariables.ALLUSERSPROFILE])

"""Schedule backup to run periodically"""
backup_schedule = common_types.BackupScheduleBuilder.interval(hours=6)  # periodically, every 6 hours
backup_schedule = common_types.BackupScheduleBuilder.interval(hours=0, minutes=30)  # periodically, every 30 minutes

"""Schedule backup for a specific time"""
time_range = common_types.TimeRange().start('07:00:00').days(common_enum.DayOfWeek.Weekdays).build()  # 7am, on weekdays
backup_schedule = common_types.BackupScheduleBuilder.window(time_range)

"""Backup applications"""
apps = [common_enum.Application.NTDS, common_enum.Application.HyperV]  # back up Active Directory and Hyper-V
apps = common_enum.Application.All  # back up all applications

"""Configure software versions"""
versions = [portal_types.PlatformVersion(portal_enum.Platform.Edge_7, '7.0.981.7')]  # use 7.0.981.7 for v7 Edge Filers

"""Configure software update schedule"""
schedule = common_types.TimeRange().start('01:00:00').end('02:00:00').days(common_enum.DayOfWeek.Weekdays).build()
builder = common_types.SoftwareUpdatePolicyBuilder()
update_settings = builder.download_and_install(True).reboot_after_update(True).schedule(schedule).build()

"""Configure Scripts"""
scripts = [
    portal_types.TemplateScript.windows().after_logon('echo Current directory: %cd%'),
    portal_types.TemplateScript.linux().before_backup('./mysqldump -u admin website > /mnt/backup/backup.sql'),
    portal_types.TemplateScript.linux().after_backup('rm /mnt/backup/backup.sql')
]

"""Configure CLI Commands"""
cli_commands = [
    'set /config/agent/stubs/deleteFilesOfCachedFolderOnDisable false',
    'add /config/agent/stubs/allowedExplorerExtensions url'
]

"""Configure Consent Page"""
consent_page = common_types.ConsentPage('the header of your consent page', 'the body of your consent page')

admin.templates.add('MyTemplate', 'woohoo', include_sets=[include_sets], exclude_sets=[exclude_sets],
                   backup_schedule=backup_schedule, apps=apps, versions=versions, update_settings=update_settings,
                   scripts=scripts, cli_commands=cli_commands, consent_page=consent_page)
Templates.set_default(name, wait=False)

Set a Configuration Template as the default template

Parameters:
  • name (str) – Name of the template

  • wait (bool,optional) – Wait for all changes to apply, defaults to False

admin.templates.set_default('MyTemplate')

admin.templates.set_default('MyTemplate', wait=True)  # wait for template changes to apply
Templates.remove_default(name, wait=False)

Set a Configuration Template not to be the default template

Parameters:
  • name (str) – Name of the template

  • wait (bool,optional) – Wait for all changes to apply, defaults to False

admin.templates.remove_default('MyTemplate')

admin.templates.remove_default('MyTemplate', wait=True)  # wait for template changes to apply
TemplateAutoAssignPolicy.apply_changes(wait=False)

Apply provisioning changes.

Parameters:

wait (bool,optional) – Wait for all changes to apply, defaults to False

admin.templates.auto_assign.apply_changes()

admin.templates.auto_assign.apply_changes(wait=True)  # wait for template changes to apply

Template Auto Assignment Rules#

TemplateAutoAssignPolicy.get_policy()

Get templates auto assignment policy

TemplateAutoAssignPolicy.set_policy(rules, apply_default=None, default=None, apply_changes=True)

Set templates auto assignment policy

Parameters:
  • rules (list[cterasdk.common.types.PolicyRule]) – List of policy rules

  • apply_default (bool,optional) – If no match found, apply default template. If not passed, the current config will be kept

  • default (str,optional) – Name of a template to assign if no match found. Ignored unless the apply_default is set to True

  • apply_changes (bool,optional) – Apply changes upon update, defaults to True

"""Apply the 'ESeries' template to devices of type: C200, C400, C800, C800P"""
device_types = [portal_enum.DeviceType.C200, portal_enum.DeviceType.C400, portal_enum.DeviceType.C800, portal_enum.DeviceType.C800P]
c1 = portal_types.TemplateCriteriaBuilder.type().include(device_types).build()
r1 = PolicyRule('ESeries', c1)

"""Apply the 'Windows' template to devices that use a 'Windows' operating system"""
c2 = portal_types.TemplateCriteriaBuilder.os().contains('Windows').build()
r2 = PolicyRule('Windows', c2)

"""Apply the 'CTERA7' template to devices running version 7"""
c3 = portal_types.TemplateCriteriaBuilder.version().startswith('7.0').build()
r3 = PolicyRule('CTERA7', c3)

"""Apply the 'WD5' template to devices that their hostname ends with 'WD5'"""
c4 = portal_types.TemplateCriteriaBuilder.hostname().endswith('WD5').build()
r4 = PolicyRule('WD5', c4)

"""Apply the 'Beta' template to devices that their name is one of"""
c5 = portal_types.TemplateCriteriaBuilder.name().isoneof(['DEV1', 'DEV2', 'DEV3']).build()
r5 = PolicyRule('Beta', c5)

admin.templates.auto_assign.set_policy([r1, r2, r3, r4, r5])

"""Remove all policy rules"""
admin.templates.auto_assign.set_policy([])

"""Do not assign a default template if no match applies"""
admin.templates.auto_assign.set_policy([], False)

"""Assign 'Default' if no match applies"""
admin.templates.auto_assign.set_policy([], True, 'Default')

Servers#

Servers.get(name, include=None)

Retrieve server properties

Parameters:
  • name (str) – Name of the server

  • include (list[str]) – List of fields to retrieve, defaults to [‘name’]

Returns:

The server, including the requested fields

"""Retrieve a server"""

server = admin.servers.get('server', ['isApplicationServer', 'renderingServer'])
print(server.isApplicationServer, server.renderingServer)
Servers.list_servers(include=None)

Retrieve the servers that comprise CTERA Portal.

To retrieve servers, you must first browse the Global Administration Portal, using: GlobalAdmin.portals.browse_global_admin()

Parameters:

include (list[str],optional) – List of fields to retrieve, defaults to [‘name’]

"""Retrieve all servers"""
servers = admin.servers.list_servers() # will only retrieve the server name
for server in servers:
    print(server.name)

"""Retrieve multiple server attributes"""
servers = admin.servers.list_servers(include = ['name', 'connected', 'isApplicationServer', 'mainDB'])
for server in servers:
    print(server)
Servers.modify(name, server_name=None, app=None, preview=None, enable_public_ip=None, public_ip=None, allow_user_login=None, enable_replication=None, replica_of=None)

Modify a Portal server

Parameters:
  • name (str) – The current server name

  • server_name (str,optional) – New server name

  • app (bool,optional) – Application server

  • preview (bool,optional) – Preview server

  • enable_public_ip (bool,optional) – Enable or disable public NAT address

  • public_ip (str,optional) – Public NAT address

  • allow_user_login (bool,optional) – Allow or disallow logins to this server

  • enable_replication (bool,optional) – Enable or disable database replication

  • replica_of (str,optional) – Configure as a replicate of another Portal server. enable_replication must be set to True

admin.servers.modify('server2', server_name='replica', app=False, enable_replication=True, replica_of='maindb')  # rename and enable database replication

admin.servers.modify('server2', allow_user_login=False)  # disable logins to this server

admin.servers.modify('server2', enable_public_ip=True, public_ip='33.191.55.2')  # configure a public NAT ip address

Server Tasks#

Tasks.background(name)

Get all background tasks

Parameters:

name (str) – Name of the server

Returns:

List of tasks

for task in admin.servers.tasks.background('database'):
    print(task.name)
Tasks.scheduled(name)

Get all scheduled tasks

Parameters:

name (str) – Name of the server

Returns:

List of tasks

for task in admin.servers.tasks.scheduled('database'):
   print(task.name)

Messaging Service#

Messaging.get_status()

Retrieve the global status of messaging service

"""Retrieve the global status of Messaging service"""

print(admin.messaging.get_status())
Messaging.get_servers_status()

Retrieve the status of the messaging servers

"""Retrieve the status of the Messaging servers"""

print(admin.messaging.get_servers_status())
Messaging.add(servers)

Add messaging servers to cluster

Parameters:

servers (list[str]) – Server names (number of allowed servers: 1 or 3)

"""Add Messaging servers to cluster"""

servers = ["server1", "server2", "server3"]
admin.messaging.add(servers)

Key Management Service#

KMS.settings()

Get Key Management Service Settings

admin.kms.settings()
KMS.status()

Get Key Management Service Status

admin.kms.status()
KMS.enable(private_key, client_certificate, server_certificate, expiration=None, timeout=None, port=None)

Enable Key Management Service

Parameters:
  • private_key (str) – The PEM-encoded private key, or a path to the PEM-encoded private key file

  • client_certificate (str) – The PEM-encoded client certificate, or a path to the certificate file

  • server_certificate (str) – The PEM-encoded KMS server certificate, or a path to the certificate file

  • expiration (int,optional) – Key expiration in days, defaults to 365.

  • timeout (int,optional) – Connection timeout in seconds, defaults to 2

  • port (int,optional) – Key server port, defaults to 5696

private_key = './private_key.pem'
client_certificate = './client_certificate.crt'
server_certificate = './server_certificate.crt'

admin.kms.enable(private_key, client_certificate, server_certificate)
KMS.disable()

Disable Key Management Service

admin.kms.disable()
KMS.modify(private_key=None, client_certificate=None, server_certificate=None, expiration=None, timeout=None, port=None)

Modify Key Management Service Settings

Parameters:
  • private_key (str,optional) – The PEM-encoded private key, or a path to the PEM-encoded private key file

  • client_certificate (str,optional) – The PEM-encoded client certificate, or a path to the certificate file

  • server_certificate (str,optional) – The PEM-encoded KMS server certificate, or a path to the certificate file

  • expiration (int,optional) – Key expiration in days, defaults to 365.

  • timeout (int,optional) – Connection timeout in seconds, defaults to 2

  • port (int,optional) – Key server port, defaults to 5696

Key Management Service Servers#

KMSServers.get(name)

Retrieve a key-server

Parameters:

name (str) – Key-server name

admin.kms.servers.get('kms001')
KMSServers.all()

List Key Management Servers

for server in admin.kms.servers.all():
    print(server)
KMSServers.add(name, ipaddr)

Add a key-server

Parameters:
  • name (str) – Key-server name

  • ipaddr (str) – Key-server IP address

admin.kms.servers.add('kms001', '192.168.30.1')
KMSServers.modify(current_name, new_name)

Remove a key-server

Parameters:
  • current_name (str) – Key-server current name

  • new_name (str) – Key-server new name

admin.kms.servers.modify('kms001', 'kms001-renamed')
KMSServers.delete(name)

Remove a key-server

Parameters:

name (str) – Key-server name

admin.kms.servers.delete('kms001')

Antivirus#

Antivirus.list_servers(include=None)

List the antivirus servers

Parameters:

include (list[str],optional) – List of fields to retrieve, defaults to ['name', 'type']

Antivirus.status()

Get antivirus service status

Antivirus.rescan()

Scan all files using the latest antivirus update. This may take a while

Antivirus.suspend()

Suspend antivirus scanning

Antivirus.unsuspend()

Unsuspend antivirus scanning

Antivirus Servers#

AntivirusServers.get(name)

Get an antivirus server’s configuration

Parameters:

name (str) – Server name

AntivirusServers.add(name, vendor, url, connection_timeout=5)

Add an antivirus server

Parameters:
  • name (str) – Server name

  • vendor (cterasdk.core.enum.AntivirusType) – Server type

  • url (str) – Server URL (example: http://your-antivirus.server.local:1234/signature)

  • connection_timeout (int,optional) – Server connection timeout (in seconds), defaults to 5 seconds

AntivirusServers.delete(name)

Remove an antivirus server

AntivirusServers.suspend(name)

Suspend an antivirus server

AntivirusServers.unsuspend(name)

Unsuspend antivirus scanning

Global Administrators#

Administrators.list_admins(include=None)

List local administrators

Parameters:

include (list[str]) – List of fields to retrieve, defaults to [‘name’]

Returns:

Iterator for local administrators

Return type:

cterasdk.lib.iterator.Iterator

"""list all global admins"""
for admin in admin.admins.list_global_administrators():
    print(admin.name)

for admin in admin.admins.list_global_administrators(include=['name', 'email', 'firstName', 'lastName']):
    print(admin)
Administrators.add(name, email, first_name, last_name, password, role, company=None, comment=None, password_change=False)

Create a Global Administrator

Parameters:
  • name (str) – User name for the new GlobalAdmin

  • email (str) – E-mail address of the new GlobalAdmin

  • first_name (str) – The first name of the new GlobalAdmin

  • last_name (str) – The last name of the new GlobalAdmin

  • password (str) – Password for the new GlobalAdmin

  • role (cterasdk.core.enum.Role) – User role of the new GlobalAdmin

  • company (str,optional) – The name of the company of the new GlobalAdmin, defaults to None

  • comment (str,optional) – Additional comment for the new GlobalAdmin, defaults to None

  • password_change (variable,optional) – Require the user to change the password on the first login. Pass datetime.date for a specific date, integer for days from creation, or True for immediate , defaults to False

"""Create a global admin"""
admin.admins.add('bruce', 'bruce.wayne@we.com', 'Bruce', 'Wayne', 'G0th4amCity!')
Administrators.modify(current_username, new_username=None, email=None, first_name=None, last_name=None, password=None, role=None, company=None, comment=None)

Modify a Global Administrator user account

Parameters:
  • current_username (str) – The current GlobalAdmin username

  • new_username (str,optional) – New name

  • email (str,optional) – E-mail address

  • first_name (str,optional) – First name

  • last_name (str,optional) – Last name

  • password (str,optional) – Password

  • role (cterasdk.core.enum.Role,optional) – User role

  • company (str,optional) – Company name

  • comment (str,optional) – Comment

"""Modify a global admin"""
admin.admins.modify('bruce', 'bwayne@we.com', 'Bruce', 'Wayne', 'Str0ngP@ssword!', 'Wayne Enterprises')
Administrators.delete(name)

Delete a Global Administrator

Parameters:

username (str) – Global administrator username

"""Delete a global admin"""
admin.admins.delete('alice')

Roles#

static Roles.types()

Get a list of roles

print(admin.roles.types)
Roles.get(role)

Get Role

Parameters:

role (str) – Role

Returns:

Role settings

Return type:

cterasdk.core.types.RoleSettings

rw_admin_settings = admin.roles.get(portal_enum.Role.ReadWriteAdmin)
ro_admin_settings = admin.roles.get(portal_enum.Role.ReadOnlyAdmin)
support_admin_settings = admin.roles.get(portal_enum.Role.Support)
Roles.modify(role, settings)

Modify Role

Parameters:
Returns:

Updated role settings

Return type:

cterasdk.core.types.RoleSettings

support_admin_settings = admin.roles.get(portal_enum.Role.Support)
support_admin_settings.manage_logs = True
admin.roles.modify(portal_enum.Role.Support, support_admin_settings)

Users#

Users.delete(user)

Delete a user

Parameters:

user (cterasdk.core.types.UserAccount) – the user account

"""Delete a local user"""

alice = portal_types.UserAccount('alice')
admin.users.delete(alice)

"""Delete a domain user"""

bruce = portal_types.UserAccount('bruce', 'domain.ctera.local')
admin.users.delete(bruce)

Local Users#

Users.list_local_users(include=None)

List all local users

Parameters:

include (list[str]) – List of fields to retrieve, defaults to [‘name’]

Returns:

Iterator for all local users

Return type:

cterasdk.lib.iterator.Iterator

users = admin.users.list_local_users()

for user in users:

    print(user.name)

users = admin.users.list_local_users(include = ['name', 'email', 'firstName', 'lastName'])

for user in users:

    print(user)
Users.add(name, email, first_name, last_name, password, role, company=None, comment=None, password_change=False)

Create a local user account

Parameters:
  • name (str) – User name for the new user

  • email (str) – E-mail address of the new user

  • first_name (str) – The first name of the new user

  • last_name (str) – The last name of the new user

  • password (str) – Password for the new user

  • role (cterasdk.core.enum.Role) – User role of the new user

  • company (str,optional) – The name of the company of the new user, defaults to None

  • comment (str,optional) – Additional comment for the new user, defaults to None

  • password_change (variable,optional) – Require the user to change the password on the first login. Pass datetime.date for a specific date, integer for days from creation, or True for immediate , defaults to False

"""Create a local user"""
admin.users.add('bruce', 'bruce.wayne@we.com', 'Bruce', 'Wayne', 'G0th4amCity!')
Users.modify(current_username, new_username=None, email=None, first_name=None, last_name=None, password=None, role=None, company=None, comment=None)

Modify a local user account

Parameters:
  • current_username (str) – The current user name

  • new_username (str,optional) – New name

  • email (str,optional) – E-mail address

  • first_name (str,optional) – First name

  • last_name (str,optional) – Last name

  • password (str,optional) – Password

  • role (cterasdk.core.enum.Role,optional) – User role

  • company (str,optional) – Company name

  • comment (str,optional) – Comment

"""Modify a local user"""
admin.users.modify('bruce', 'bwayne@we.com', 'Bruce', 'Wayne', 'Str0ngP@ssword!', 'Wayne Enterprises')

Domain Users#

Users.list_domain_users(domain, include=None)

List all the users in the domain

Parameters:
  • domain (str) – Domain name

  • include (list[str]) – List of fields to retrieve, defaults to [‘name’]

Returns:

Iterator for all the domain users

Return type:

cterasdk.lib.iterator.Iterator

users = admin.users.list_domain_users('domain.ctera.local') # will only retrieve the 'name' attribute
for user in users:
    print(user.name)

"""Retrieve additional user attributes"""
users = admin.users.list_domain_users('domain.ctera.local', include = ['name', 'email', 'firstName', 'lastName'])
print(user)

Fetch Users & Groups#

DirectoryService.fetch(active_directory_accounts)

Instruct the Portal to fetch the provided Active Directory Accounts

Parameters:

active_directory_accounts (list[cterasdk.core.types.PortalAccount]) – List of Active Directory Accounts to fetch

Returns:

Response Code

"""Fetch domain users"""

alice = portal_types.UserAccount('alice', 'domain.ctera.local')
bruce = portal_types.UserAccount('bruce', 'domain.ctera.local')

admin.directoryservice.fetch([alice, bruce])

Directory Services#

DirectoryService.connect(domain, username, password, directory='ActiveDirectory', domain_controllers=None, ou=None, ssl=False, krb=False, mapping=None, acl=None, default='Disabled', fetch='Lazy')

Connect a Portal tenant to directory services

Parameters:
  • domain (str) – The directory services domain to connect to

  • username (str) – The user name to use when connecting to the active directory services

  • password (str) – The password to use when connecting to the active directory services

  • ou (str,optional) – The OU path to use when connecting to the active directory services, defaults to None

  • directory (cterasdk.core.enum.DirectoryServiceType,optional) – The directory service type, deafults to ‘ActiveDirectory’

  • domain_controllers (cterasdk.core.types.DomainControllers,optional) – Connect to a primary and a secondary domain controllers, defaults to None

  • ssl (bool,optional) – Connect using SSL, defaults to False

  • krb (bool,optional) – Connect using Kerberos, defaults to False

  • list[cterasdk.common.types.ADDomainIDMapping],optional – The directory services UID/GID mapping

  • acl (list[cterasdk.core.types.AccessControlEntry],optional) – List of access control entries and their associated roles

  • default (cterasdk.core.enum.Role) – Default role if no match applies, defaults to None

  • fetch (str,optional) – Configure identity fetching mode, defaults to ‘Lazy’

"""Connect to Active Directory using a primary domain controller, configure domain UID/GID mapping and access control"""
mapping = [portal_types.ADDomainIDMapping('demo.local', 200001, 5000000), portal_types.ADDomainIDMapping('trusted.local', 5000001, 10000000)]
rw_admin_group = portal_types.AccessControlEntry(
    portal_types.GroupAccount('ctera_admins', 'demo.local'),
    portal_enum.Role.ReadWriteAdmin
)
ro_admin_user = portal_types.AccessControlEntry(
    portal_types.UserAccount('jsmith', 'demo.local'),
    portal_enum.Role.ReadOnlyAdmin
)
admin.directoryservice.connect('demo.local', 'svc_account', 'P@ssw0rd1', mapping=mapping, domain_controllers=portal_types.DomainControllers('172.54.3.52'), acl=[rw_admin, ro_admin])
DirectoryService.domains()

Get domains

Return list(str):

List of names of all discovered domains

print(admin.directoryservice.domains())
DirectoryService.get_connected_domain()

Get the connected domain information. Returns None if the Portal tenant is not connected to a domain

Return str:

The connected domain

print(admin.directoryservice.get_connected_domain())
DirectoryService.get_advanced_mapping()

Retrieve directory services advanced mapping configuration

Returns:

A dictionary of domain mapping objects

Return type:

dict

for domain, mapping in admin.directoryservice.get_advanced_mapping().items():
    print(domain, mapping)
DirectoryService.set_advanced_mapping(mapping)

Configure advanced mapping

Parameters:

mapping (list[cterasdk.common.types.ADDomainIDMapping]) – List of domains and their UID/GID mapping range

"""Configure UID/GID mapping"""
mapping = [portal_types.ADDomainIDMapping('demo.local', 200001, 5000000), portal_types.ADDomainIDMapping('trusted.local', 5000001, 10000000)]
admin.directoryservice.set_advanced_mapping(mapping)
DirectoryService.get_access_control()

Retrieve directory services access control list

Returns:

List of access control entries

Return type:

list[cterasdk.core.types.AccessControlEntry]

for ace in admin.directoryservice.get_access_control():
    print(ace.account, ace.role)
DirectoryService.set_access_control(acl=None, default=None)

Configure directory services access control

Parameters:
"""Configure access control for a domain group and a domain user. Set the default role to 'Disabled'"""
rw_admin_group = portal_types.AccessControlEntry(
    portal_types.GroupAccount('ctera_admins', 'demo.local'),
    portal_enum.Role.ReadWriteAdmin
)
ro_admin_user = portal_types.AccessControlEntry(
    portal_types.UserAccount('jsmith', 'demo.local'),
    portal_enum.Role.ReadOnlyAdmin
)
admin.directoryservice.set_access_control([rw_admin_group, ro_admin_user], portal_enum.Role.Disabled)
DirectoryService.get_default_role()#

Retrieve the default role assigned when no access control entry match was found

print(admin.directoryservice.get_default_role())
DirectoryService.disconnect()

Disconnect a Portal tenant from directory services

admin.directoryservice.disconnect()

Credentials#

S3.all(user_account=None)

List Credentials

Parameters:

user_account (cterasdk.core.types.UserAccount,optional) – User account

"""List all of 'jsmith@demo.local' S3 credentials"""
jsmith = portal_types.UserAccount('jsmith', 'demo.local')
for credential in user.credentials.s3.all(jsmith):
    print(credential.accessKey, credential.activated)
S3.create(user_account=None)

Create Credential

Parameters:

user_account (cterasdk.core.types.UserAccount,optional) – User account

"""Create an S3 credential for a service account"""
service_account = portal_types.UserAccount('service_account')
credential = user.credentials.s3.create(service_account)
S3.delete(access_key_id, user_account=None)

Delete Credential

Parameters:
"""Delete an S3 credentials associated with a user account"""
user_account = portal_types.UserAccount('jsmith', 'demo.local')
access_key_id = 'ABCDEFGHIJKLMOP'
user.credentials.s3.delete(access_key_id, user_account)

Groups#

Groups.delete(group_account)

Delete a group

Parameters:

group_account (cterasdk.core.types.GroupAccount) – Group account

"""Delete a local group"""
group = portal_types.GroupAccount('local_group')
admin.groups.delete(group)

"""Delete a domain group"""

group = portal_types.GroupAccount('domain_group', 'domain.ctera.local')
admin.groups.delete(group)

Local Groups#

Groups.list_local_groups(include=None)

List all local groups

Parameters:

include (list[str]) – List of fields to retrieve, defaults to [‘name’]

Returns:

Iterator for all local groups

Return type:

cterasdk.lib.iterator.Iterator

groups = admin.groups.list_local_groups()
for group in groups:
    print(group.name)

groups = admin.groups.list_local_groups(include=['name', 'description'])
for group in groups:
    print(group)
Groups.add(name, description=None, members=None)

Create a local group

Parameters:
  • name (str) – Group name

  • description (str,optional) – Group description

  • members (list(cterasdk.core.types.UserAccount),optional) – List of user group members

"""Create a local group"""
admin.groups.add('Users')
admin.groups.add('Users', 'A group of users')  # with description
admin.groups.add('Users', members=[portal_types.UserAccount('alice'), portal_types.UserAccount('bruce', 'domain.ctera.local')])  # with members
Groups.modify(current_groupname, new_groupname=None, description=None)

Modify a local group

Parameters:
  • current_groupname (str) – The current group name

  • new_groupname (str,optional) – New group name

  • description (str,optional) – Group description

"""Modify a local group"""
admin.groups.modify('Users', new_groupname='End Users')  # change group name
admin.groups.modify('Users', description='A group of end users')  # change group description
Groups.get_members(group_account)

Get group members

Parameters:

group_account (cterasdk.core.types.GroupAccount) – Group account

"""Get group members"""
admin.groups.get_members(portal_types.GroupAccount('Users'))  # get members of a local group
admin.groups.get_members(portal_types.GroupAccount('Users', 'domain.ctera.local'))  # get members of a domain group
Groups.add_members(group_account, members)

Add group members

Parameters:
"""Add group members"""
admin.groups.add_members(portal_types.GroupAccount('Users'), [portal_types.UserAccount('alice')])  # add local users to a local group
admin.groups.add_members(portal_types.GroupAccount('Users'), [portal_types.UserAccount('bruce', 'domain.ctera.local')])  # add domain users to a local group

Devices#

Devices.device(device_name, tenant=None, include=None)

Get a Device by its name

Parameters:
  • device_name (str) – Name of the device to retrieve

  • tenant (str,optional) – Tenant of the device, defaults to the tenant in the current session

  • include (list[str],optional) – List of fields to retrieve, defaults to [‘name’, ‘portal’, ‘deviceType’]

Returns:

Managed Device

Return type:

ctera.object.Gateway.Gateway or ctera.object.Agent.Agent

Devices.filers(include=None, allPortals=False, deviceTypes=None)

Get Filers

Parameters:
  • include (list[str],optional) – List of fields to retrieve, defaults to [‘name’, ‘portal’, ‘deviceType’]

  • allPortals (bool,optional) – Search in all portals, defaults to False

  • deviceTypes (list[cterasdk.core.enum.DeviceType.Gateways]) – Types of Filers, defaults to all Filer types

Returns:

Iterator for all matching Filers

Return type:

cterasdk.lib.iterator.Iterator[cterasdk.object.Gateway.Gateway]

"""Retrieve all Gateways from the current tenant"""

filers = admin.devices.filers()
for filer in filers:
    print(filer.name) # will print the Gateway name

"""Retrieve additional Gateway attributes"""
filers = admin.devices.filers(['owner', 'deviceConnectionStatus'])

"""Retrieve nested attributes using the '.' delimiter"""
filers = admin.devices.filers(['deviceReportedStatus.status.device.runningFirmware'])

"""Retrieve filers from all portals"""
admin.portals.browse_global_admin()

filers = admin.devices.filers(allPortals = True)
"""Retrieve C200's and C400's from all portals"""
admin.portals.browse_global_admin()
filers = admin.devices.filers(allPortals = True, deviceTypes = ['C200', 'C400'])
Devices.agents(include=None, allPortals=False)

Get Agents

Parameters:
  • include (list[str],optional) – List of fields to retrieve, defaults to [‘name’, ‘portal’, ‘deviceType’]

  • allPortals (bool,optional) – Search in all portals, defaults to False

Returns:

Iterator for all matching Agents

Return type:

cterasdk.lib.iterator.Iterator[cterasdk.object.Agent.Agent]

"""Retrieve all Agents from the current tenant"""
agents = admin.devices.agents()
for agent in agents:
    print(agent.name) # will print the Agent name

"""Retrieve all Agents and the underlying OS name"""
agents = admin.devices.agents(['deviceReportedStatus.status.agent.details.osName'])
Devices.servers(include=None, allPortals=False)

Get Servers

Parameters:
  • include (list[str],optional) – List of fields to retrieve, defaults to [‘name’, ‘portal’, ‘deviceType’]

  • allPortals (bool,optional) – Search in all portals, defaults to False

Returns:

Iterator for all matching Servers

Return type:

cterasdk.lib.iterator.Iterator

server_agents = admin.devices.servers()
Devices.desktops(include=None, allPortals=False)

Get Desktops

Parameters:
  • include (list[str],optional) – List of fields to retrieve, defaults to [‘name’, ‘portal’, ‘deviceType’]

  • allPortals (bool,optional) – Search in all portals, defaults to False

Returns:

Iterator for all matching Desktops

Return type:

cterasdk.lib.iterator.Iterator

desktop_agents = admin.devices.desktop_agents()
Devices.by_name(names, include=None)

Get Devices by their names

Parameters:
  • names (list[str],optional) – List of names of devices

  • include (list[str],optional) – List of fields to retrieve, defaults to [‘name’, ‘portal’, ‘deviceType’]

Returns:

Iterator for all matching Devices

Return type:

cterasdk.lib.iterator.Iterator

Devices.get_comment(device_name, tenant=None)

Get Portal device comment

Parameters:

device (str) – Device name

Returns:

Comment

Return type:

str

print(admin.devices.get_comment('FSRV'))
Devices.set_comment(device_name, comment, tenant=None)

Set a comment to a Portal device

Parameters:
  • device (str) – Device name

  • comment (str) – Comment

admin.devices.set_comment('FSRV', 'Production')

Remote Access#

The Devices APIs retrieve a handle that can be used to query and update the configuration of remote Edge Filers or Drive Agents.

"""Retrieving a List of Shares from an Edge Filer"""

filer = admin.devices.device('edge-hostname')
shares = filer.shares.get()
for share in shares:
    print(share.name)

However, the handle retrieved from the Portal does not provide full access to the Edge Filer or Drive Agent APIs. To obtain full access to the remote Edge Filer or Drive Agent APIs, use the remote_access function.

Gateway.remote_access()
"""Retrieving a List of Shares from an Edge Filer"""

filer = admin.devices.device('edge-hostname')
remote_session = filer.remote_access()  # Returns an authenticated remote access session

"""Downloading a File via a Remote Access Edge Filer Session"""
remote_session.files.download('cloud/users/Service Account/My Files/docs/document.docx')

Generate Activation Codes#

Activation.generate_code(username=None, tenant=None)

Generate device activation code

Parameters:
  • username (str,optional) – User name used for activation, defaults to None

  • tenant (str,optional) – Tenant name used for activation, defaults to None

Returns:

Portal Activation Code

Return type:

str

"""Generate a device activation code"""
code = admin.activation.generate_code() # will generate a code for the current, logged on, user
code = admin.activation.generate_code('bruce') # will generate a code for 'bruce' in the current tenant
code = admin.activation.generate_code('batman', 'gotham') # will generate a code for 'bruce' in the 'gotham' tenant

Note

Read Write Administrator, granted with the “Super User” role permission, can generate 200 codes every 5 minutes

Code Snippets#

Generate activation codes for all domain users

users = admin.users.list_domain_users('dc.ctera.local') # obtain a list of domain users
for user in users:
    activation_code = admin.activation.generate_code(user.name) # generate activation code
    print((user.name, activation_code))

CloudFS#

You must be a Read Write Administrator to manage the Cloud File System, folder groups, backup folders, cloud drive folders, and zones.

Folder Groups#

FolderGroups.all(include=None, user=None)

List folder groups

Parameters:
  • include (str,optional) – List of fields to retrieve, defaults to [‘name’, ‘owner’]

  • user (cterasdk.core.types.UserAccount) – User account of the folder group owner

Returns:

Iterator for all folder groups

"""List all folder groups"""
folder_groups = admin.cloudfs.groups.all()
for folder_group in folder_groups:
    print(folder_group.name, folder_group.owner)

"""List folder groups owned by a domain user"""
bruce = portal_types.UserAccount('bruce', 'domain.ctera.local')
folder_groups = admin.cloudfs.groups.all(user=bruce)
FolderGroups.add(name, user=None, deduplication_method_type=None, storage_class=None)

Create a Folder Group

Parameters:
"""Create a Folder Group, owned by a local user account 'svc_account'"""
svc_account = portal_types.UserAccount('svc_account')
admin.cloudfs.groups.add('FG-001', svc_account)

"""Create a Folder Group, owned by the domain user 'ctera.local\wbruce'"""
wbruce = portal_types.UserAccount('wbruce', 'ctera.local')
admin.cloudfs.groups.add('FG-002', wbruce)

admin.cloudfs.groups.add('FG-003') # without an owner

"""Create a Folder Group, assigned to an 'Archive' storage class"""
admin.cloudfs.groups.add('Archive', portal_types.UserAccount('svc_account'), storage_class='Archive')
FolderGroups.modify(current_name, new_name)

Modify a folder group

Parameters:
  • current_name (str) – Current folder group name

  • new_name (str) – New folder group name

"""Rename a Folder Group"
admin.cloudfs.groups.modify('FG-001', 'FG-002')
FolderGroups.delete(name)

Remove a Folder Group

Parameters:

name (str) – Name of the folder group to remove

admin.cloudfs.groups.delete('FG-001')

Backup Folders#

Backups.all(include=None, list_filter='NonDeleted', user=None)

List Backup folders.

Parameters:
Returns:

Iterator for all Backup folders

"""List all backup folder"""
for backup_folder in admin.cloudfs.backups.all():
   print(backup_folder)
Backups.add(name, group, owner, xattr=True)

Create a new Backup Folder

Parameters:
  • name (str) – Name of the backup folder

  • group (str) – Folder Group to assign this folder to

  • owner (cterasdk.core.types.UserAccount) – User account, the owner of the backup folder

  • xattr (bool,optional) – Backup extended attributes, defaults to True

"""Create a backup folder"""
folder_group = 'backup-fg'
owner = portal_types.UserAccount('bwayne', 'domain.ctera.local')
admin.cloudfs.backups.add('my-backup', folder_group, owner)
Backups.modify(current_name, new_name=None, new_owner=None, new_group=None, xattr=None)

Modify a Backup Folder

Parameters:
  • current_name (str) – Current folder name

  • owner (cterasdk.core.types.UserAccount) – User account, the owner of the folder

  • new_name (str,optional) – New folder name

  • new_owner (cterasdk.core.types.UserAccount,optional) – User account, the new owner of the folder

  • new_group (str,optional) – Folder Group to assign this folder to

  • xattr (bool,optional) – Backup extended attributes

"""Change backup folder owner"""
bwayne = portal_types.UserAccount('bwayne', 'domain.ctera.local')
admin.cloudfs.backups.modify('my-backup', new_owner=bwayne)
Backups.delete(name)

Delete a Backup Folder

Parameters:

name (str) – Name of the Backup Folder to delete

"""Delete a backup folder"""
admin.cloudfs.backups.modify('my-backup')

Cloud Drive Folders#

CloudDrives.all(include=None, list_filter='NonDeleted', user=None)

List Cloud Drive folders.

Parameters:
  • include (str,optional) – List of fields to retrieve, defaults to [‘name’, ‘group’, ‘owner’]

  • list_filter (cterasdk.core.enum.ListFilter) – Filter the list of Cloud Drive folders, defaults to non-deleted folders

  • user (cterasdk.core.types.UserAccount) – User account of the cloud folder owner

Returns:

Iterator for all Cloud Drive folders

"""List all cloud drive folders"""
cloud_drive_folders = admin.cloudfs.drives.all()
for cloud_drive_folder in cloud_drive_folders:
    print(cloud_drive_folder)

"""List cloud drive folders owned by a domain user"""
bruce = portal_types.UserAccount('bruce', 'domain.ctera.local')
cloud_drive_folders = admin.cloudfs.drives.all(user=bruce)

"""List both deleted and non-deleted cloud drive folders"""
cloud_drive_folders = admin.cloudfs.drives.all(list_filter=portal_enum.ListFilter.All)

"""List deleted cloud drive folders"""
cloud_drive_folders = admin.cloudfs.drives.all(list_filter=portal_enum.ListFilter.Deleted)
CloudDrives.add(name, group, owner, winacls=True, description=None, quota=None, compliance_settings=None)

Create a new Cloud Drive Folder (Cloud Volume)

Parameters:
  • name (str) – Name of the new folder

  • group (str) – Folder Group to assign this folder to

  • owner (cterasdk.core.types.UserAccount) – User account, the owner of the new folder

  • winacls (bool,optional) – Use Windows ACLs, defaults to True

  • description (str,optional) – Cloud drive folder description

  • quota (str,optional) – Cloud drive folder quota in GB

  • compliance_settings (cterasdk.common.object.Object,optional) – Compliance settings, defaults to disabled. Use cterasdk.core.types.ComplianceSettingsBuilder() to build the compliance settings object

"""Create a Cloud Drive folder, owned by a local user account 'svc_account'"""
svc_account = portal_types.UserAccount('svc_account')
admin.cloudfs.drives.add('DIR-001', 'FG-001', svc_account)
admin.cloudfs.drives.add('DIR-003', 'FG-003', svc_account, winacls = False) # disable Windows ACL's
admin.cloudfs.drives.add('DIR-003', 'FG-003', svc_account, quota = 1024) # Set folder quota, in GB

"""Create a Cloud Drive folder, owned by the domain user 'ctera.local\wbruce'"""
wbruce = portal_types.UserAccount('wbruce', 'ctera.local')
admin.cloudfs.drives.add('DIR-002', 'FG-002', wbruce)

"""Create immutable Cloud Drive folders"""

svc_account = portal_types.UserAccount('svc_account')

"""
Mode: Enterprise (i.e., allow privileged delete by the CTERA Compliance Officer role)
Retention Period: 7 Years.
Grace Period: 30 Minutes.
"""
admin.cloudfs.groups.add('FG-Enterprise', svc_account)
settings = portal_types.ComplianceSettingsBuilder.enterprise(7, portal_enum.Duration.Years).grace_period(30, portal_enum.Duration.Minutes).build()
admin.cloudfs.drives.add('Enterprise', 'FG-Enterprise', svc_account, compliance_settings=settings)

"""
Mode: Compliance (data cannot be deleted after grace period expires)
Retention Period: 1 Years.
Grace Period: 1 Hour.
"""
admin.cloudfs.groups.add('FG-Compliance', svc_account)
settings = portal_types.ComplianceSettingsBuilder.enterprise(1, portal_enum.Duration.Years).grace_period(1, portal_enum.Duration.Hours).build()
admin.cloudfs.drives.add('Compliance', 'FG-Compliance', svc_account, compliance_settings=settings)
CloudDrives.modify(current_name, owner, new_name=None, new_owner=None, new_group=None, description=None, winacls=None, quota=None, compliance_settings=None)

Modify a Cloud Drive Folder (Cloud Volume)

Parameters:
"""Update Quota of a Cloud Drive Folder"""
svc_account = portal_types.UserAccount('svc_account')
admin.cloudfs.drives.modify('DIR-001', svc_account, quota=5120) # Set folder quota to 5 TB
CloudDrives.delete(name, owner)

Delete a Cloud Drive Folder

Parameters:
  • name (str) – Name of the Cloud Drive Folder to delete

  • owner (cterasdk.core.types.UserAccount) – User account, the owner of the Cloud Drive Folder to delete

"""Delete a Cloud Drive folder, owned by the local user account 'svc_account'"""
svc_account = portal_types.UserAccount('svc_account')
admin.cloudfs.drives.delete('DIR-001', svc_account)

"""Delete a Cloud Drive folder, owned by the domain user 'ctera.local\wbruce'"""
wbruce = portal_types.UserAccount('wbruce', 'ctera.local')
admin.cloudfs.drives.delete('DIR-002', wbruce)
CloudDrives.recover(name, owner)

Recover a deleted a Cloud Drive Folder

Parameters:
  • name (str) – Name of the Cloud Drive Folder to un-delete

  • owner (cterasdk.core.types.UserAccount) – User account, the owner of the Cloud Drive Folder to delete

"""Recover a deleted Cloud Drive folder, owned by the local user account 'svc_account'"""
svc_account = portal_types.UserAccount('svc_account')
admin.cloudfs.drives.recover('DIR-001', svc_account)

"""Recover a deleted Cloud Drive folder, owned by the domain user 'ctera.local\wbruce'"""
wbruce = portal_types.UserAccount('wbruce', 'ctera.local')
admin.cloudfs.drives.recover('DIR-002', wbruce)
CloudDrives.setfacl(paths, acl, recursive=False)

Changing the file or Folder ACLs

Parameters:
  • paths (list(str)) – List of folder paths

  • acl (str) – Access control list (ACL) represented as an SDDL String

  • recursive (bool,optional) – Apply changes recursively to subfolders and files

"""Changing the file or Folder ACLs"""
folders_paths = ["portaladmin/cloudFolder/diagrams", "adrian/data/docs"]
sddl_string = 'O:S-1-12-1-1536910496-1126310805-1188065941-1612002142' \
              'G:S-1-12-1-1536910496-1126310805-1188065941-1612002142' \
              'D:AI(A;ID;FA;;;BA)(A;ID;FA;;;SY)(A;ID;0x1200a9;;;BU)(A;ID;0x1301bf;;;AU)'
admin.cloudfs.drives.setfacl(folders_paths, sddl_string, True)
CloudDrives.setoacl(paths, owner_sid, recursive=False)

Changing the File or Folder Owner SID or ACLs

Parameters:
  • paths (list(str)) – List of folder paths

  • owner_sid (str) – Owner SID (Security Descriptor)

  • recursive (bool,optional) – Apply changes recursively to subfolders and files

"""Changing the File or Folder Owner SID or ACLs"""
folders_paths = ["portaladmin/cloudFolder/diagrams", "dorian/data/docs"]
owner_sid = 'S-1-12-1-1536910496-1126310805-1188065941-1612002142'
admin.cloudfs.drives.setoacl(folders_paths, owner_sid, True)

Zones#

To manage zones, you must be a Read Write Administrator

Zones.get(name)

Get zone by name

Parameters:

name (str) – The name of the zone to get

Returns:

The requested zone

zone = admin.cloudfs.zones.get('ZN-001')
Zones.all(filters=None)

List Zones :param list[],optional filters: List of additional filters, defaults to None

Returns:

Iterator for all Zones

Return type:

cterasdk.lib.iterator.Iterator

for zone in admin.cloudfs.zones.all():
    print(zone)
Zones.search(name)

Search for Zones by name :param str name: Search query

Returns:

Iterator for all matching Zones

Return type:

cterasdk.lib.iterator.Iterator

for zone in admin.cloudfs.zones.search('ZN'):
    print(zone)
Zones.add(name, policy_type='selectedFolders', description=None)

Add a new zone

Parameters:
  • name (str) – The name of the new zone

  • policy_type (cterasdk.core.enum.PolicyType,optional) – Policy type of the new zone, defaults to cterasdk.core.enum.PolicyType.SELECT

  • description (str,optional) – The description of the new zone

"""
Policy Types:
- All: Include all cloud folders
- Select: Select one or more cloud folders to include
- None: Create an empty zone
"""

"""Create a zone with a description"""

admin.cloudfs.zones.add('ZN-NYS-001', description = 'The New York State Zone')

"""Create a zone and include all folders"""

admin.cloudfs.zones.add('ZN-NYS-002', 'All', 'All Folders')

"""Create an empty zone"""

admin.cloudfs.zones.add('ZN-NYS-003', 'None', 'Empty Zone')
Zones.add_folders(name, folder_finding_helpers)

Add the folders to the zone

Parameters:
"""
Add the following cloud folders to zone: 'ZN-001'

1) 'Accounting' folder owned by 'Bruce'
2) 'HR' folder owned by 'Diana'
"""

accounting = portal_types.CloudFSFolderFindingHelper('Accounting', 'Bruce')
hr = portal_types.CloudFSFolderFindingHelper('HR', 'Diana')

admin.cloudfs.zones.add_folders('ZN-001', [accounting, hr])
Zones.add_devices(name, device_names)

Add devices to a zone

Parameters:
  • name (str) – The name of the zone to add devices to

  • device_names (list[str]) – The names of the devices to add to the zone

admin.cloudfs.zones.add_devices('ZN-001', ['vGateway-01ba', 'vGateway-bd02'])
Zones.delete(name)

Delete a zone

Parameters:

name (str) – The name of the zone to delete

admin.cloudfs.zones.delete('ZN-001')

Timezone#

GlobalSettings.get_timezone()

Get timezone

admin.settings.global_settings.get_timezone()
GlobalSettings.set_timezone(timezone)

Set timezone

Parameters:

timezone (str) – Timezone

admin.settings.global_settings.set_timzeone('(GMT-05:00) Eastern Time (US , Canada)')

SSL Certificate#

SSL.get()

Retrieve details of the current installed SSL certificate

Return cterasdk.common.object.Object:

An object including the SSL certificate details

certificate = admin.ssl.get()
print(certificate)
SSL.thumbprint()

Get the SHA1 thumbprint of the Portal SSL certificate

print(admin.ssl.thumbprint)
SSL.export(destination=None)

Export the Portal SSL Certificate to a ZIP archive

Parameters:

destination (str,optional) – File destination, defaults to the default directory

admin.ssl.export()

admin.ssl.export(r'C:\Temp')  # export to an alternate location
SSL.import_from_zip(zipfile)

Import an SSL Certificate to CTERA Portal from a ZIP archive

Parameters:

zipfile (str) – A zip archive including the private key and SSL certificate chain

admin.ssl.import_from_zip(r'C:\Users\jsmith\Downloads\certificate.zip')
SSL.import_from_chain(private_key, *certificates)

Import an SSL Certificate to CTERA Portal from a chain

Parameters:
  • private_key (str) – The PEM-encoded private key, or a path to the PEM-encoded private key file

  • certificates (list[str]) – The PEM-encoded certificates, or a list of paths of the PEM-encoded certificate files

admin.ssl.import_from_chain(
    r'C:\Users\jsmith\Downloads\private.key',
    r'C:\Users\jsmith\Downloads\domain.crt',
    r'C:\Users\jsmith\Downloads\intermediate.crt',
    r'C:\Users\jsmith\Downloads\root.crt'
)

Logs#

Logs.get(topic='system', min_severity='info', origin_type='Portal', origin=None, before=None, after=None, filters=None)

Get logs from the Portal

Parameters:
  • topic (cterasdk.core.enum.LogTopic,optional) – Log topic to get, defaults to cterasdk.core.enum.LogTopic.System

  • min_severity (cterasdk.core.enum.Severity,optional) – Minimun severity of logs to get, defaults to cterasdk.core.enum.Severity.INFO

  • origin_type (cterasdk.core.enum.OriginType,optional) – Origin type of the logs to get, defaults to cterasdk.core.enum.OriginType.Portal

  • origin (str,optional) – Log origin (e.g. device name, Portal server name), defaults to None

  • before (str,optional) – Get logs before this date (in format “%m/%d/%Y %H:%M:%S”), defaults to None

  • after (str,optional) – Get logs after this date (in format “%m/%d/%Y %H:%M:%S”), defaults to None

  • filters (list[cterasdk.core.query.FilterBuilder],optional) – List of additional filters, defaults to None

Returns:

Iterator for all matching logs

Return type:

cterasdk.lib.iterator.Iterator[cterasdk.object.Object]

Logs.device(name, topic='system', min_severity='info', before=None, after=None, filters=None)

Get device logs from the Portal

Parameters:
  • name (str) – Name of a device

  • topic (cterasdk.core.enum.LogTopic,optional) – Log topic to get, defaults to cterasdk.core.enum.LogTopic.System

  • min_severity (cterasdk.core.enum.Severity,optional) – Minimun severity of logs to get, defaults to cterasdk.core.enum.Severity.INFO

  • before (str,optional) – Get logs before this date (in format “%m/%d/%Y %H:%M:%S”), defaults to None

  • after (str,optional) – Get logs after this date (in format “%m/%d/%Y %H:%M:%S”), defaults to None

  • filters (list[cterasdk.core.query.FilterBuilder],optional) – List of additional filters, defaults to None

Returns:

Iterator for all matching logs

Return type:

cterasdk.lib.iterator.Iterator[cterasdk.object.Object]

"""Retrieve all cloud backup logs for device 'WIN-SRV2019'"""
admin.logs.device('WIN-SRV2019', topic='backup')

Log Based Alerts#

Alerts.get()

Get a List of Log Based Alerts

Returns:

A list of alerts

Return type:

list[cterasdk.common.object.Object]

"""Get a list of log based alerts"""
for alert in admin.logs.alerts.get():
   print(alert)
Alerts.add(name, description=None, topic=None, log=None, min_severity=None, origin_type=None, content=None)

Add a Log Based Alert

Parameters:
  • name (str) – Alert name

  • description (str,optional) – Alert description

  • topic (cterasdk.core.enum.LogTopic,optional) – Log topic to get, defaults to any topic

  • log (str,optional) – Class name of the log

  • min_severity (cterasdk.core.enum.Severity,optional) – Minimun severity for triggering an alert, defaults to any severity

  • origin_type (cterasdk.core.enum.OriginType,optional) – Origin type of the log, defaults to any origin

  • content (str) – Content of the log message

Returns:

A list of alerts

Return type:

list[cterasdk.common.object.Object]

"""Alert on a volume full error event"""
admin.logs.alerts.add('Volume Full', topic='system', log='VolumeFull', origin_type='Device', min_severity='error')
Alerts.put(alerts)
Set Log Based Alerts

Use cterasdk.core.types.AlertBuilder() to build log based alerts

Parameters:

alerts (list[cterasdk.core.types.Alert]) – List of alerts

"""Set alerts. Overrides all existing alerts"""
volume_full = portal_types.AlertBuilder.name('volume_full').log('VolumeFull').build()
agent_repo = portal_types.AlertBuilder.name('agent_repo').log('AgentRepositoryNotReady').build()
admin.logs.alerts.put([volume_full, agent_repo])
Alerts.delete(name)

Remove a Log Based Alert

Parameters:

name (str) – Alert name

"""Delete an alert by name"""
admin.logs.alerts.delete('volume_full')

"""Delete all alerts"""
admin.logs.alerts.put([])

Syslog#

Syslog.is_enabled()

Check if forwarding log messages over syslog is enabled

Syslog.get_configuration()

Retrieve the syslog server configuration

Syslog.enable(server, port=514, protocol='UDP', min_severity='info')

Enable Syslog

Parameters:
Syslog.disable()

CLI Execution#

CLI.run_command(cli_command)

Run a CLI command

Parameters:

cli_command (str) – The CLI command to run on the gateway

Return str:

The response of the Portal

result = admin.cli.run_command('show /settings')
print(result)