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

Add Org level API key #93

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ The SDK can be configured using environment variables:

- `CORALOGIX_TEAM_API_KEY`: The API key that is used for all team-level interactions. Note that it has to have appropriate permissions. Read the [docs](https://coralogix.com/docs/api-keys/) for more information.
- `CORALOGIX_USER_API_KEY`: The API key that is used for all user-level interactions. Note that it has to have appropriate permissions. Read the [docs](https://coralogix.com/docs/api-keys/) for more information.
- `CORALOGIX_ORG_API_KEY`: The API key that is used for all organization-level interactions.
- `CORALGOIX_REGION`: The region/cluster to connect to as a shorthand (EU2, AP1, etc. read more [here](https://coralogix.com/docs/coralogix-domain/)).

Furthermore, if you want to run the examples locally, you're going to to have set the following environment variables:
Expand Down
18 changes: 18 additions & 0 deletions go/callPropertiesCreator.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ type CallPropertiesCreator struct {
coraglogixRegion string
teamsLevelAPIKey string
userLevelAPIKey string
orgLevelAPIKey string
correlationID string
sdkVersion string
//allowRetry bool
Expand Down Expand Up @@ -75,6 +76,21 @@ func (c CallPropertiesCreator) GetUserLevelCallProperties(ctx context.Context) (
return &CallProperties{Ctx: ctx, Connection: conn, CallOptions: callOptions}, nil
}

// GetOrgLevelCallProperties returns a new CallProperties object built from an organization-level API key. It essentially prepares the context, connection, and call options for a gRPC call.
func (c CallPropertiesCreator) GetOrgLevelCallProperties(ctx context.Context) (*CallProperties, error) {
ctx = createContext(ctx, c.orgLevelAPIKey, c.correlationID, c.sdkVersion)

endpoint := CoralogixGrpcEndpointFromRegion(c.coraglogixRegion)
conn, err := createSecureConnection(endpoint)
if err != nil {
return nil, err
}

callOptions := createCallOptions()

return &CallProperties{Ctx: ctx, Connection: conn, CallOptions: callOptions}, nil
}

func createCallOptions() []grpc.CallOption {
var callOptions []grpc.CallOption
callOptions = append(callOptions, grpc_retry.WithMax(5))
Expand All @@ -99,6 +115,7 @@ func NewCallPropertiesCreator(region string, authContext AuthContext) *CallPrope
coraglogixRegion: region,
teamsLevelAPIKey: authContext.teamLevelAPIKey,
userLevelAPIKey: authContext.userLevelAPIKey,
orgLevelAPIKey: authContext.orgLevelAPIKey,
correlationID: uuid.New().String(),
sdkVersion: vanillaSdkVersion,
}
Expand All @@ -109,6 +126,7 @@ func NewCallPropertiesCreatorTerraformOperator(region string, authContext AuthCo
return &CallPropertiesCreator{
coraglogixRegion: region,
teamsLevelAPIKey: authContext.teamLevelAPIKey,
orgLevelAPIKey: authContext.orgLevelAPIKey,
userLevelAPIKey: authContext.userLevelAPIKey,
correlationID: uuid.New().String(),
sdkVersion: terraformOperatorVersion,
Expand Down
47 changes: 19 additions & 28 deletions go/cxsdk.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,8 @@ func (c *ClientSet) DataUsage() *DataUsageClient {
}

// NewClientSet Creates a new ClientSet.
func NewClientSet(targetURL, teamsLevelAPIKey string, userLevelAPIKey string) *ClientSet {
authContext := NewAuthContext(teamsLevelAPIKey, userLevelAPIKey)
func NewClientSet(targetURL, teamsLevelAPIKey, userLevelAPIKey, orgLevelAPIKey string) *ClientSet {
authContext := NewAuthContext(teamsLevelAPIKey, userLevelAPIKey, orgLevelAPIKey)
apikeyCPC := NewCallPropertiesCreator(targetURL, authContext)

return &ClientSet{
Expand Down Expand Up @@ -196,6 +196,9 @@ const EnvCoralogixTeamLevelAPIKey = "CORALOGIX_TEAM_API_KEY"
// EnvCoralogixUserLevelAPIKey is the name of the environment variable that contains the Coralogix User API key.
const EnvCoralogixUserLevelAPIKey = "CORALOGIX_USER_API_KEY"

// EnvCoralogixOrgLevelAPIKey is the name of the environment variable that contains the Coralogix Organization API key.
const EnvCoralogixOrgLevelAPIKey = "CORALOGIX_ORG_API_KEY"

// CoralogixRegionFromEnv reads the Coralogix region from environment variables.
func CoralogixRegionFromEnv() (string, error) {
regionIdentifier := strings.ToLower(os.Getenv(EnvCoralogxRegion))
Expand Down Expand Up @@ -271,56 +274,44 @@ const (
type AuthContext struct {
teamLevelAPIKey string
userLevelAPIKey string
orgLevelAPIKey string
}

// NewAuthContext creates a new AuthContext.
func NewAuthContext(teamLevelAPIKey, userLevelAPIKey string) AuthContext {
func NewAuthContext(teamLevelAPIKey, userLevelAPIKey, orgLevelAPIKey string) AuthContext {
if teamLevelAPIKey == "" {
log.Println("Warning: teamLevelAPIKey was not provided. Some functionality will not be available.")
}
if userLevelAPIKey == "" {
log.Println("Warning: userLevelAPIKey was not provided. Some functionality will not be available.")
}
if orgLevelAPIKey == "" {
log.Println("Warning: orgLevelAPIKey was not provided. Some functionality will not be available.")
}
return AuthContext{
teamLevelAPIKey: teamLevelAPIKey,
userLevelAPIKey: userLevelAPIKey,
orgLevelAPIKey: orgLevelAPIKey,
}
}

// AuthContextFromEnv reads the Coralogix API keys from environment variables.
func AuthContextFromEnv() (AuthContext, error) {
teamLevelAPIKey, err := CoralogixTeamsLevelAPIKeyFromEnv()
if err != nil {
return AuthContext{}, err
}
userLevelAPIKey, err := CoralogixUserLevelAPIKeyFromEnv()
if err != nil {
return AuthContext{}, err
teamLevelAPIKey := os.Getenv(EnvCoralogixTeamLevelAPIKey)
userLevelAPIKey := os.Getenv(EnvCoralogixUserLevelAPIKey)
orgLevelAPIKey := os.Getenv(EnvCoralogixOrgLevelAPIKey)
if teamLevelAPIKey == "" && userLevelAPIKey == "" && orgLevelAPIKey == "" {
return AuthContext{}, fmt.Errorf("at least one of %s, %s, or %s must be set", EnvCoralogixTeamLevelAPIKey, EnvCoralogixUserLevelAPIKey, EnvCoralogixOrgLevelAPIKey)
}
if teamLevelAPIKey == "" {
log.Println("Warning: teamLevelAPIKey is empty. Some functionality will not be available.")
}
if userLevelAPIKey == "" {
log.Println("Warning: userLevelAPIKey is empty. Some functionality will not be available.")
}

return AuthContext{teamLevelAPIKey: teamLevelAPIKey, userLevelAPIKey: userLevelAPIKey}, nil
}

// CoralogixTeamsLevelAPIKeyFromEnv reads the Coralogix Team API key from environment variables.
func CoralogixTeamsLevelAPIKeyFromEnv() (string, error) {
apiKey := os.Getenv(EnvCoralogixTeamLevelAPIKey)
if apiKey == "" {
return "", fmt.Errorf("the %s environment variable is not set", EnvCoralogixTeamLevelAPIKey)
if orgLevelAPIKey == "" {
log.Println("Warning: orgLevelAPIKey is empty. Some functionality will not be available.")
}
return apiKey, nil
}

// CoralogixUserLevelAPIKeyFromEnv reads the Coralogix User API key from environment variables.
func CoralogixUserLevelAPIKeyFromEnv() (string, error) {
apiKey := os.Getenv(EnvCoralogixUserLevelAPIKey)
if apiKey == "" {
return "", fmt.Errorf("the %s environment variable is not set", EnvCoralogixUserLevelAPIKey)
}
return apiKey, nil
return AuthContext{teamLevelAPIKey: teamLevelAPIKey, userLevelAPIKey: userLevelAPIKey, orgLevelAPIKey: orgLevelAPIKey}, nil
}
26 changes: 19 additions & 7 deletions go/teams-client.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,27 @@ import (
// CreateTeamInOrgRequest is a request to create a team.
type CreateTeamInOrgRequest = teams.CreateTeamInOrgRequest

// CreateTeamInOrgResponse is a response to creating a team.
type CreateTeamInOrgResponse = teams.CreateTeamInOrgResponse

// UpdateTeamRequest is a request to update a team.
type UpdateTeamRequest = teams.UpdateTeamRequest

// UpdateTeamResponse is a response to updating a team.
type UpdateTeamResponse = teams.UpdateTeamResponse

// GetTeamRequest is a request to get a team.
type GetTeamRequest = teams.GetTeamRequest

// GetTeamResponse is a response to getting a team.
type GetTeamResponse = teams.GetTeamResponse

// DeleteTeamRequest is a request to delete a team.
type DeleteTeamRequest = teams.DeleteTeamRequest

// DeleteTeamResponse is a response to deleting a team.
type DeleteTeamResponse = teams.DeleteTeamResponse

// SetDailyQuotaRequest is a request to set the daily quota for a team.
type SetDailyQuotaRequest = teams.SetDailyQuotaRequest

Expand Down Expand Up @@ -63,7 +75,7 @@ type TeamsClient struct {

// Create creates a new team.
func (c TeamsClient) Create(ctx context.Context, req *CreateTeamInOrgRequest) (*teams.CreateTeamInOrgResponse, error) {
callProperties, err := c.callPropertiesCreator.GetTeamsLevelCallProperties(ctx)
callProperties, err := c.callPropertiesCreator.GetOrgLevelCallProperties(ctx)
if err != nil {
return nil, err
}
Expand All @@ -77,7 +89,7 @@ func (c TeamsClient) Create(ctx context.Context, req *CreateTeamInOrgRequest) (*

// Update updates a team.
func (c TeamsClient) Update(ctx context.Context, req *UpdateTeamRequest) (*teams.UpdateTeamResponse, error) {
callProperties, err := c.callPropertiesCreator.GetTeamsLevelCallProperties(ctx)
callProperties, err := c.callPropertiesCreator.GetOrgLevelCallProperties(ctx)
if err != nil {
return nil, err
}
Expand All @@ -91,7 +103,7 @@ func (c TeamsClient) Update(ctx context.Context, req *UpdateTeamRequest) (*teams

// Get gets a team.
func (c TeamsClient) Get(ctx context.Context, req *GetTeamRequest) (*teams.GetTeamResponse, error) {
callProperties, err := c.callPropertiesCreator.GetTeamsLevelCallProperties(ctx)
callProperties, err := c.callPropertiesCreator.GetOrgLevelCallProperties(ctx)
if err != nil {
return nil, err
}
Expand All @@ -105,7 +117,7 @@ func (c TeamsClient) Get(ctx context.Context, req *GetTeamRequest) (*teams.GetTe

// Delete deletes a team.
func (c TeamsClient) Delete(ctx context.Context, req *DeleteTeamRequest) (*teams.DeleteTeamResponse, error) {
callProperties, err := c.callPropertiesCreator.GetTeamsLevelCallProperties(ctx)
callProperties, err := c.callPropertiesCreator.GetOrgLevelCallProperties(ctx)
if err != nil {
return nil, err
}
Expand All @@ -119,7 +131,7 @@ func (c TeamsClient) Delete(ctx context.Context, req *DeleteTeamRequest) (*teams

// SetDailyQuota sets the daily quota for a team.
func (c TeamsClient) SetDailyQuota(ctx context.Context, req *SetDailyQuotaRequest) (*teams.SetDailyQuotaResponse, error) {
callProperties, err := c.callPropertiesCreator.GetTeamsLevelCallProperties(ctx)
callProperties, err := c.callPropertiesCreator.GetOrgLevelCallProperties(ctx)
if err != nil {
return nil, err
}
Expand All @@ -133,7 +145,7 @@ func (c TeamsClient) SetDailyQuota(ctx context.Context, req *SetDailyQuotaReques

// GetQuota gets the quota for a team.
func (c TeamsClient) GetQuota(ctx context.Context, req *GetTeamQuotaRequest) (*teams.GetTeamQuotaResponse, error) {
callProperties, err := c.callPropertiesCreator.GetTeamsLevelCallProperties(ctx)
callProperties, err := c.callPropertiesCreator.GetOrgLevelCallProperties(ctx)
if err != nil {
return nil, err
}
Expand All @@ -147,7 +159,7 @@ func (c TeamsClient) GetQuota(ctx context.Context, req *GetTeamQuotaRequest) (*t

// MoveQuota moves the quota from one team to another.
func (c TeamsClient) MoveQuota(ctx context.Context, req *MoveQuotaRequest) (*teams.MoveQuotaResponse, error) {
callProperties, err := c.callPropertiesCreator.GetTeamsLevelCallProperties(ctx)
callProperties, err := c.callPropertiesCreator.GetOrgLevelCallProperties(ctx)
if err != nil {
return nil, err
}
Expand Down
24 changes: 23 additions & 1 deletion rust/cx-sdk/src/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use std::fmt::{

const ENV_TEAM_API_KEY: &str = "CORALOGIX_TEAM_API_KEY";
const ENV_USER_API_KEY: &str = "CORALOGIX_USER_API_KEY";
const ENV_ORG_API_KEY: &str = "CORALOGIX_ORG_API_KEY";

#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Default)]
/// The authentication context.
Expand All @@ -28,6 +29,8 @@ pub struct AuthContext {
pub(crate) team_level_api_key: ApiKey,
/// The user level API key.
pub(crate) user_level_api_key: ApiKey,
/// The organization level API key.
pub(crate) org_level_api_key: ApiKey,
}

impl AuthContext {
Expand All @@ -36,16 +39,27 @@ impl AuthContext {
/// # Arguments
/// * `team_level_api_key` - The team level API key.
/// * `user_level_api_key` - The user level API key.
pub fn new(team_level_api_key: Option<ApiKey>, user_level_api_key: Option<ApiKey>) -> Self {
/// * `org_level_api_key` - The organization level API key.
pub fn new(
team_level_api_key: Option<ApiKey>,
user_level_api_key: Option<ApiKey>,
org_level_api_key: Option<ApiKey>,
) -> Self {
if team_level_api_key.is_none() {
log::warn!("Team level API key is not set. some functionality may not be available.");
}
if user_level_api_key.is_none() {
log::warn!("User level API key is not set. some functionality may not be available.");
}
if org_level_api_key.is_none() {
log::warn!(
"Organization level API key is not set. some functionality may not be available."
);
}
AuthContext {
team_level_api_key: team_level_api_key.unwrap_or_default(),
user_level_api_key: user_level_api_key.unwrap_or_default(),
org_level_api_key: org_level_api_key.unwrap_or_default(),
}
}

Expand All @@ -54,6 +68,7 @@ impl AuthContext {
AuthContext::new(
ApiKey::teams_level_from_env().ok(),
ApiKey::user_level_from_env().ok(),
ApiKey::org_level_from_env().ok(),
)
}
}
Expand Down Expand Up @@ -81,6 +96,13 @@ impl ApiKey {
.map(ApiKey)
.map_err(From::from)
}

/// Creates a new organization-level API key from the ENV_API_KEY environment variable.
pub fn org_level_from_env() -> Result<Self> {
std::env::var(ENV_ORG_API_KEY)
.map(ApiKey)
.map_err(From::from)
}
}

impl From<&str> for ApiKey {
Expand Down
2 changes: 1 addition & 1 deletion rust/cx-sdk/src/client/teams.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ impl TeamsClient {
let channel: Channel = Endpoint::from_str(region.grpc_endpoint().as_str())?
.tls_config(ClientTlsConfig::new().with_native_roots())?
.connect_lazy();
let request_metadata: CallProperties = (&auth_context.team_level_api_key).into();
let request_metadata: CallProperties = (&auth_context.org_level_api_key).into();
Ok(Self {
metadata_map: request_metadata.to_metadata_map(),
service_client: Mutex::new(TeamServiceClient::new(channel)),
Expand Down
Loading