Skip to content

Commit

Permalink
Merge pull request delphix#330 from rasantel/CP-4097
Browse files Browse the repository at this point in the history
CP-4097 Merge plugin password vaults project branch into production branch
  • Loading branch information
rasantel authored Feb 3, 2021
2 parents c27b9a1 + 23bac75 commit 82dd1a3
Show file tree
Hide file tree
Showing 20 changed files with 578 additions and 21 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 3.0.0
current_version = 3.1.0.dev2
commit = False
tag = False
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(\.(?P<release>[a-z]+)(?P<dev>\d+))?
Expand Down
1 change: 1 addition & 0 deletions common/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
bump2version==0.5.11
contextlib2==0.6.0.post1 ; python_version < '3'
enum34==1.1.6
funcsigs==1.0.2 ; python_version < '3.0'
importlib-metadata==0.23 ; python_version < '3.8'
more-itertools==5.0.0 ; python_version <= '2.7'
Expand Down
2 changes: 1 addition & 1 deletion common/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
PYTHON_SRC = 'src/main/python'

install_requires = [
"dvp-api == 1.4.0",
"dvp-api == 1.5.0.dev1",
]

with open(os.path.join(PYTHON_SRC, 'dlpx/virtualization/common/VERSION')) as version_file:
Expand Down
2 changes: 1 addition & 1 deletion common/src/main/python/dlpx/virtualization/common/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.0.0
3.1.0.dev2
127 changes: 125 additions & 2 deletions common/src/main/python/dlpx/virtualization/common/_common_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
# Copyright (c) 2019 by Delphix. All rights reserved.
#

from dlpx.virtualization.api import common_pb2
from abc import ABCMeta
from dlpx.virtualization.api import common_pb2, libs_pb2
from dlpx.virtualization.common.exceptions import IncorrectTypeError
from enum import IntEnum

"""Classes used for Plugin Operations
Expand All @@ -17,7 +19,10 @@
"RemoteConnection",
"RemoteEnvironment",
"RemoteHost",
"RemoteUser"]
"RemoteUser",
"Credentials",
"PasswordCredentials",
"KeyPairCredentials"]


class RemoteConnection(object):
Expand Down Expand Up @@ -293,3 +298,121 @@ def from_proto(user):
common_pb2.RemoteUser)
remote_user = RemoteUser(name=user.name, reference=user.reference)
return remote_user


class Credentials(object):
"""Plugin base class for CredentialsResult to be used for plugin operations
and library functions.
Plugin authors should use this instead of the corresponding protobuf generated
class.
Args:
username: User name.
"""
def __init__(self, username):
if not isinstance(username, basestring):
raise IncorrectTypeError(
Credentials,
'username',
type(username),
basestring)
self.__username = username

__metaclass__ = ABCMeta

@property
def username(self):
return self.__username


class PasswordCredentials(Credentials):
"""Plugin class for CredentialsResult with password to be used for plugin operations
and library functions.
Plugin authors should use this instead of the corresponding protobuf generated
class.
Args:
username: User name.
password: Password.
"""
def __init__(self, username, password):
super(PasswordCredentials, self).__init__(username)
if not isinstance(password, basestring):
raise IncorrectTypeError(
PasswordCredentials,
'password',
type(password),
basestring)
self.__password = password

@property
def password(self):
return self.__password

@staticmethod
def from_proto(credentials_result):
"""Converts protobuf class libs_pb2.CredentialsResult to plugin class PasswordCredentials
"""
if not isinstance(credentials_result, libs_pb2.CredentialsResult):
raise IncorrectTypeError(
PasswordCredentials,
'credentials_result',
type(credentials_result),
libs_pb2.CredentialsResult)
return PasswordCredentials(
username=credentials_result.username, password=credentials_result.pasword)


class KeyPairCredentials(Credentials):
"""Plugin class for CredentialsResult with key pair to be used for plugin operations
and library functions.
Plugin authors should use this instead of the corresponding protobuf generated
class.
Args:
username (str): User name.
private_key (str): Private key.
public_key (str): Public key corresponding to private key. Empty string if not present.
"""
def __init__(self, username, private_key, public_key):
super(KeyPairCredentials, self).__init__(username)
if not isinstance(private_key, basestring):
raise IncorrectTypeError(
KeyPairCredentials,
'private_key',
type(private_key),
basestring)
self.__private_key = private_key
if not isinstance(public_key, basestring):
raise IncorrectTypeError(
KeyPairCredentials,
'public_key',
type(public_key),
basestring)
self.__public_key = public_key

@property
def private_key(self):
return self.__private_key

@property
def public_key(self):
return self.__public_key

@staticmethod
def from_proto(credentials_result):
"""Converts protobuf class libs_pb2.CredentialsResult to plugin class KeyPairCredentials
"""
if not isinstance(credentials_result, libs_pb2.CredentialsResult):
raise IncorrectTypeError(
KeyPairCredentials,
'credentials_result',
type(credentials_result),
libs_pb2.CredentialsResult)
return KeyPairCredentials(
username=credentials_result.username,
private_key=credentials_result.key_pair.private_key,
public_key=credentials_result.key_pair.public_key)
2 changes: 1 addition & 1 deletion dvp/src/main/python/dlpx/virtualization/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.0.0
3.1.0.dev2
1 change: 1 addition & 0 deletions libs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
./../common
bump2version==0.5.11
contextlib2==0.6.0.post1 ; python_version < '3'
enum34==1.1.6
funcsigs==1.0.2 ; python_version < '3.3'
importlib-metadata==1.3.0 ; python_version < '3.8'
mock==3.0.5
Expand Down
2 changes: 1 addition & 1 deletion libs/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
version = version_file.read().strip()

install_requires = [
"dvp-api == 1.4.0",
"dvp-api == 1.5.0.dev1",
"dvp-common == {}".format(version)
]

Expand Down
2 changes: 1 addition & 1 deletion libs/src/main/python/dlpx/virtualization/libs/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.0.0
3.1.0.dev2
70 changes: 68 additions & 2 deletions libs/src/main/python/dlpx/virtualization/libs/libs.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@
from dlpx.virtualization.libs.exceptions import (IncorrectArgumentTypeError,
LibraryError,
PluginScriptError)
from dlpx.virtualization.common._common_classes import RemoteConnection
from dlpx.virtualization.common._common_classes import (RemoteConnection,
PasswordCredentials,
KeyPairCredentials)
from google.protobuf import json_format
from google.protobuf.struct_pb2 import Struct

import logging

Expand All @@ -39,7 +43,9 @@
"run_bash",
"run_sync",
"run_powershell",
"run_expect"
"run_expect",
"retrieve_credentials",
"upgrade_password"
]


Expand Down Expand Up @@ -410,3 +416,63 @@ def _log_request(message, log_level):

response = internal_libs.log(log_request)
_handle_response(response)


def retrieve_credentials(credentials_supplier):
"""This is an internal wrapper around the Virtualization library's credentials retrieval API.
Given a supplier provided by Virtualization, retrieves the credentials from that supplier.
Args:
credentials_supplier (dict): Properties that make up a supplier of credentials.
Return:
Subclass of Credentials retrieved from supplier. Either a PasswordCredentials or a KeyPairCredentials
from dlpx.virtualization.common._common_classes.
"""
from dlpx.virtualization._engine import libs as internal_libs

if not isinstance(credentials_supplier, dict):
raise IncorrectArgumentTypeError('credentials_supplier', type(credentials_supplier), dict)

credentials_request = libs_pb2.CredentialsRequest()
credentials_struct = Struct()
credentials_struct.update(credentials_supplier)
credentials_request.credentials_supplier.CopyFrom(credentials_struct)

response = internal_libs.retrieve_credentials(credentials_request)

credentials_result = _handle_response(response)
if credentials_result.password != "":
return PasswordCredentials(credentials_result.username, credentials_result.password)
return KeyPairCredentials(
credentials_result.username,
credentials_result.key_pair.private_key,
credentials_result.key_pair.public_key)


def upgrade_password(password, username=None):
"""This is an internal wrapper around Virtualization's credentials-supplier conversion API.
It is intended for use during plugin upgrade when a plugin needs to transform a password
value into a more generic credentials supplier object.
Args:
password (basestring): Plain password string.
username (basestring, defaults to None): User name contained in the password credential supplier to return.
Return:
Credentials supplier (dict) that supplies the given password and username.
"""
from dlpx.virtualization._engine import libs as internal_libs

if not isinstance(password, basestring):
raise IncorrectArgumentTypeError('password', type(password), basestring)
if username and not isinstance(username, basestring):
raise IncorrectArgumentTypeError('username', type(username), basestring, required=False)

upgrade_password_request = libs_pb2.UpgradePasswordRequest()
upgrade_password_request.password = password
if username:
upgrade_password_request.username = username

response = internal_libs.upgrade_password(upgrade_password_request)

upgrade_password_result = _handle_response(response)
return json_format.MessageToDict(upgrade_password_result.credentials_supplier)
Loading

0 comments on commit 82dd1a3

Please sign in to comment.