pvw-cli 1.2.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pvw-cli might be problematic. Click here for more details.
- purviewcli/__init__.py +27 -0
- purviewcli/__main__.py +15 -0
- purviewcli/cli/__init__.py +5 -0
- purviewcli/cli/account.py +199 -0
- purviewcli/cli/cli.py +170 -0
- purviewcli/cli/collections.py +502 -0
- purviewcli/cli/domain.py +361 -0
- purviewcli/cli/entity.py +2436 -0
- purviewcli/cli/glossary.py +533 -0
- purviewcli/cli/health.py +250 -0
- purviewcli/cli/insight.py +113 -0
- purviewcli/cli/lineage.py +1103 -0
- purviewcli/cli/management.py +141 -0
- purviewcli/cli/policystore.py +103 -0
- purviewcli/cli/relationship.py +75 -0
- purviewcli/cli/scan.py +357 -0
- purviewcli/cli/search.py +527 -0
- purviewcli/cli/share.py +478 -0
- purviewcli/cli/types.py +831 -0
- purviewcli/cli/unified_catalog.py +3540 -0
- purviewcli/cli/workflow.py +402 -0
- purviewcli/client/__init__.py +21 -0
- purviewcli/client/_account.py +1877 -0
- purviewcli/client/_collections.py +1761 -0
- purviewcli/client/_domain.py +414 -0
- purviewcli/client/_entity.py +3545 -0
- purviewcli/client/_glossary.py +3233 -0
- purviewcli/client/_health.py +501 -0
- purviewcli/client/_insight.py +2873 -0
- purviewcli/client/_lineage.py +2138 -0
- purviewcli/client/_management.py +2202 -0
- purviewcli/client/_policystore.py +2915 -0
- purviewcli/client/_relationship.py +1351 -0
- purviewcli/client/_scan.py +2607 -0
- purviewcli/client/_search.py +1472 -0
- purviewcli/client/_share.py +272 -0
- purviewcli/client/_types.py +2708 -0
- purviewcli/client/_unified_catalog.py +5112 -0
- purviewcli/client/_workflow.py +2734 -0
- purviewcli/client/api_client.py +1295 -0
- purviewcli/client/business_rules.py +675 -0
- purviewcli/client/config.py +231 -0
- purviewcli/client/data_quality.py +433 -0
- purviewcli/client/endpoint.py +123 -0
- purviewcli/client/endpoints.py +554 -0
- purviewcli/client/exceptions.py +38 -0
- purviewcli/client/lineage_visualization.py +797 -0
- purviewcli/client/monitoring_dashboard.py +712 -0
- purviewcli/client/rate_limiter.py +30 -0
- purviewcli/client/retry_handler.py +125 -0
- purviewcli/client/scanning_operations.py +523 -0
- purviewcli/client/settings.py +1 -0
- purviewcli/client/sync_client.py +250 -0
- purviewcli/plugins/__init__.py +1 -0
- purviewcli/plugins/plugin_system.py +709 -0
- pvw_cli-1.2.8.dist-info/METADATA +1618 -0
- pvw_cli-1.2.8.dist-info/RECORD +60 -0
- pvw_cli-1.2.8.dist-info/WHEEL +5 -0
- pvw_cli-1.2.8.dist-info/entry_points.txt +3 -0
- pvw_cli-1.2.8.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"""
|
|
2
|
+
usage:
|
|
3
|
+
pvw management addRootCollectionAdmin --subscriptionId=<val> --resourceGroupName=<val> --accountName=<val> --objectId=<val>
|
|
4
|
+
pvw management checkNameAvailability --subscriptionId=<val> --accountName=<val>
|
|
5
|
+
pvw management createAccount --subscriptionId=<val> --resourceGroupName=<val> --accountName=<val> --payloadFile=<val>
|
|
6
|
+
pvw management defaultAccount --scopeTenantId=<val> --scopeType=<val> --scope=<val>
|
|
7
|
+
pvw management deleteAccount --subscriptionId=<val> --resourceGroupName=<val> --accountName=<val>
|
|
8
|
+
pvw management deletePrivateEndpoint --subscriptionId=<val> --resourceGroupName=<val> --accountName=<val> --privateEndpointConnectionName=<val>
|
|
9
|
+
pvw management listKeys --subscriptionId=<val> --resourceGroupName=<val> --accountName=<val>
|
|
10
|
+
pvw management listOperations
|
|
11
|
+
pvw management listPrivateLinkResources --subscriptionId=<val> --resourceGroupName=<val> --accountName=<val> [--groupId=<val>]
|
|
12
|
+
pvw management putPrivateEndpoint --subscriptionId=<val> --resourceGroupName=<val> --accountName=<val> --privateEndpointConnectionName=<val> --payloadFile=<val>
|
|
13
|
+
pvw management readAccount --subscriptionId=<val> --resourceGroupName=<val> --accountName=<val>
|
|
14
|
+
pvw management readAccounts --subscriptionId=<val> [--resourceGroupName=<val>]
|
|
15
|
+
pvw management readPrivateEndpoint --subscriptionId=<val> --resourceGroupName=<val> --accountName=<val> --privateEndpointConnectionName=<val>
|
|
16
|
+
pvw management readPrivateEndpoints --subscriptionId=<val> --resourceGroupName=<val> --accountName=<val>
|
|
17
|
+
pvw management removeDefaultAccount --scopeTenantId=<val> --scopeType=<val> --scope=<val>
|
|
18
|
+
pvw management setDefaultAccount --subscriptionId=<val> --resourceGroupName=<val> --accountName=<val> --scopeTenantId=<val> --scopeType=<val> --scope=<val>
|
|
19
|
+
pvw management updateAccount --subscriptionId=<val> --resourceGroupName=<val> --accountName=<val> --payloadFile=<val>
|
|
20
|
+
|
|
21
|
+
options:
|
|
22
|
+
--subscriptionId=<val> [string] The subscription ID.
|
|
23
|
+
--resourceGroupName=<val> [string] The name of the resource group.
|
|
24
|
+
--accountName=<val> [string] The name of the account.
|
|
25
|
+
--scopeTenantId=<val> [string] The scope tenant in which the default account is set.
|
|
26
|
+
--scopeType=<val> [string] The scope where the default account is set (Tenant or Subscription).
|
|
27
|
+
--scope=<val> [string] The scope object ID (e.g. sub ID or tenant ID).
|
|
28
|
+
--groupId=<val> [string] The group identifier.
|
|
29
|
+
--privateEndpointConnectionName=<val> [string] The name of the private endpoint connection.
|
|
30
|
+
--objectId=<val> [string] Gets or sets the object identifier of the admin.
|
|
31
|
+
|
|
32
|
+
"""
|
|
33
|
+
import click
|
|
34
|
+
from purviewcli.client._management import Management
|
|
35
|
+
|
|
36
|
+
@click.group()
|
|
37
|
+
def management():
|
|
38
|
+
"""
|
|
39
|
+
Manage metastore operations in Microsoft Purview.
|
|
40
|
+
"""
|
|
41
|
+
pass
|
|
42
|
+
|
|
43
|
+
def _invoke_management_method(method_name, **kwargs):
|
|
44
|
+
client = Management()
|
|
45
|
+
method = getattr(client, method_name)
|
|
46
|
+
args = {f'--{k}': v for k, v in kwargs.items() if v is not None}
|
|
47
|
+
try:
|
|
48
|
+
result = method(args)
|
|
49
|
+
click.echo(result)
|
|
50
|
+
except Exception as e:
|
|
51
|
+
click.echo(f"[ERROR] {e}", err=True)
|
|
52
|
+
|
|
53
|
+
@management.command()
|
|
54
|
+
def listoperations():
|
|
55
|
+
"""List management operations"""
|
|
56
|
+
_invoke_management_method('managementListOperations')
|
|
57
|
+
|
|
58
|
+
@management.command()
|
|
59
|
+
@click.option('--subscriptionId', required=True)
|
|
60
|
+
@click.option('--accountName', required=True)
|
|
61
|
+
def checknameavailability(subscriptionid, accountname):
|
|
62
|
+
"""Check account name availability"""
|
|
63
|
+
_invoke_management_method('managementCheckNameAvailability', subscriptionId=subscriptionid, accountName=accountname)
|
|
64
|
+
|
|
65
|
+
@management.command()
|
|
66
|
+
@click.option('--subscriptionId', required=True)
|
|
67
|
+
@click.option('--resourceGroupName', required=False)
|
|
68
|
+
def readaccounts(subscriptionid, resourcegroupname):
|
|
69
|
+
"""Read all accounts or by resource group"""
|
|
70
|
+
_invoke_management_method('managementReadAccounts', subscriptionId=subscriptionid, resourceGroupName=resourcegroupname)
|
|
71
|
+
|
|
72
|
+
@management.command()
|
|
73
|
+
@click.option('--subscriptionId', required=True)
|
|
74
|
+
@click.option('--resourceGroupName', required=True)
|
|
75
|
+
@click.option('--accountName', required=True)
|
|
76
|
+
def readaccount(subscriptionid, resourcegroupname, accountname):
|
|
77
|
+
"""Read a specific account"""
|
|
78
|
+
_invoke_management_method('managementReadAccount', subscriptionId=subscriptionid, resourceGroupName=resourcegroupname, accountName=accountname)
|
|
79
|
+
|
|
80
|
+
@management.command()
|
|
81
|
+
@click.option('--subscriptionId', required=True)
|
|
82
|
+
@click.option('--resourceGroupName', required=True)
|
|
83
|
+
@click.option('--accountName', required=True)
|
|
84
|
+
@click.option('--payloadFile', required=True, type=click.Path(exists=True))
|
|
85
|
+
def createaccount(subscriptionid, resourcegroupname, accountname, payloadfile):
|
|
86
|
+
"""Create a new account"""
|
|
87
|
+
_invoke_management_method('managementCreateAccount', subscriptionId=subscriptionid, resourceGroupName=resourcegroupname, accountName=accountname, payloadFile=payloadfile)
|
|
88
|
+
|
|
89
|
+
@management.command()
|
|
90
|
+
@click.option('--subscriptionId', required=True)
|
|
91
|
+
@click.option('--resourceGroupName', required=True)
|
|
92
|
+
@click.option('--accountName', required=True)
|
|
93
|
+
def deleteaccount(subscriptionid, resourcegroupname, accountname):
|
|
94
|
+
"""Delete an account"""
|
|
95
|
+
_invoke_management_method('managementDeleteAccount', subscriptionId=subscriptionid, resourceGroupName=resourcegroupname, accountName=accountname)
|
|
96
|
+
|
|
97
|
+
@management.command()
|
|
98
|
+
@click.option('--subscriptionId', required=True)
|
|
99
|
+
@click.option('--resourceGroupName', required=True)
|
|
100
|
+
@click.option('--accountName', required=True)
|
|
101
|
+
def listkeys(subscriptionid, resourcegroupname, accountname):
|
|
102
|
+
"""List account keys"""
|
|
103
|
+
_invoke_management_method('managementListKeys', subscriptionId=subscriptionid, resourceGroupName=resourcegroupname, accountName=accountname)
|
|
104
|
+
|
|
105
|
+
@management.command()
|
|
106
|
+
@click.option('--subscriptionId', required=True)
|
|
107
|
+
@click.option('--resourceGroupName', required=True)
|
|
108
|
+
@click.option('--accountName', required=True)
|
|
109
|
+
@click.option('--payloadFile', required=True, type=click.Path(exists=True))
|
|
110
|
+
def updateaccount(subscriptionid, resourcegroupname, accountname, payloadfile):
|
|
111
|
+
"""Update an account"""
|
|
112
|
+
_invoke_management_method('managementUpdateAccount', subscriptionId=subscriptionid, resourceGroupName=resourcegroupname, accountName=accountname, payloadFile=payloadfile)
|
|
113
|
+
|
|
114
|
+
@management.command()
|
|
115
|
+
@click.option('--scopeTenantId', required=True)
|
|
116
|
+
@click.option('--scopeType', required=True)
|
|
117
|
+
@click.option('--scope', required=True)
|
|
118
|
+
def defaultaccount(scopetenantid, scopetype, scope):
|
|
119
|
+
"""Get the default account for a scope"""
|
|
120
|
+
_invoke_management_method('managementDefaultAccount', scopeTenantId=scopetenantid, scopeType=scopetype, scope=scope)
|
|
121
|
+
|
|
122
|
+
@management.command()
|
|
123
|
+
@click.option('--subscriptionId', required=True)
|
|
124
|
+
@click.option('--resourceGroupName', required=True)
|
|
125
|
+
@click.option('--accountName', required=True)
|
|
126
|
+
@click.option('--scopeTenantId', required=True)
|
|
127
|
+
@click.option('--scopeType', required=True)
|
|
128
|
+
@click.option('--scope', required=True)
|
|
129
|
+
def setdefaultaccount(subscriptionid, resourcegroupname, accountname, scopetenantid, scopetype, scope):
|
|
130
|
+
"""Set the default account for a scope"""
|
|
131
|
+
_invoke_management_method('managementSetDefaultAccount', subscriptionId=subscriptionid, resourceGroupName=resourcegroupname, accountName=accountname, scopeTenantId=scopetenantid, scopeType=scopetype, scope=scope)
|
|
132
|
+
|
|
133
|
+
@management.command()
|
|
134
|
+
@click.option('--scopeTenantId', required=True)
|
|
135
|
+
@click.option('--scopeType', required=True)
|
|
136
|
+
@click.option('--scope', required=True)
|
|
137
|
+
def removedefaultaccount(scopetenantid, scopetype, scope):
|
|
138
|
+
"""Remove the default account for a scope"""
|
|
139
|
+
_invoke_management_method('managementRemoveDefaultAccount', scopeTenantId=scopetenantid, scopeType=scopetype, scope=scope)
|
|
140
|
+
|
|
141
|
+
__all__ = ['management']
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Manage policy store operations in Microsoft Purview using modular Click-based commands.
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
policystore delete-data-policy Delete a data policy
|
|
6
|
+
policystore delete-data-policy-scope Delete a data policy scope
|
|
7
|
+
policystore put-data-policy Create or update a data policy
|
|
8
|
+
policystore put-data-policy-scope Create or update a data policy scope
|
|
9
|
+
policystore put-metadata-policy Create or update a metadata policy
|
|
10
|
+
policystore read-data-policies Read data policies
|
|
11
|
+
policystore read-data-policy-scopes Read data policy scopes
|
|
12
|
+
policystore read-metadata-policies Read metadata policies
|
|
13
|
+
policystore read-metadata-policy Read a metadata policy by collection or policyId
|
|
14
|
+
policystore read-metadata-roles Read metadata roles
|
|
15
|
+
policystore --help Show this help message and exit
|
|
16
|
+
|
|
17
|
+
Options:
|
|
18
|
+
-h --help Show this help message and exit
|
|
19
|
+
"""
|
|
20
|
+
import click
|
|
21
|
+
from purviewcli.client._policystore import Policystore
|
|
22
|
+
|
|
23
|
+
@click.group()
|
|
24
|
+
def policystore():
|
|
25
|
+
"""
|
|
26
|
+
Manage policy store operations in Microsoft Purview.
|
|
27
|
+
"""
|
|
28
|
+
pass
|
|
29
|
+
|
|
30
|
+
def _invoke_policystore_method(method_name, **kwargs):
|
|
31
|
+
client = Policystore()
|
|
32
|
+
method = getattr(client, method_name)
|
|
33
|
+
args = {f'--{k}': v for k, v in kwargs.items() if v is not None}
|
|
34
|
+
try:
|
|
35
|
+
result = method(args)
|
|
36
|
+
click.echo(result)
|
|
37
|
+
except Exception as e:
|
|
38
|
+
click.echo(f"[ERROR] {e}", err=True)
|
|
39
|
+
|
|
40
|
+
@policystore.command(name='delete-data-policy')
|
|
41
|
+
@click.option('--policyName', required=True)
|
|
42
|
+
def delete_data_policy(policyname):
|
|
43
|
+
"""Delete a data policy"""
|
|
44
|
+
_invoke_policystore_method('policystoreDeleteDataPolicy', policyName=policyname)
|
|
45
|
+
|
|
46
|
+
@policystore.command(name='delete-data-policy-scope')
|
|
47
|
+
@click.option('--policyName', required=True)
|
|
48
|
+
@click.option('--datasource', required=True)
|
|
49
|
+
def delete_data_policy_scope(policyname, datasource):
|
|
50
|
+
"""Delete a data policy scope"""
|
|
51
|
+
_invoke_policystore_method('policystoreDeleteDataPolicyScope', policyName=policyname, datasource=datasource)
|
|
52
|
+
|
|
53
|
+
@policystore.command(name='put-data-policy')
|
|
54
|
+
@click.option('--policyName', required=True)
|
|
55
|
+
@click.option('--payloadFile', required=True, type=click.Path(exists=True))
|
|
56
|
+
def put_data_policy(policyname, payloadfile):
|
|
57
|
+
"""Create or update a data policy"""
|
|
58
|
+
_invoke_policystore_method('policystorePutDataPolicy', policyName=policyname, payloadFile=payloadfile)
|
|
59
|
+
|
|
60
|
+
@policystore.command(name='put-data-policy-scope')
|
|
61
|
+
@click.option('--policyName', required=True)
|
|
62
|
+
@click.option('--payloadFile', required=True, type=click.Path(exists=True))
|
|
63
|
+
def put_data_policy_scope(policyname, payloadfile):
|
|
64
|
+
"""Create or update a data policy scope"""
|
|
65
|
+
_invoke_policystore_method('policystorePutDataPolicyScope', policyName=policyname, payloadFile=payloadfile)
|
|
66
|
+
|
|
67
|
+
@policystore.command(name='put-metadata-policy')
|
|
68
|
+
@click.option('--policyId', required=True)
|
|
69
|
+
@click.option('--payloadFile', required=True, type=click.Path(exists=True))
|
|
70
|
+
def put_metadata_policy(policyid, payloadfile):
|
|
71
|
+
"""Create or update a metadata policy"""
|
|
72
|
+
_invoke_policystore_method('policystorePutMetadataPolicy', policyId=policyid, payloadFile=payloadfile)
|
|
73
|
+
|
|
74
|
+
@policystore.command(name='read-data-policies')
|
|
75
|
+
@click.option('--policyName', required=False)
|
|
76
|
+
def read_data_policies(policyname):
|
|
77
|
+
"""Read data policies"""
|
|
78
|
+
_invoke_policystore_method('policystoreReadDataPolicies', policyName=policyname)
|
|
79
|
+
|
|
80
|
+
@policystore.command(name='read-data-policy-scopes')
|
|
81
|
+
@click.option('--policyName', required=True)
|
|
82
|
+
def read_data_policy_scopes(policyname):
|
|
83
|
+
"""Read data policy scopes"""
|
|
84
|
+
_invoke_policystore_method('policystoreReadDataPolicyScopes', policyName=policyname)
|
|
85
|
+
|
|
86
|
+
@policystore.command(name='read-metadata-policies')
|
|
87
|
+
def read_metadata_policies():
|
|
88
|
+
"""Read metadata policies"""
|
|
89
|
+
_invoke_policystore_method('policystoreReadMetadataPolicies')
|
|
90
|
+
|
|
91
|
+
@policystore.command(name='read-metadata-policy')
|
|
92
|
+
@click.option('--collectionName', required=False)
|
|
93
|
+
@click.option('--policyId', required=False)
|
|
94
|
+
def read_metadata_policy(collectionname, policyid):
|
|
95
|
+
"""Read a metadata policy by collection or policyId"""
|
|
96
|
+
_invoke_policystore_method('policystoreReadMetadataPolicy', collectionName=collectionname, policyId=policyid)
|
|
97
|
+
|
|
98
|
+
@policystore.command(name='read-metadata-roles')
|
|
99
|
+
def read_metadata_roles():
|
|
100
|
+
"""Read metadata roles"""
|
|
101
|
+
_invoke_policystore_method('policystoreReadMetadataRoles')
|
|
102
|
+
|
|
103
|
+
__all__ = ['policystore']
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""
|
|
2
|
+
usage:
|
|
3
|
+
pvw relationship create --payloadFile=<val>
|
|
4
|
+
pvw relationship delete --guid=<val>
|
|
5
|
+
pvw relationship put --payloadFile=<val>
|
|
6
|
+
pvw relationship read --guid=<val> [--extendedInfo]
|
|
7
|
+
|
|
8
|
+
options:
|
|
9
|
+
--purviewName=<val> [string] Microsoft Purview account name.
|
|
10
|
+
--extendedInfo [boolean] Limits whether includes extended information [default: false].
|
|
11
|
+
--guid=<val> [string] The globally unique identifier of the relationship.
|
|
12
|
+
--payloadFile=<val> [string] File path to a valid JSON document.
|
|
13
|
+
|
|
14
|
+
"""
|
|
15
|
+
import click
|
|
16
|
+
import json
|
|
17
|
+
from purviewcli.client._relationship import Relationship
|
|
18
|
+
|
|
19
|
+
@click.group()
|
|
20
|
+
def relationship():
|
|
21
|
+
"""
|
|
22
|
+
Manage entity relationships in Microsoft Purview.
|
|
23
|
+
"""
|
|
24
|
+
pass
|
|
25
|
+
|
|
26
|
+
@relationship.command()
|
|
27
|
+
@click.option('--payload-file', type=click.Path(exists=True), required=True, help='File path to a valid JSON document')
|
|
28
|
+
def create(payload_file):
|
|
29
|
+
"""Create a new relationship"""
|
|
30
|
+
try:
|
|
31
|
+
args = {'--payloadFile': payload_file}
|
|
32
|
+
client = Relationship()
|
|
33
|
+
result = client.relationshipCreate(args)
|
|
34
|
+
click.echo(json.dumps(result, indent=2))
|
|
35
|
+
except Exception as e:
|
|
36
|
+
click.echo(f"Error: {e}")
|
|
37
|
+
|
|
38
|
+
@relationship.command()
|
|
39
|
+
@click.option('--guid', required=True, help='The globally unique identifier of the relationship')
|
|
40
|
+
def delete(guid):
|
|
41
|
+
"""Delete a relationship by GUID"""
|
|
42
|
+
try:
|
|
43
|
+
args = {'--guid': guid}
|
|
44
|
+
client = Relationship()
|
|
45
|
+
result = client.relationshipDelete(args)
|
|
46
|
+
click.echo(json.dumps(result, indent=2))
|
|
47
|
+
except Exception as e:
|
|
48
|
+
click.echo(f"Error: {e}")
|
|
49
|
+
|
|
50
|
+
@relationship.command()
|
|
51
|
+
@click.option('--payload-file', type=click.Path(exists=True), required=True, help='File path to a valid JSON document')
|
|
52
|
+
def put(payload_file):
|
|
53
|
+
"""Update or create a relationship (PUT)"""
|
|
54
|
+
try:
|
|
55
|
+
args = {'--payloadFile': payload_file}
|
|
56
|
+
client = Relationship()
|
|
57
|
+
result = client.relationshipPut(args)
|
|
58
|
+
click.echo(json.dumps(result, indent=2))
|
|
59
|
+
except Exception as e:
|
|
60
|
+
click.echo(f"Error: {e}")
|
|
61
|
+
|
|
62
|
+
@relationship.command()
|
|
63
|
+
@click.option('--guid', required=True, help='The globally unique identifier of the relationship')
|
|
64
|
+
@click.option('--extended-info', is_flag=True, default=False, help='Include extended information')
|
|
65
|
+
def read(guid, extended_info):
|
|
66
|
+
"""Read a relationship by GUID"""
|
|
67
|
+
try:
|
|
68
|
+
args = {'--guid': guid, '--extendedInfo': extended_info}
|
|
69
|
+
client = Relationship()
|
|
70
|
+
result = client.relationshipRead(args)
|
|
71
|
+
click.echo(json.dumps(result, indent=2))
|
|
72
|
+
except Exception as e:
|
|
73
|
+
click.echo(f"Error: {e}")
|
|
74
|
+
|
|
75
|
+
__all__ = ['relationship']
|
purviewcli/cli/scan.py
ADDED
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Manage scan operations in Microsoft Purview using modular Click-based commands.
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
scan cancel-scan Cancel a scan run
|
|
6
|
+
scan delete-classification-rule Delete a classification rule
|
|
7
|
+
scan delete-credential Delete a credential
|
|
8
|
+
scan delete-data-source Delete a data source
|
|
9
|
+
scan delete-key-vault Delete a key vault
|
|
10
|
+
scan delete-scan Delete a scan
|
|
11
|
+
scan delete-scan-ruleset Delete a scan ruleset
|
|
12
|
+
scan delete-trigger Delete a scan trigger
|
|
13
|
+
scan put-classification-rule Create or update a classification rule
|
|
14
|
+
scan put-credential Create or update a credential
|
|
15
|
+
scan put-data-source Create or update a data source
|
|
16
|
+
scan put-filter Create or update a scan filter
|
|
17
|
+
scan put-key-vault Create or update a key vault
|
|
18
|
+
scan put-scan Create or update a scan
|
|
19
|
+
scan put-scan-ruleset Create or update a scan ruleset
|
|
20
|
+
scan put-trigger Create or update a scan trigger
|
|
21
|
+
scan read-classification-rule Read a classification rule
|
|
22
|
+
scan read-classification-rules Read classification rules
|
|
23
|
+
scan read-credential Read a credential
|
|
24
|
+
scan read-data-source Read a data source
|
|
25
|
+
scan read-data-sources Read data sources
|
|
26
|
+
scan read-filters Read scan filters
|
|
27
|
+
scan read-key-vault Read a key vault
|
|
28
|
+
scan read-key-vaults Read key vaults
|
|
29
|
+
scan read-scan Read a scan
|
|
30
|
+
scan read-scan-history Read scan history
|
|
31
|
+
scan read-scan-ruleset Read a scan ruleset
|
|
32
|
+
scan read-scan-rulesets Read scan rulesets
|
|
33
|
+
scan read-scans Read scans
|
|
34
|
+
scan read-system-scan-ruleset Read a system scan ruleset
|
|
35
|
+
scan run-scan Run a scan
|
|
36
|
+
scan tag-classification-version Tag a classification version
|
|
37
|
+
scan --help Show this help message and exit
|
|
38
|
+
|
|
39
|
+
Options:
|
|
40
|
+
-h --help Show this help message and exit
|
|
41
|
+
"""
|
|
42
|
+
# Scan CLI for Purview Data Map API (Atlas v2)
|
|
43
|
+
"""
|
|
44
|
+
CLI for managing scans, scan rulesets, triggers, and scan runs
|
|
45
|
+
"""
|
|
46
|
+
import click
|
|
47
|
+
from purviewcli.client._scan import Scan
|
|
48
|
+
|
|
49
|
+
@click.group()
|
|
50
|
+
def scan():
|
|
51
|
+
"""Manage scans and related resources"""
|
|
52
|
+
pass
|
|
53
|
+
|
|
54
|
+
# Helper to invoke Scan methods
|
|
55
|
+
def _invoke_scan_method(method_name, **kwargs):
|
|
56
|
+
scan_client = Scan()
|
|
57
|
+
method = getattr(scan_client, method_name)
|
|
58
|
+
args = {f'--{k}': v for k, v in kwargs.items() if v is not None}
|
|
59
|
+
try:
|
|
60
|
+
result = method(args)
|
|
61
|
+
click.echo(result)
|
|
62
|
+
except Exception as e:
|
|
63
|
+
click.echo(f"[ERROR] {e}", err=True)
|
|
64
|
+
|
|
65
|
+
@scan.command()
|
|
66
|
+
@click.option('--dataSourceName', required=True)
|
|
67
|
+
@click.option('--scanName', required=True)
|
|
68
|
+
@click.option('--runId', required=True)
|
|
69
|
+
def cancelscan(datasourcename, scanname, runid):
|
|
70
|
+
"""Cancel a running scan"""
|
|
71
|
+
_invoke_scan_method('scanCancelScan', dataSourceName=datasourcename, scanName=scanname, runId=runid)
|
|
72
|
+
|
|
73
|
+
@scan.command()
|
|
74
|
+
@click.option('--classificationRuleName', required=True)
|
|
75
|
+
def deleteclassificationrule(classificationrulename):
|
|
76
|
+
"""Delete a classification rule"""
|
|
77
|
+
_invoke_scan_method('scanDeleteClassificationRule', classificationRuleName=classificationrulename)
|
|
78
|
+
|
|
79
|
+
@scan.command()
|
|
80
|
+
@click.option('--credentialName', required=True)
|
|
81
|
+
def deletecredential(credentialname):
|
|
82
|
+
"""Delete a credential"""
|
|
83
|
+
_invoke_scan_method('scanDeleteCredential', credentialName=credentialname)
|
|
84
|
+
|
|
85
|
+
@scan.command()
|
|
86
|
+
@click.option('--dataSourceName', required=True)
|
|
87
|
+
def deletedatasource(datasourcename):
|
|
88
|
+
"""Delete a data source"""
|
|
89
|
+
_invoke_scan_method('scanDeleteDataSource', dataSourceName=datasourcename)
|
|
90
|
+
|
|
91
|
+
@scan.command()
|
|
92
|
+
@click.option('--keyVaultName', required=True)
|
|
93
|
+
def deletekeyvault(keyvaultname):
|
|
94
|
+
"""Delete a key vault"""
|
|
95
|
+
_invoke_scan_method('scanDeleteKeyVault', keyVaultName=keyvaultname)
|
|
96
|
+
|
|
97
|
+
@scan.command()
|
|
98
|
+
@click.option('--dataSourceName', required=True)
|
|
99
|
+
@click.option('--scanName', required=True)
|
|
100
|
+
def deletescan(datasourcename, scanname):
|
|
101
|
+
"""Delete a scan"""
|
|
102
|
+
_invoke_scan_method('scanDeleteScan', dataSourceName=datasourcename, scanName=scanname)
|
|
103
|
+
|
|
104
|
+
@scan.command()
|
|
105
|
+
@click.option('--scanRulesetName', required=True)
|
|
106
|
+
def deletescanruleset(scanrulesetname):
|
|
107
|
+
"""Delete a scan ruleset"""
|
|
108
|
+
_invoke_scan_method('scanDeleteScanRuleset', scanRulesetName=scanrulesetname)
|
|
109
|
+
|
|
110
|
+
@scan.command()
|
|
111
|
+
@click.option('--dataSourceName', required=True)
|
|
112
|
+
@click.option('--scanName', required=True)
|
|
113
|
+
def deletetrigger(datasourcename, scanname):
|
|
114
|
+
"""Delete a scan trigger"""
|
|
115
|
+
_invoke_scan_method('scanDeleteTrigger', dataSourceName=datasourcename, scanName=scanname)
|
|
116
|
+
|
|
117
|
+
@scan.command()
|
|
118
|
+
@click.option('--classificationRuleName', required=True)
|
|
119
|
+
@click.option('--payloadFile', required=True, type=click.Path(exists=True))
|
|
120
|
+
def putclassificationrule(classificationrulename, payloadfile):
|
|
121
|
+
"""Create or update a classification rule"""
|
|
122
|
+
_invoke_scan_method('scanPutClassificationRule', classificationRuleName=classificationrulename, payloadFile=payloadfile)
|
|
123
|
+
|
|
124
|
+
@scan.command()
|
|
125
|
+
@click.option('--credentialName', required=True)
|
|
126
|
+
@click.option('--payloadFile', required=True, type=click.Path(exists=True))
|
|
127
|
+
def putcredential(credentialname, payloadfile):
|
|
128
|
+
"""Create or update a credential"""
|
|
129
|
+
_invoke_scan_method('scanPutCredential', credentialName=credentialname, payloadFile=payloadfile)
|
|
130
|
+
|
|
131
|
+
@scan.command()
|
|
132
|
+
@click.option('--dataSourceName', required=True)
|
|
133
|
+
@click.option('--payloadFile', required=True, type=click.Path(exists=True))
|
|
134
|
+
def putdatasource(datasourcename, payloadfile):
|
|
135
|
+
"""Create or update a data source"""
|
|
136
|
+
_invoke_scan_method('scanPutDataSource', dataSourceName=datasourcename, payloadFile=payloadfile)
|
|
137
|
+
|
|
138
|
+
@scan.command()
|
|
139
|
+
@click.option('--dataSourceName', required=True)
|
|
140
|
+
@click.option('--scanName', required=True)
|
|
141
|
+
@click.option('--payloadFile', required=True, type=click.Path(exists=True))
|
|
142
|
+
def putfilter(datasourcename, scanname, payloadfile):
|
|
143
|
+
"""Create or update a scan filter"""
|
|
144
|
+
_invoke_scan_method('scanPutFilter', dataSourceName=datasourcename, scanName=scanname, payloadFile=payloadfile)
|
|
145
|
+
|
|
146
|
+
@scan.command()
|
|
147
|
+
@click.option('--keyVaultName', required=True)
|
|
148
|
+
@click.option('--payloadFile', required=True, type=click.Path(exists=True))
|
|
149
|
+
def putkeyvault(keyvaultname, payloadfile):
|
|
150
|
+
"""Create or update a key vault"""
|
|
151
|
+
_invoke_scan_method('scanPutKeyVault', keyVaultName=keyvaultname, payloadFile=payloadfile)
|
|
152
|
+
|
|
153
|
+
@scan.command()
|
|
154
|
+
@click.option('--dataSourceName', required=True)
|
|
155
|
+
@click.option('--scanName', required=True)
|
|
156
|
+
@click.option('--payloadFile', required=True, type=click.Path(exists=True))
|
|
157
|
+
def putscan(datasourcename, scanname, payloadfile):
|
|
158
|
+
"""Create or update a scan"""
|
|
159
|
+
_invoke_scan_method('scanPutScan', dataSourceName=datasourcename, scanName=scanname, payloadFile=payloadfile)
|
|
160
|
+
|
|
161
|
+
@scan.command()
|
|
162
|
+
@click.option('--scanRulesetName', required=True)
|
|
163
|
+
@click.option('--payloadFile', required=True, type=click.Path(exists=True))
|
|
164
|
+
def putscanruleset(scanrulesetname, payloadfile):
|
|
165
|
+
"""Create or update a scan ruleset"""
|
|
166
|
+
_invoke_scan_method('scanPutScanRuleset', scanRulesetName=scanrulesetname, payloadFile=payloadfile)
|
|
167
|
+
|
|
168
|
+
@scan.command()
|
|
169
|
+
@click.option('--dataSourceName', required=True)
|
|
170
|
+
@click.option('--scanName', required=True)
|
|
171
|
+
@click.option('--payloadFile', required=True, type=click.Path(exists=True))
|
|
172
|
+
def puttrigger(datasourcename, scanname, payloadfile):
|
|
173
|
+
"""Create or update a scan trigger"""
|
|
174
|
+
_invoke_scan_method('scanPutTrigger', dataSourceName=datasourcename, scanName=scanname, payloadFile=payloadfile)
|
|
175
|
+
|
|
176
|
+
@scan.command()
|
|
177
|
+
@click.option('--classificationRuleName', required=True)
|
|
178
|
+
def readclassificationrule(classificationrulename):
|
|
179
|
+
"""Read a classification rule"""
|
|
180
|
+
_invoke_scan_method('scanReadClassificationRule', classificationRuleName=classificationrulename)
|
|
181
|
+
|
|
182
|
+
@scan.command()
|
|
183
|
+
@click.option('--classificationRuleName', required=True)
|
|
184
|
+
def readclassificationruleversions(classificationrulename):
|
|
185
|
+
"""Read classification rule versions"""
|
|
186
|
+
_invoke_scan_method('scanReadClassificationRuleVersions', classificationRuleName=classificationrulename)
|
|
187
|
+
|
|
188
|
+
@scan.command()
|
|
189
|
+
def readclassificationrules():
|
|
190
|
+
"""Read all classification rules"""
|
|
191
|
+
_invoke_scan_method('scanReadClassificationRules')
|
|
192
|
+
|
|
193
|
+
@scan.command()
|
|
194
|
+
@click.option('--credentialName', required=False)
|
|
195
|
+
def readcredential(credentialname):
|
|
196
|
+
"""Read a credential or all credentials"""
|
|
197
|
+
_invoke_scan_method('scanReadCredential', credentialName=credentialname)
|
|
198
|
+
|
|
199
|
+
@scan.command()
|
|
200
|
+
@click.option('--dataSourceName', required=True)
|
|
201
|
+
def readdatasource(datasourcename):
|
|
202
|
+
"""Read a data source"""
|
|
203
|
+
_invoke_scan_method('scanReadDataSource', dataSourceName=datasourcename)
|
|
204
|
+
|
|
205
|
+
@scan.command()
|
|
206
|
+
@click.option('--collectionName', required=False)
|
|
207
|
+
def readdatasources(collectionname):
|
|
208
|
+
"""Read all data sources or by collection"""
|
|
209
|
+
_invoke_scan_method('scanReadDataSources', collectionName=collectionname)
|
|
210
|
+
|
|
211
|
+
@scan.command()
|
|
212
|
+
@click.option('--dataSourceName', required=True)
|
|
213
|
+
@click.option('--scanName', required=True)
|
|
214
|
+
def readfilters(datasourcename, scanname):
|
|
215
|
+
"""Read scan filters"""
|
|
216
|
+
_invoke_scan_method('scanReadFilters', dataSourceName=datasourcename, scanName=scanname)
|
|
217
|
+
|
|
218
|
+
@scan.command()
|
|
219
|
+
@click.option('--keyVaultName', required=True)
|
|
220
|
+
def readkeyvault(keyvaultname):
|
|
221
|
+
"""Read a key vault"""
|
|
222
|
+
_invoke_scan_method('scanReadKeyVault', keyVaultName=keyvaultname)
|
|
223
|
+
|
|
224
|
+
@scan.command()
|
|
225
|
+
def readkeyvaults():
|
|
226
|
+
"""Read all key vaults"""
|
|
227
|
+
_invoke_scan_method('scanReadKeyVaults')
|
|
228
|
+
|
|
229
|
+
@scan.command()
|
|
230
|
+
@click.option('--dataSourceName', required=True)
|
|
231
|
+
@click.option('--scanName', required=True)
|
|
232
|
+
def readscanhistory(datasourcename, scanname):
|
|
233
|
+
"""Read scan history"""
|
|
234
|
+
_invoke_scan_method('scanReadScanHistory', dataSourceName=datasourcename, scanName=scanname)
|
|
235
|
+
|
|
236
|
+
@scan.command()
|
|
237
|
+
@click.option('--scanRulesetName', required=True)
|
|
238
|
+
def readscanruleset(scanrulesetname):
|
|
239
|
+
"""Read a scan ruleset"""
|
|
240
|
+
_invoke_scan_method('scanReadScanRuleset', scanRulesetName=scanrulesetname)
|
|
241
|
+
|
|
242
|
+
@scan.command()
|
|
243
|
+
def readscanrulesets():
|
|
244
|
+
"""Read all scan rulesets"""
|
|
245
|
+
_invoke_scan_method('scanReadScanRulesets')
|
|
246
|
+
|
|
247
|
+
@scan.command()
|
|
248
|
+
@click.option('--dataSourceName', required=True)
|
|
249
|
+
@click.option('--scanName', required=True)
|
|
250
|
+
def readscan(datasourcename, scanname):
|
|
251
|
+
"""Read a scan"""
|
|
252
|
+
_invoke_scan_method('scanReadScan', dataSourceName=datasourcename, scanName=scanname)
|
|
253
|
+
|
|
254
|
+
@scan.command()
|
|
255
|
+
@click.option('--dataSourceName', required=True)
|
|
256
|
+
def readscans(datasourcename):
|
|
257
|
+
"""Read all scans for a data source"""
|
|
258
|
+
_invoke_scan_method('scanReadScans', dataSourceName=datasourcename)
|
|
259
|
+
|
|
260
|
+
@scan.command()
|
|
261
|
+
@click.option('--dataSourceType', required=True)
|
|
262
|
+
def readsystemscanruleset(datasourcetype):
|
|
263
|
+
"""Read a system scan ruleset"""
|
|
264
|
+
_invoke_scan_method('scanReadSystemScanRuleset', dataSourceType=datasourcetype)
|
|
265
|
+
|
|
266
|
+
@scan.command()
|
|
267
|
+
@click.option('--dataSourceType', required=True)
|
|
268
|
+
def readsystemscanrulesetlatest(datasourcetype):
|
|
269
|
+
"""Read latest system scan ruleset"""
|
|
270
|
+
_invoke_scan_method('scanReadSystemScanRulesetLatest', dataSourceType=datasourcetype)
|
|
271
|
+
|
|
272
|
+
@scan.command()
|
|
273
|
+
@click.option('--version', required=True)
|
|
274
|
+
@click.option('--dataSourceType', required=True)
|
|
275
|
+
def readsystemscanrulesetversion(version, datasourcetype):
|
|
276
|
+
"""Read a specific version of a system scan ruleset"""
|
|
277
|
+
_invoke_scan_method('scanReadSystemScanRulesetVersion', version=version, dataSourceType=datasourcetype)
|
|
278
|
+
|
|
279
|
+
@scan.command()
|
|
280
|
+
@click.option('--dataSourceType', required=True)
|
|
281
|
+
def readsystemscanrulesetversions(datasourcetype):
|
|
282
|
+
"""Read all versions of a system scan ruleset"""
|
|
283
|
+
_invoke_scan_method('scanReadSystemScanRulesetVersions', dataSourceType=datasourcetype)
|
|
284
|
+
|
|
285
|
+
@scan.command()
|
|
286
|
+
def readsystemscanrulesets():
|
|
287
|
+
"""Read all system scan rulesets"""
|
|
288
|
+
_invoke_scan_method('scanReadSystemScanRulesets')
|
|
289
|
+
|
|
290
|
+
@scan.command()
|
|
291
|
+
@click.option('--dataSourceName', required=True)
|
|
292
|
+
@click.option('--scanName', required=True)
|
|
293
|
+
def readtrigger(datasourcename, scanname):
|
|
294
|
+
"""Read a scan trigger"""
|
|
295
|
+
_invoke_scan_method('scanReadTrigger', dataSourceName=datasourcename, scanName=scanname)
|
|
296
|
+
|
|
297
|
+
@scan.command()
|
|
298
|
+
@click.option('--dataSourceName', required=True)
|
|
299
|
+
@click.option('--scanName', required=True)
|
|
300
|
+
@click.option('--scanLevel', required=False, default='Full')
|
|
301
|
+
def runscan(datasourcename, scanname, scanlevel):
|
|
302
|
+
"""Run a scan"""
|
|
303
|
+
_invoke_scan_method('scanRunScan', dataSourceName=datasourcename, scanName=scanname, scanLevel=scanlevel)
|
|
304
|
+
|
|
305
|
+
@scan.command()
|
|
306
|
+
@click.option('--classificationRuleName', required=True)
|
|
307
|
+
@click.option('--classificationRuleVersion', required=True, type=int)
|
|
308
|
+
@click.option('--action', required=True)
|
|
309
|
+
def tagclassificationversion(classificationrulename, classificationruleversion, action):
|
|
310
|
+
"""Tag a classification rule version"""
|
|
311
|
+
_invoke_scan_method('scanTagClassificationVersion', classificationRuleName=classificationrulename, classificationRuleVersion=classificationruleversion, action=action)
|
|
312
|
+
|
|
313
|
+
@scan.command()
|
|
314
|
+
def list():
|
|
315
|
+
"""List all scans (TODO: add filtering options)"""
|
|
316
|
+
# TODO: Call Scan().scanReadScans()
|
|
317
|
+
pass
|
|
318
|
+
|
|
319
|
+
@scan.command()
|
|
320
|
+
def read():
|
|
321
|
+
"""Read a scan by name"""
|
|
322
|
+
# TODO: Call Scan().scanReadScan()
|
|
323
|
+
pass
|
|
324
|
+
|
|
325
|
+
@scan.command()
|
|
326
|
+
def create():
|
|
327
|
+
"""Create a new scan"""
|
|
328
|
+
# TODO: Call Scan().scanPutScan()
|
|
329
|
+
pass
|
|
330
|
+
|
|
331
|
+
@scan.command()
|
|
332
|
+
def update():
|
|
333
|
+
"""Update an existing scan"""
|
|
334
|
+
# TODO: Call Scan().scanPutScan()
|
|
335
|
+
pass
|
|
336
|
+
|
|
337
|
+
@scan.command()
|
|
338
|
+
def delete():
|
|
339
|
+
"""Delete a scan by name"""
|
|
340
|
+
# TODO: Call Scan().scanDeleteScan()
|
|
341
|
+
pass
|
|
342
|
+
|
|
343
|
+
@scan.command()
|
|
344
|
+
def run():
|
|
345
|
+
"""Run a scan"""
|
|
346
|
+
# TODO: Call Scan().scanRunScan()
|
|
347
|
+
pass
|
|
348
|
+
|
|
349
|
+
@scan.command()
|
|
350
|
+
def cancel():
|
|
351
|
+
"""Cancel a running scan"""
|
|
352
|
+
# TODO: Call Scan().scanCancelScan()
|
|
353
|
+
pass
|
|
354
|
+
|
|
355
|
+
# TODO: Add commands for rulesets, triggers, scan history, etc.
|
|
356
|
+
|
|
357
|
+
__all__ = ['scan']
|