You're Invited:Meet the Socket Team at RSAC and BSidesSF 2026, March 23–26.RSVP
Socket
Book a DemoSign in
Socket

sym-cli

Package Overview
Dependencies
Maintainers
1
Versions
176
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

sym-cli - pypi Package Compare versions

Comparing version
0.4.11
to
0.5.0
+98
sym/cli/saml_clients/aws_config.py
import os
from configparser import ConfigParser
from functools import cached_property
from pathlib import Path
from typing import Iterator, Tuple
from boto3 import setup_default_session
from sym.shared.cli.helpers.contexts import push_env
from sym.shared.cli.helpers.keywords_to_options import Argument
from sym.cli.helpers.boto import get_identity
from ..decorators import command_require_bins, intercept_errors, run_subprocess
from ..errors import InvalidResource
from ..helpers.params import Profile
from .saml_client import SAMLClient
# The docs say that the credentials file is for sensitive values like actual access keys etc
# and the config file for less sensitive things like role names, SSO configs.
AwsConfigPath = Path(os.getenv("AWS_CONFIG_FILE", Path.home() / ".aws" / "config"))
class AwsConfig(SAMLClient):
binary = "aws"
option_value = "aws-config"
priority = 0
setup_help = f"Set up your profile in `{str(AwsConfigPath)}`."
resource: str
options: "GlobalOptions"
def __init__(self, resource: str, *, options: "GlobalOptions") -> None:
super().__init__(resource, options=options)
# Make the default session use our AWS profile so we don't need to manage sessions in
# whatever other call chains there are to get AWS creds
setup_default_session(profile_name=resource)
@classmethod
def _read_creds_config(cls):
config = ConfigParser(strict=False)
if AwsConfigPath.exists():
config.read(AwsConfigPath)
return config
@classmethod
def validate_resource(cls, resource: str):
config = cls._read_creds_config()
return config.has_section(cls._profile_name(resource))
@cached_property
def _section(self):
config = self.__class__._read_creds_config()
return config[self.__class__._profile_name(self.resource)]
@classmethod
def _profile_name(cls, resource: str):
return f"profile {resource}"
def raise_if_invalid(self):
if self.__class__.validate_resource(self.resource):
return
raise InvalidResource(
self.resource, self.__class__._read_creds_config().sections()
)
# Returning an empty dict here because we set up a default boto session above, so no need
# for creds here
def get_creds(self):
return {}
@intercept_errors()
@run_subprocess
@command_require_bins(binary)
def _exec(self, *args: str, **opts: str) -> Iterator[Tuple[Argument, ...]]:
with push_env("AWS_PROFILE", self.resource):
yield (*args, opts)
def is_setup(self) -> bool:
return AwsConfigPath.exists()
def _ensure_config(self, profile: Profile) -> ConfigParser:
return ConfigParser(strict=False)
def _ensure_session(self, *, force: bool):
if not force and not self._creds_expiring():
return
get_identity(self)
def get_profile(self):
return Profile(
display_name=self.resource,
region=self._section.get("region"),
arn=self._section.get("x_principal_arn"),
ansible_bucket=self._section.get("x_sym_ansible_bucket"),
)
def send_analytics_event(self):
pass
+4
-2
Metadata-Version: 2.1
Name: sym-cli
Version: 0.4.11
Version: 0.5.0
Summary: Sym's Official CLI for Users

@@ -11,5 +11,7 @@ Home-page: https://symops.com/

Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3
Requires-Dist: PyYAML (>=5.3.1,<6.0.0)

@@ -16,0 +18,0 @@ Requires-Dist: SecretStorage (>=3.2.0,<4.0.0)

[tool.poetry]
name = "sym-cli"
version = "0.4.11"
version = "0.5.0"
description = "Sym's Official CLI for Users"

@@ -5,0 +5,0 @@ authors = ["SymOps, Inc. <pypi@symops.io>"]

@@ -35,9 +35,12 @@ import json

creds = saml_client.get_creds()
return boto3.client(
service,
config=BotoConfig(region_name=get_region(saml_client, creds)),
aws_access_key_id=creds["AWS_ACCESS_KEY_ID"],
aws_secret_access_key=creds["AWS_SECRET_ACCESS_KEY"],
aws_session_token=creds.get("AWS_SESSION_TOKEN"),
)
if access_key_id := creds.get("AWS_ACCESS_KEY_ID"):
return boto3.client(
service,
config=BotoConfig(region_name=get_region(saml_client, creds)),
aws_access_key_id=access_key_id,
aws_secret_access_key=creds["AWS_SECRET_ACCESS_KEY"],
aws_session_token=creds.get("AWS_SESSION_TOKEN"),
)
# If there is no access key id, then assume that the boto3 default session is set up
return boto3.client(service)

@@ -44,0 +47,0 @@

@@ -184,23 +184,2 @@ from typing import Dict, List, NamedTuple, Optional, Tuple, TypedDict

},
"healthy-health": {
"resource_env_var": "ENVIRONMENT",
"users": {"ssh": "ubuntu"},
"domain": "healthy-health.co",
"aws_saml_url": (
"https://healthy-health.okta.com/home/amazon_aws/0oagrj7yFaVtJoI2N5d5/272"
),
"aws_okta_params": {
"mfa_provider": "OKTA",
"assume_role_ttl": "1h",
"session_ttl": "30m",
},
"saml2aws_params": {"mfa": "Auto", "aws_session_duration": "1800"},
"profiles": {
"prod": Profile(
display_name="Prod",
region="us-east-1",
arn="arn:aws:iam::223440862848:role/ssm-healthy-health-user-prod",
),
},
},
}

@@ -207,0 +186,0 @@

@@ -21,3 +21,5 @@ import os

# This client assumes that access key and secret are defined in the credentials file.
# If you want to use a named profile that works with SSO or some other supported AWS credential
# process, use AwsConfig
class AwsProfile(SAMLClient):

@@ -24,0 +26,0 @@ binary = "aws"

@@ -10,4 +10,4 @@ from typing import Literal, Optional, Type

SAMLClientName = Literal["auto", "aws-okta", "saml2aws", "aws-profile"]
AUTO_EXCLUDED_SAML_CLIENT_NAMES = ["aws-profile"]
SAMLClientName = Literal["auto", "aws-okta", "saml2aws", "aws-profile", "aws-config"]
AUTO_EXCLUDED_SAML_CLIENT_NAMES = ["aws-profile", "aws-config"]

@@ -14,0 +14,0 @@

@@ -36,3 +36,3 @@ import socket

regions = ec2_client.get_regions()
assert len(regions) == 26
assert len(regions) == 27
assert "us-east-1" in regions

@@ -39,0 +39,0 @@

@@ -1,1 +0,1 @@

__version__ = '0.4.11'
__version__ = '0.5.0'
# -*- coding: utf-8 -*-
from setuptools import setup
packages = \
['cli',
'cli.actions',
'cli.ansible',
'cli.ansible.connection',
'cli.commands',
'cli.constants',
'cli.data',
'cli.helpers',
'cli.helpers.check',
'cli.helpers.ec2',
'cli.saml_clients',
'cli.tests',
'cli.tests.commands',
'cli.tests.decorators',
'cli.tests.helpers',
'cli.tests.helpers.ec2',
'cli.tests.helpers.updater',
'cli.tests.integration',
'cli.tests.saml_clients']
package_data = \
{'': ['*'], 'cli.tests.helpers.updater': ['responses/*']}
install_requires = \
['PyYAML>=5.3.1,<6.0.0',
'SecretStorage>=3.2.0,<4.0.0',
'analytics-python>=1.3.1,<2.0.0',
'boto3>=1.16.20,<2.0.0',
'click-option-group>=0.5.1,<0.6.0',
'click>=8.0.0,<9.0.0',
'colorama<0.4.4',
'cryptography==3.4.8',
'immutables>=0.14,<0.15',
'keyring>=21.5.0,<22.0.0',
'mistune<2.0.0',
'policyuniverse>=1.3.2,<2.0.0',
'portalocker>=2.0.0,<3.0.0',
'python-dateutil>=2.8.1,<3.0.0',
'requests>=2.25,<3.0',
'semver>=2.13.0,<3.0.0',
'sentry-sdk>=0.19.3,<0.20.0',
'sym-shared-cli>=0.2.3,<0.3.0',
'validators>=0.18.1,<0.19.0']
entry_points = \
{'console_scripts': ['sym = sym.cli.sym:sym']}
setup_kwargs = {
'name': 'sym-cli',
'version': '0.4.11',
'description': "Sym's Official CLI for Users",
'long_description': '# sym-cli\n\nThis is the official CLI for [Sym](https://symops.com/) Users. Check out the docs [here](https://docs.symops.com/docs/install-sym-cli).\n',
'author': 'SymOps, Inc.',
'author_email': 'pypi@symops.io',
'maintainer': None,
'maintainer_email': None,
'url': 'https://symops.com/',
'packages': packages,
'package_data': package_data,
'install_requires': install_requires,
'entry_points': entry_points,
'python_requires': '>=3.8,<4.0',
}
setup(**setup_kwargs)