Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for issue 3102 #3107

Merged
merged 4 commits into from
Aug 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions volttrontesting/fixtures/volttron_platform_fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,9 @@ def volttron_instance(request, **kwargs):
"""
address = kwargs.pop("vip_address", get_rand_vip())
wrapper = build_wrapper(address,
messagebus=request.param.pop('messagebus', 'zmq'),
ssl_auth=request.param.pop('ssl_auth', False),
auth_enabled=request.param.pop('auth_enabled', True),
messagebus=request.param.get('messagebus', 'zmq'),
ssl_auth=request.param.get('ssl_auth', False),
auth_enabled=request.param.get('auth_enabled', True),
**kwargs)
wrapper_pid = wrapper.p_process.pid

Expand Down Expand Up @@ -182,8 +182,8 @@ def get_n_volttron_instances(n, should_start=True, **kwargs):
address = kwargs.pop("vip_address", get_rand_vip())

wrapper = build_wrapper(address, should_start=should_start,
messagebus=request.param.pop('messagebus', 'zmq'),
ssl_auth=request.param.pop('ssl_auth', False),
messagebus=request.param.get('messagebus', 'zmq'),
ssl_auth=request.param.get('ssl_auth', False),
**kwargs)
instances.append(wrapper)
if should_start:
Expand Down
25 changes: 13 additions & 12 deletions volttrontesting/platform/test_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@


@pytest.fixture(scope="module")
def setup_control_connection(request, get_volttron_instances):
def setup_control_connection(request, volttron_instance):
""" Creates a single instance of VOLTTRON for testing purposes
"""
global wrapper, control_connection

wrapper = get_volttron_instances(1)
wrapper = volttron_instance

request.addfinalizer(wrapper.shutdown_platform)

Expand All @@ -27,14 +27,14 @@ def setup_control_connection(request, get_volttron_instances):
ks = KeyStore()
ks.generate()

control_connection = build_connection(identity="foo",
address=wrapper.vip_address,
peer=CONTROL,
serverkey=wrapper.serverkey,
publickey=ks.public,
secretkey=ks.secret,
instance_name=wrapper.instance_name,
message_bus=wrapper.messagebus)
control_connection = wrapper.build_connection(identity="foo",
address=wrapper.vip_address,
peer=CONTROL,
serverkey=wrapper.serverkey,
publickey=ks.public,
secretkey=ks.secret,
instance_name=wrapper.instance_name,
message_bus=wrapper.messagebus)

# Sleep a couple seconds to wait for things to startup
gevent.sleep(2)
Expand All @@ -49,11 +49,12 @@ def test_can_connect_to_control(setup_control_connection):


@pytest.mark.control
def test_can_get_peers(setup_control_connection):
def test_can_get_peers(setup_control_connection, volttron_instance):
wrapper, connection = setup_control_connection
peers = connection.peers()
assert CONTROL in peers
assert AUTH in peers
if volttron_instance.auth_enabled:
assert AUTH in peers
assert CONFIGURATION_STORE in peers


Expand Down
85 changes: 49 additions & 36 deletions volttrontesting/utils/platformwrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,9 +330,12 @@ def __init__(self, messagebus=None, ssl_auth=False, instance_name=None,

# Writes the main volttron config file for this instance.
store_message_bus_config(self.messagebus, self.instance_name)

# Update volttron config file with non-auth setting if auth_enabled is False
if not self.auth_enabled:
if self.auth_enabled:
keystorefile = os.path.join(self.volttron_home, 'keystore')
self.keystore = KeyStore(keystorefile)
self.keystore.generate()
else:
# Update volttron config file with non-auth setting if auth_enabled is False
config_path = os.path.join(self.volttron_home, "config")
if os.path.exists(config_path):
config = configparser.ConfigParser()
Expand All @@ -358,7 +361,6 @@ def __init__(self, messagebus=None, ssl_auth=False, instance_name=None,
if not self.debug_mode:
self.debug_mode = self.env.get('DEBUG', False)
self.skip_cleanup = self.env.get('SKIP_CLEANUP', False)

self._web_admin_api = None

@property
Expand Down Expand Up @@ -419,10 +421,11 @@ def build_connection(self, peer=None, address=None, identity=None,
self.logit(
'Default address was None so setting to current instances')
address = self.vip_address

if self.auth_enabled:
if address is None:
serverkey = self.serverkey
if serverkey is None:
serverkey = self.serverkey
if serverkey is None and address is not None:
self.logit("serverkey wasn't set but the address was.")
raise Exception("Invalid state.")
if publickey is None or secretkey is None:
Expand Down Expand Up @@ -479,31 +482,32 @@ def build_agent(self, address=None, should_spawn=True, identity=None,
print(f"Publickey is: {publickey}\nServerkey is: {serverkey}")
if serverkey is None:
serverkey = self.serverkey
if publickey is None:
self.logit(f'generating new public secret key pair {KeyStore.get_agent_keystore_path(identity=identity)}')
ks = KeyStore(KeyStore.get_agent_keystore_path(identity=identity))
publickey = ks.public
secretkey = ks.secret

if address is None:
self.logit('Using vip-address {address}'.format(
address=self.vip_address))
address = self.vip_address
if self.auth_enabled:
if publickey is None:
self.logit(
f'generating new public secret key pair {KeyStore.get_agent_keystore_path(identity=identity)}')
ks = KeyStore(KeyStore.get_agent_keystore_path(identity=identity))
publickey = ks.public
secretkey = ks.secret
if publickey and not serverkey:
self.logit('using instance serverkey: {}'.format(publickey))
serverkey = publickey
self.logit("BUILD agent VOLTTRON HOME: {}".format(self.volttron_home))
if self.bind_web_address:
kwargs['enable_web'] = True

if publickey and not serverkey:
self.logit('using instance serverkey: {}'.format(publickey))
serverkey = publickey
self.logit("BUILD agent VOLTTRON HOME: {}".format(self.volttron_home))
if self.bind_web_address:
kwargs['enable_web'] = True
if 'enable_store' not in kwargs:
kwargs['enable_store'] = False

if 'enable_store' not in kwargs:
kwargs['enable_store'] = False
if capabilities is None:
capabilities = dict(edit_config_store=dict(identity=identity))
print(f"Publickey is: {publickey}\nServerkey is: {serverkey}")

if capabilities is None:
capabilities = dict(edit_config_store=dict(identity=identity))
print(f"Publickey is: {publickey}\nServerkey is: {serverkey}")
if self.auth_enabled:
entry = AuthEntry(user_id=identity, identity=identity, credentials=publickey,
capabilities=capabilities,
comments="Added by platform wrapper")
Expand Down Expand Up @@ -599,6 +603,9 @@ def disable_auto_csr(self):
assert not self.is_auto_csr_enabled()

def add_capabilities(self, publickey, capabilities):
if not self.auth_enabled:
self.logit("Auth is not enabled, so ignore and return False")
return False
with with_os_environ(self.env):
if isinstance(capabilities, str) or isinstance(capabilities, dict):
capabilities = [capabilities]
Expand All @@ -619,17 +626,21 @@ def add_capabilities(self, publickey, capabilities):
# when invoked in quick succession. add_capabilities updates auth.json, gets the peerlist and calls all peers'
# auth.update rpc call. So sleeping here instead expecting individual test cases to sleep for long
gevent.sleep(2)
return True

@staticmethod
def add_capability(entry, capabilites):
def add_capability(self, entry, capabilities):
if not self.auth_enabled:
self.logit("Auth is not enabled, so ignore and return False")
return False
if isinstance(entry, str):
if entry not in capabilites:
capabilites[entry] = None
if entry not in capabilities:
capabilities[entry] = None
elif isinstance(entry, dict):
capabilites.update(entry)
capabilities.update(entry)
else:
raise ValueError("Invalid capability {}. Capability should be string or dictionary or list of string"
"and dictionary.")
return True

def set_auth_dict(self, auth_dict):
if auth_dict:
Expand Down Expand Up @@ -845,12 +856,13 @@ def startup_platform(self, vip_address, auth_dict=None,
pconfig = os.path.join(self.volttron_home, 'config')
config = {}

# Add platform's public key to known hosts file
publickey = self.keystore.public
known_hosts_file = os.path.join(self.volttron_home, 'known_hosts')
known_hosts = KnownHostsStore(known_hosts_file)
known_hosts.add(self.opts['vip_local_address'], publickey)
known_hosts.add(self.opts['vip_address'], publickey)
if self.auth_enabled:
# Add platform's public key to known hosts file
publickey = self.keystore.public
known_hosts_file = os.path.join(self.volttron_home, 'known_hosts')
known_hosts = KnownHostsStore(known_hosts_file)
known_hosts.add(self.opts['vip_local_address'], publickey)
known_hosts.add(self.opts['vip_address'], publickey)

# Set up the configuration file based upon the passed parameters.
parser = configparser.ConfigParser()
Expand Down Expand Up @@ -918,8 +930,9 @@ def startup_platform(self, vip_address, auth_dict=None,

utils.wait_for_volttron_startup(self.volttron_home, timeout)

self.serverkey = self.keystore.public
assert self.serverkey
if self.auth_enabled:
self.serverkey = self.keystore.public
assert self.serverkey

# Use dynamic_agent so we can look and see the agent with peerlist.
if not setupmode:
Expand Down
Loading