Skip to content

Commit

Permalink
Merge pull request #71 from rapyuta-robotics/devel
Browse files Browse the repository at this point in the history
🎉 release: v1.13.0
  • Loading branch information
pallabpain authored Dec 13, 2023
2 parents b6b3682 + 78c17a8 commit 53560aa
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 193 deletions.
3 changes: 1 addition & 2 deletions rapyuta_io/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@
BuildOptions
from .clients.buildoperation import BuildOperation, BuildOperationInfo
from .clients.project import Project
from .clients.secret import Secret, SecretConfigSourceSSHAuth, SecretConfigDocker, \
SecretConfigSourceBasicAuth
from .clients.secret import Secret, SecretConfigDocker
from .clients.rosbag import UploadOptions
from .clients.user_group import UserGroup

Expand Down
75 changes: 1 addition & 74 deletions rapyuta_io/clients/secret.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class Secret(ObjBase):
:param name: Name of the Secret
:type name: str
:param secret_config: Secret Configuration
:type secret_config: Union[:py:class:`~rapyuta_io.clients.secret.SecretConfigSourceSSHAuth`, :py:class:`~rapyuta_io.clients.secret.SecretConfigSourceBasicAuth`, :py:class:`~rapyuta_io.clients.secret.SecretConfigDocker`]
:type secret_config: Union[:py:class:`~rapyuta_io.clients.secret.SecretConfigDocker`]
"""
SECRET_PATH = '/api/secret'

Expand Down Expand Up @@ -111,8 +111,6 @@ def __str__(self):
return str(self.value)

DOCKER = 'kubernetes.io/dockercfg'
SOURCE_BASIC_AUTH = 'kubernetes.io/basic-auth'
SOURCE_SSH_AUTH = 'kubernetes.io/ssh-auth'


class _SecretConfigBase(six.with_metaclass(ABCMeta, ObjBase)):
Expand All @@ -132,77 +130,6 @@ def get_serialize_map(self):
pass


class SecretConfigSourceSSHAuth(_SecretConfigBase):
"""
SecretConfigSSHAuth represents Source Secret with SSH Authentication. This type of secrets can be used to access
private Git repositories using SSH, for building the Docker images from Source Code.
:param ssh_key: Private SSH key for authenticating with the Git repository hosting
:type ssh_key: str
"""

def __init__(self, ssh_key):
self.validate(ssh_key)
self.ssh_key = ssh_key

@staticmethod
def validate(ssh_key):
if not (isinstance(ssh_key, str) or isinstance(ssh_key, six.string_types)) or ssh_key == '':
raise InvalidParameterException('ssh_key cannot be empty')

@classmethod
def get_type(cls):
return SecretType.SOURCE_SSH_AUTH

def serialize(self):
return {
'ssh-privatekey': base64.b64encode(self.ssh_key.encode()).decode()
}


class SecretConfigSourceBasicAuth(_SecretConfigBase):
"""
SecretConfigSourceBasicAuth represents Source Secret with Basic Authentication. This type of secrets can be used to
access private Git repositories exposing HTTP interface, for building the Docker images from Source Code.
:param username: Username for the Git repository hosting
:type username: str
:param password: Password for the Git repository hosting
:type password: str
:param ca_cert: If the Git repository is using self-signed certificates, a CA Root Certificate can optionally be provided.
:type ca_cert: str
"""

def __init__(self, username, password, ca_cert=None):
self.validate(username, password, ca_cert)
self.username = username
self.password = password
self.ca_cert = ca_cert

@staticmethod
def validate(username, password, ca_cert):
if not isinstance(username, six.string_types) or username == '':
raise InvalidParameterException('username cannot be empty')
if not isinstance(password, six.string_types) or password == '':
raise InvalidParameterException('password cannot be empty')
if ca_cert is not None and (not isinstance(ca_cert, six.string_types) or ca_cert == ''):
raise InvalidParameterException('ca_cert cannot be empty')

@classmethod
def get_type(cls):
return SecretType.SOURCE_BASIC_AUTH

def serialize(self):
ret = {
'username': base64.b64encode(self.username.encode()).decode(),
'password': base64.b64encode(self.password.encode()).decode(),
}
if self.ca_cert is not None:
ret['ca.crt'] = base64.b64encode(self.ca_cert.encode()).decode()

return ret


class SecretConfigDocker(_SecretConfigBase):
"""
SecretConfigDocker represents Docker Secret for Docker registries. This type of secrets can be used to access
Expand Down
9 changes: 7 additions & 2 deletions rapyuta_io/rio_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -485,20 +485,22 @@ def delete_device(self, device_id):
raise InvalidParameterException('device_id needs to be a non empty string')
return self._dmClient.delete_device(device_id)

def toggle_features(self, device_id, features):
def toggle_features(self, device_id, features, config=None):
"""
Patch a device on rapyuta.io platform.
:param device_id: Device ID
:type device_id: str
:param features: A tuple of featues and their states
:type features: list<tuple>
:param config: A dict of additional feature configuration
:type config: dict
Following example demonstrates how to toggle features a device.
>>> from rapyuta_io import Client
>>> client = Client(auth_token='auth_token', project='project_guid')
>>> client.toggle_features('device-id', [('vpn', True), ('tracing', False)])
>>> client.toggle_features('device-id', [('vpn', True), ('tracing', False)], config={'vpn': {'advertise_routes': True}})
"""
if not device_id or not isinstance(device_id, six.string_types):
raise InvalidParameterException('device_id needs to be a non empty string')
Expand All @@ -510,6 +512,9 @@ def toggle_features(self, device_id, features):
feature, state = entry
data[feature] = state

if config is not None:
data['config'] = config

return self._dmClient.patch_daemons(device_id, data)

def create_package_from_manifest(self, manifest_filepath, retry_limit=0):
Expand Down
6 changes: 2 additions & 4 deletions sdk_test/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import six
from six.moves import filter

from rapyuta_io import Client, SecretConfigSourceSSHAuth, SecretConfigDocker, \
from rapyuta_io import Client, SecretConfigDocker, \
DeviceArch, Secret, Project
from rapyuta_io.utils.error import InvalidParameterException
from rapyuta_io.utils.utils import create_auth_header, \
Expand Down Expand Up @@ -154,12 +154,10 @@ def set_devices(self, devices):
self._devices = list(filter(filter_devices_by_name(), devices))

def create_secrets(self):
ssh_key = self._config['git']['ssh-key']
git_secret = self.client.create_secret(Secret('git-secret', SecretConfigSourceSSHAuth(ssh_key)))
docker = self._config['docker']
docker_secret = self.client.create_secret(Secret('docker-secret', SecretConfigDocker(
docker['username'], docker['password'], docker['email'])))
self._secrets = {'git': git_secret, 'docker': docker_secret}
self._secrets = {'docker': docker_secret}

def delete_secrets(self):
for secret in self._secrets.values():
Expand Down
5 changes: 3 additions & 2 deletions sdk_test/coreapi/project_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import unittest

from rapyuta_io import Client, Project, Secret, SecretConfigSourceSSHAuth
from rapyuta_io import Client, Project, Secret, SecretConfigDocker
from rapyuta_io.utils import BadRequestError
from rapyuta_io.utils.utils import generate_random_value
from sdk_test.config import Configuration
Expand Down Expand Up @@ -46,6 +46,7 @@ def test_client_without_project(self):
self.assertRaises(
BadRequestError,
lambda: client.create_secret(
Secret('test-secret', SecretConfigSourceSSHAuth('test'))
Secret('test-secret', SecretConfigDocker(username='username', password='password', email='[email protected]',
registry='quay.io'))
)
)
18 changes: 5 additions & 13 deletions sdk_test/coreapi/secret_test.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
from __future__ import absolute_import
import unittest

from rapyuta_io import Secret, SecretConfigSourceSSHAuth, SecretConfigSourceBasicAuth, \
SecretConfigDocker
from rapyuta_io import Secret, SecretConfigDocker
from sdk_test.config import Configuration
from sdk_test.util import get_logger

Expand All @@ -23,26 +22,19 @@ def assertSecret(self, secret):
self.assertIsNotNone(secret.created_at)
self.assertIsNotNone(secret.secret_type)

def test_create_secret_source_ssh_auth(self):
self.secret = self.config.client.create_secret(Secret('ssh-auth-test', SecretConfigSourceSSHAuth('test-ssh-key')))
self.assertSecret(self.secret)

def test_create_secret_source_http_auth(self):
self.secret = self.config.client.create_secret(Secret('basic-auth-test', SecretConfigSourceBasicAuth('user', 'pass')))
self.assertSecret(self.secret)

def test_create_secret_docker(self):
self.secret = self.config.client.create_secret(Secret('docker-test', SecretConfigDocker('user','pass', 'email')))
self.assertSecret(self.secret)

def test_list_secret_docker(self):
self.secret = self.config.client.create_secret(Secret('ssh-auth-test', SecretConfigSourceSSHAuth('test-ssh-key')))
self.secret = self.config.client.create_secret(Secret('docker-test', SecretConfigDocker('user','pass', 'email')))
secret_list = self.config.client.list_secrets()
secret_list = [s for s in secret_list if s.guid == self.secret.guid]
self.assertEqual(len(secret_list), 1)

def test_update_secret_source_basic_auth(self):
self.secret = self.config.client.create_secret(Secret('basic-auth-test', SecretConfigSourceBasicAuth('user', 'pass')))
self.secret = self.config.client.update_secret(self.secret.guid, Secret('basic-auth-test', SecretConfigSourceBasicAuth('user', 'newpass')))
def test_update_secret_source_docker(self):
self.secret = self.config.client.create_secret(Secret('docker-test', SecretConfigDocker('user','pass', 'email')))
self.secret = self.config.client.update_secret(self.secret.guid, Secret('docker-test', SecretConfigDocker('user1','pass1', 'email1')))
self.assertSecret(self.secret)

Loading

0 comments on commit 53560aa

Please sign in to comment.