Skip to content
Open
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
120 changes: 120 additions & 0 deletions javelin_cli/_internal/commands.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import json
import os
import asyncio

from pathlib import Path

from pydantic import ValidationError
Expand Down Expand Up @@ -28,6 +30,7 @@
Secrets,
Template,
Templates,
Customer, AWSConfig, AzureConfig, UsageResponse, AlertResponse,Request,HttpMethod,
)


Expand Down Expand Up @@ -87,6 +90,123 @@ def get_javelin_client():
return JavelinClient(config)


#aispm commands
def create_customer(args):
try:
client = get_javelin_client()
customer = Customer(
name=args.name,
description=args.description,
metrics_interval=args.metrics_interval,
security_interval=args.security_interval
)
response = client._send_request_sync(Request(
method=HttpMethod.POST,
route="v1/admin/aispm/customer",
data=customer.dict()
))
print(f"Customer '{args.name}' created successfully.")
except Exception as e:
print(f"Error creating customer: {e}")

def get_customer(args):
try:
client = get_javelin_client()
route = "v1/admin/aispm/customer"
print(f"Making request to: {client.config.base_url}{route}")
print(f"Headers: {client._headers}") # Access _headers directly

response = client._send_request_sync(Request(
method=HttpMethod.GET,
route=route
))
print(f"Status: {response.status_code}")
print(f"Response: {response.content.decode('utf-8')}")
except Exception as e:
print(f"Error getting customer: {e}")

def configure_aws(args):
try:
client = get_javelin_client()
config = json.loads(args.config)
configs = [AWSConfig(**config)]
result = client.aispm.configure_aws(configs)
print(f"AWS configuration created successfully.")
except Exception as e:
print(f"Error configuring AWS: {e}")

def get_aws_config(args):
try:
client = get_javelin_client()
request = Request(
method=HttpMethod.GET,
route="v1/admin/aispm/config/aws"
)
response = client._send_request_sync(request)
print(json.dumps(response.json(), indent=2))
except Exception as e:
print(f"Error getting AWS config: {e}")

def delete_aws_config(args):
try:
client = get_javelin_client()
request = Request(
method=HttpMethod.DELETE,
route=f"v1/admin/aispm/config/aws/{args.name}"
)
response = client._send_request_sync(request)
print(f"AWS configuration '{args.name}' deleted successfully.")
except Exception as e:
print(f"Error deleting AWS config: {e}")

def get_azure_config(args):
try:
client = get_javelin_client()
request = Request(
method=HttpMethod.GET,
route="v1/admin/aispm/config/azure"
)
response = client._send_request_sync(request)
print(json.dumps(response.json(), indent=2))
except Exception as e:
print(f"Error getting Azure config: {e}")

def configure_azure(args):
try:
client = get_javelin_client()
config = json.loads(args.config)
configs = [AzureConfig(**config)]
result = client.aispm.configure_azure(configs)
print(f"Azure configuration created successfully.")
except Exception as e:
print(f"Error configuring Azure: {e}")

def get_usage(args):
try:
client = get_javelin_client()
usage = client.aispm.get_usage(
provider=args.provider,
cloud_account=args.account,
model=args.model,
region=args.region
)
print(json.dumps(usage.dict(), indent=2))
except Exception as e:
print(f"Error getting usage: {e}")

def get_alerts(args):
try:
client = get_javelin_client()
alerts = client.aispm.get_alerts(
provider=args.provider,
cloud_account=args.account,
model=args.model,
region=args.region
)
print(json.dumps(alerts.dict(), indent=2))
except Exception as e:
print(f"Error getting alerts: {e}")

def create_gateway(args):
try:
client = get_javelin_client()
Expand Down
97 changes: 97 additions & 0 deletions javelin_cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,30 @@
update_route,
update_secret,
update_template,
create_customer,
get_customer,
configure_aws,
configure_azure,
get_usage,
get_alerts,
get_aws_config,
get_azure_config,
delete_aws_config
)



#def check_permissions():
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uncomment this code

# """Check if user has permissions"""
# home_dir = Path.home()
# cache_file = home_dir / ".javelin" / "cache.json"

# if not cache_file.exists():
# print("❌ Not authenticated. Please run 'javelin auth' first.")
# sys.exit(1)

# return True # Skip role check

def check_permissions():
"""Check if user has superadmin permissions"""
home_dir = Path.home()
Expand Down Expand Up @@ -89,6 +110,80 @@ def main():
auth_parser = subparsers.add_parser("auth", help="Authenticate with Javelin.")
auth_parser.add_argument("--force", action="store_true", help="Force re-authentication, overriding existing credentials")
auth_parser.set_defaults(func=authenticate)
#aispm CRUD
# AISPM commands
aispm_parser = subparsers.add_parser("aispm", help="Manage AISPM functionality")
aispm_subparsers = aispm_parser.add_subparsers()

# Customer commands
customer_parser = aispm_subparsers.add_parser("customer", help="Manage customers")
customer_subparsers = customer_parser.add_subparsers()

customer_create = customer_subparsers.add_parser("create", help="Create customer")
customer_create.add_argument("--name", required=True, help="Customer name")
customer_create.add_argument("--description", help="Customer description")
customer_create.add_argument("--metrics-interval", default="5m", help="Metrics interval")
customer_create.add_argument("--security-interval", default="1m", help="Security interval")
customer_create.set_defaults(func=create_customer)

customer_get = customer_subparsers.add_parser("get", help="Get customer details")
customer_get.set_defaults(func=get_customer)


# Cloud config commands
config_parser = aispm_subparsers.add_parser("config", help="Manage cloud configurations")
config_subparsers = config_parser.add_subparsers()

aws_parser = config_subparsers.add_parser("aws", help="Configure AWS")

azure_parser = config_subparsers.add_parser("azure", help="Configure Azure")

#azure_parser.add_argument("--config", type=str, required=True, help="Azure config JSON")
#azure_parser.set_defaults(func=configure_azure)


aws_subparsers = aws_parser.add_subparsers()

# GET AWS Config
aws_get_parser = aws_subparsers.add_parser("get", help="Get AWS configuration")
aws_get_parser.set_defaults(func=get_aws_config)

# Existing AWS Config (for creating)
aws_config_parser = aws_subparsers.add_parser("create", help="Configure AWS")
aws_config_parser.add_argument("--config", type=str, required=True, help="AWS config JSON")
aws_config_parser.set_defaults(func=configure_aws)

aws_delete_parser = aws_subparsers.add_parser("delete", help="Delete AWS configuration")
aws_delete_parser.add_argument("--name", type=str, required=True, help="Name of AWS configuration to delete")
aws_delete_parser.set_defaults(func=delete_aws_config)

azure_subparsers = azure_parser.add_subparsers(dest='azure_command')

# Get Azure Config
azure_get_parser = azure_subparsers.add_parser("get", help="Get Azure configuration")
azure_get_parser.set_defaults(func=get_azure_config)

# Create Azure Config
azure_create_parser = azure_subparsers.add_parser("create", help="Configure Azure")
azure_create_parser.add_argument("--config", type=str, required=True, help="Azure config JSON")
azure_create_parser.set_defaults(func=configure_azure)


# Usage metrics
usage_parser = aispm_subparsers.add_parser("usage", help="Get usage metrics")
usage_parser.add_argument("--provider", help="Cloud provider")
usage_parser.add_argument("--account", help="Cloud account name")
usage_parser.add_argument("--model", help="Model ID")
usage_parser.add_argument("--region", help="Region")
usage_parser.set_defaults(func=get_usage)

# Alerts
alerts_parser = aispm_subparsers.add_parser("alerts", help="Get alerts")
alerts_parser.add_argument("--provider", help="Cloud provider")
alerts_parser.add_argument("--account", help="Cloud account name")
alerts_parser.add_argument("--model", help="Model ID")
alerts_parser.add_argument("--region", help="Region")
alerts_parser.set_defaults(func=get_alerts)
# Gateway CRUD
gateway_parser = subparsers.add_parser(
"gateway",
Expand Down Expand Up @@ -373,6 +468,8 @@ def main():
)
template_delete.set_defaults(func=delete_template)



args = parser.parse_args()

if hasattr(args, "func"):
Expand Down
59 changes: 45 additions & 14 deletions javelin_sdk/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
from javelin_sdk.services.secret_service import SecretService
from javelin_sdk.services.template_service import TemplateService
from javelin_sdk.services.trace_service import TraceService
from javelin_sdk.services.aispm_service import AISPMService


API_BASEURL = "https://api-dev.javelin.live"
API_BASE_PATH = "/v1"
Expand Down Expand Up @@ -45,6 +47,9 @@
self.chat = Chat(self)
self.completions = Completions(self)

self.aispm = AISPMService(self)


@property
def client(self):
if self._client is None:
Expand Down Expand Up @@ -84,24 +89,41 @@
self._client.close()

def _prepare_request(self, request: Request) -> tuple:
url = self._construct_url(
gateway_name=request.gateway,
provider_name=request.provider,
route_name=request.route,
secret_name=request.secret,
template_name=request.template,
trace=request.trace,
query=request.is_query,
archive=request.archive,
query_params=request.query_params,
is_transformation_rules=request.is_transformation_rules,
is_reload=request.is_reload,
)
if request.route.startswith("v1/admin/aispm"):
url = f"{self.config.base_url.rstrip('/')}/{request.route}"
if request.query_params:
query_string = "&".join(f"{k}={v}" for k, v in request.query_params.items())
url += f"?{query_string}"


else:
url = self._construct_url(
gateway_name=request.gateway,
provider_name=request.provider,
route_name=request.route,
secret_name=request.secret,
template_name=request.template,
trace=request.trace,
query=request.is_query,
archive=request.archive,
query_params=request.query_params,
is_transformation_rules=request.is_transformation_rules,
is_reload=request.is_reload,
)

headers = {**self._headers, **(request.headers or {})}
return url, headers

def _send_request_sync(self, request: Request) -> httpx.Response:
return self._core_send_request(self.client, request)
url, headers = self._prepare_request(request)
print(f"Making request to: {url}")

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This expression logs
sensitive data (secret)
as clear text.
This expression logs
sensitive data (secret)
as clear text.
This expression logs
sensitive data (secret)
as clear text.
This expression logs
sensitive data (secret)
as clear text.
This expression logs
sensitive data (secret)
as clear text.
print(f"With headers: {headers}")

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This expression logs
sensitive data (secret)
as clear text.
This expression logs
sensitive data (secret)
as clear text.
This expression logs
sensitive data (secret)
as clear text.
This expression logs
sensitive data (secret)
as clear text.
This expression logs
sensitive data (secret)
as clear text.
response = self._core_send_request(self.client, request)
print(f"Response status: {response.status_code}")
print(f"Response body: {response.text}")
return response



async def _send_request_async(self, request: Request) -> httpx.Response:
return await self._core_send_request(self.aclient, request)
Expand Down Expand Up @@ -199,6 +221,15 @@

return url

def _construct_aispm_url(self, request: Request) -> str:
url = request.route

if request.query_params:
query_string = "&".join(f"{k}={v}" for k, v in request.query_params.items())
url += f"?{query_string}"

return url

# Gateway methods
create_gateway = lambda self, gateway: self.gateway_service.create_gateway(gateway)
acreate_gateway = lambda self, gateway: self.gateway_service.acreate_gateway(
Expand Down
Loading
Loading