mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-30 22:26:42 +00:00
[misc] Add missing OpenAPI definitions (#5690)
This commit is contained in:
112
shared/management/client/rest/azure_idp.go
Normal file
112
shared/management/client/rest/azure_idp.go
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
package rest
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/netbirdio/netbird/shared/management/http/api"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AzureIDPAPI APIs for Azure AD IDP integrations
|
||||||
|
type AzureIDPAPI struct {
|
||||||
|
c *Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// List retrieves all Azure AD IDP integrations
|
||||||
|
func (a *AzureIDPAPI) List(ctx context.Context) ([]api.AzureIntegration, error) {
|
||||||
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/integrations/azure-idp", nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if resp.Body != nil {
|
||||||
|
defer resp.Body.Close()
|
||||||
|
}
|
||||||
|
ret, err := parseResponse[[]api.AzureIntegration](resp)
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get retrieves a specific Azure AD IDP integration by ID
|
||||||
|
func (a *AzureIDPAPI) Get(ctx context.Context, integrationID string) (*api.AzureIntegration, error) {
|
||||||
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/integrations/azure-idp/"+integrationID, nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if resp.Body != nil {
|
||||||
|
defer resp.Body.Close()
|
||||||
|
}
|
||||||
|
ret, err := parseResponse[api.AzureIntegration](resp)
|
||||||
|
return &ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create creates a new Azure AD IDP integration
|
||||||
|
func (a *AzureIDPAPI) Create(ctx context.Context, request api.CreateAzureIntegrationRequest) (*api.AzureIntegration, error) {
|
||||||
|
requestBytes, err := json.Marshal(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
resp, err := a.c.NewRequest(ctx, "POST", "/api/integrations/azure-idp", bytes.NewReader(requestBytes), nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if resp.Body != nil {
|
||||||
|
defer resp.Body.Close()
|
||||||
|
}
|
||||||
|
ret, err := parseResponse[api.AzureIntegration](resp)
|
||||||
|
return &ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update updates an existing Azure AD IDP integration
|
||||||
|
func (a *AzureIDPAPI) Update(ctx context.Context, integrationID string, request api.UpdateAzureIntegrationRequest) (*api.AzureIntegration, error) {
|
||||||
|
requestBytes, err := json.Marshal(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
resp, err := a.c.NewRequest(ctx, "PUT", "/api/integrations/azure-idp/"+integrationID, bytes.NewReader(requestBytes), nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if resp.Body != nil {
|
||||||
|
defer resp.Body.Close()
|
||||||
|
}
|
||||||
|
ret, err := parseResponse[api.AzureIntegration](resp)
|
||||||
|
return &ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete deletes an Azure AD IDP integration
|
||||||
|
func (a *AzureIDPAPI) Delete(ctx context.Context, integrationID string) error {
|
||||||
|
resp, err := a.c.NewRequest(ctx, "DELETE", "/api/integrations/azure-idp/"+integrationID, nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if resp.Body != nil {
|
||||||
|
defer resp.Body.Close()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sync triggers a manual sync for an Azure AD IDP integration
|
||||||
|
func (a *AzureIDPAPI) Sync(ctx context.Context, integrationID string) (*api.SyncResult, error) {
|
||||||
|
resp, err := a.c.NewRequest(ctx, "POST", "/api/integrations/azure-idp/"+integrationID+"/sync", nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if resp.Body != nil {
|
||||||
|
defer resp.Body.Close()
|
||||||
|
}
|
||||||
|
ret, err := parseResponse[api.SyncResult](resp)
|
||||||
|
return &ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetLogs retrieves synchronization logs for an Azure AD IDP integration
|
||||||
|
func (a *AzureIDPAPI) GetLogs(ctx context.Context, integrationID string) ([]api.IdpIntegrationSyncLog, error) {
|
||||||
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/integrations/azure-idp/"+integrationID+"/logs", nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if resp.Body != nil {
|
||||||
|
defer resp.Body.Close()
|
||||||
|
}
|
||||||
|
ret, err := parseResponse[[]api.IdpIntegrationSyncLog](resp)
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
252
shared/management/client/rest/azure_idp_test.go
Normal file
252
shared/management/client/rest/azure_idp_test.go
Normal file
@@ -0,0 +1,252 @@
|
|||||||
|
//go:build integration
|
||||||
|
|
||||||
|
package rest_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/netbirdio/netbird/shared/management/client/rest"
|
||||||
|
"github.com/netbirdio/netbird/shared/management/http/api"
|
||||||
|
"github.com/netbirdio/netbird/shared/management/http/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
var testAzureIntegration = api.AzureIntegration{
|
||||||
|
Id: 1,
|
||||||
|
Enabled: true,
|
||||||
|
ClientId: "12345678-1234-1234-1234-123456789012",
|
||||||
|
TenantId: "87654321-4321-4321-4321-210987654321",
|
||||||
|
SyncInterval: 300,
|
||||||
|
GroupPrefixes: []string{"eng-"},
|
||||||
|
UserGroupPrefixes: []string{"dev-"},
|
||||||
|
Host: "microsoft.com",
|
||||||
|
LastSyncedAt: time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAzureIDP_List_200(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/azure-idp", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
assert.Equal(t, "GET", r.Method)
|
||||||
|
retBytes, _ := json.Marshal([]api.AzureIntegration{testAzureIntegration})
|
||||||
|
_, err := w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.AzureIDP.List(context.Background())
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Len(t, ret, 1)
|
||||||
|
assert.Equal(t, testAzureIntegration, ret[0])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAzureIDP_List_Err(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/azure-idp", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||||
|
w.WriteHeader(400)
|
||||||
|
_, err := w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.AzureIDP.List(context.Background())
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "No", err.Error())
|
||||||
|
assert.Empty(t, ret)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAzureIDP_Get_200(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/azure-idp/int-1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
assert.Equal(t, "GET", r.Method)
|
||||||
|
retBytes, _ := json.Marshal(testAzureIntegration)
|
||||||
|
_, err := w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.AzureIDP.Get(context.Background(), "int-1")
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, testAzureIntegration, *ret)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAzureIDP_Get_Err(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/azure-idp/int-1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "Not found", Code: 404})
|
||||||
|
w.WriteHeader(404)
|
||||||
|
_, err := w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.AzureIDP.Get(context.Background(), "int-1")
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "Not found", err.Error())
|
||||||
|
assert.Nil(t, ret)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAzureIDP_Create_200(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/azure-idp", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
assert.Equal(t, "POST", r.Method)
|
||||||
|
reqBytes, err := io.ReadAll(r.Body)
|
||||||
|
require.NoError(t, err)
|
||||||
|
var req api.CreateAzureIntegrationRequest
|
||||||
|
err = json.Unmarshal(reqBytes, &req)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, "12345678-1234-1234-1234-123456789012", req.ClientId)
|
||||||
|
retBytes, _ := json.Marshal(testAzureIntegration)
|
||||||
|
_, err = w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.AzureIDP.Create(context.Background(), api.CreateAzureIntegrationRequest{
|
||||||
|
ClientId: "12345678-1234-1234-1234-123456789012",
|
||||||
|
ClientSecret: "secret",
|
||||||
|
TenantId: "87654321-4321-4321-4321-210987654321",
|
||||||
|
Host: api.CreateAzureIntegrationRequestHostMicrosoftCom,
|
||||||
|
GroupPrefixes: &[]string{"eng-"},
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, testAzureIntegration, *ret)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAzureIDP_Create_Err(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/azure-idp", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||||
|
w.WriteHeader(400)
|
||||||
|
_, err := w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.AzureIDP.Create(context.Background(), api.CreateAzureIntegrationRequest{})
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "No", err.Error())
|
||||||
|
assert.Nil(t, ret)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAzureIDP_Update_200(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/azure-idp/int-1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
assert.Equal(t, "PUT", r.Method)
|
||||||
|
reqBytes, err := io.ReadAll(r.Body)
|
||||||
|
require.NoError(t, err)
|
||||||
|
var req api.UpdateAzureIntegrationRequest
|
||||||
|
err = json.Unmarshal(reqBytes, &req)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, true, *req.Enabled)
|
||||||
|
retBytes, _ := json.Marshal(testAzureIntegration)
|
||||||
|
_, err = w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.AzureIDP.Update(context.Background(), "int-1", api.UpdateAzureIntegrationRequest{
|
||||||
|
Enabled: ptr(true),
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, testAzureIntegration, *ret)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAzureIDP_Update_Err(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/azure-idp/int-1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||||
|
w.WriteHeader(400)
|
||||||
|
_, err := w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.AzureIDP.Update(context.Background(), "int-1", api.UpdateAzureIntegrationRequest{})
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "No", err.Error())
|
||||||
|
assert.Nil(t, ret)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAzureIDP_Delete_200(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/azure-idp/int-1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
assert.Equal(t, "DELETE", r.Method)
|
||||||
|
w.WriteHeader(200)
|
||||||
|
})
|
||||||
|
err := c.AzureIDP.Delete(context.Background(), "int-1")
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAzureIDP_Delete_Err(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/azure-idp/int-1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "Not found", Code: 404})
|
||||||
|
w.WriteHeader(404)
|
||||||
|
_, err := w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
err := c.AzureIDP.Delete(context.Background(), "int-1")
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "Not found", err.Error())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAzureIDP_Sync_200(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/azure-idp/int-1/sync", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
assert.Equal(t, "POST", r.Method)
|
||||||
|
retBytes, _ := json.Marshal(api.SyncResult{Result: ptr("ok")})
|
||||||
|
_, err := w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.AzureIDP.Sync(context.Background(), "int-1")
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, "ok", *ret.Result)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAzureIDP_Sync_Err(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/azure-idp/int-1/sync", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "Not found", Code: 404})
|
||||||
|
w.WriteHeader(404)
|
||||||
|
_, err := w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.AzureIDP.Sync(context.Background(), "int-1")
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "Not found", err.Error())
|
||||||
|
assert.Nil(t, ret)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAzureIDP_GetLogs_200(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/azure-idp/int-1/logs", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
assert.Equal(t, "GET", r.Method)
|
||||||
|
retBytes, _ := json.Marshal([]api.IdpIntegrationSyncLog{testSyncLog})
|
||||||
|
_, err := w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.AzureIDP.GetLogs(context.Background(), "int-1")
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Len(t, ret, 1)
|
||||||
|
assert.Equal(t, testSyncLog, ret[0])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAzureIDP_GetLogs_Err(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/azure-idp/int-1/logs", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "Not found", Code: 404})
|
||||||
|
w.WriteHeader(404)
|
||||||
|
_, err := w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.AzureIDP.GetLogs(context.Background(), "int-1")
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "Not found", err.Error())
|
||||||
|
assert.Empty(t, ret)
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -110,6 +110,15 @@ type Client struct {
|
|||||||
// see more: https://docs.netbird.io/api/resources/scim
|
// see more: https://docs.netbird.io/api/resources/scim
|
||||||
SCIM *SCIMAPI
|
SCIM *SCIMAPI
|
||||||
|
|
||||||
|
// GoogleIDP NetBird Google Workspace IDP integration APIs
|
||||||
|
GoogleIDP *GoogleIDPAPI
|
||||||
|
|
||||||
|
// AzureIDP NetBird Azure AD IDP integration APIs
|
||||||
|
AzureIDP *AzureIDPAPI
|
||||||
|
|
||||||
|
// OktaScimIDP NetBird Okta SCIM IDP integration APIs
|
||||||
|
OktaScimIDP *OktaScimIDPAPI
|
||||||
|
|
||||||
// EventStreaming NetBird Event Streaming integration APIs
|
// EventStreaming NetBird Event Streaming integration APIs
|
||||||
// see more: https://docs.netbird.io/api/resources/event-streaming
|
// see more: https://docs.netbird.io/api/resources/event-streaming
|
||||||
EventStreaming *EventStreamingAPI
|
EventStreaming *EventStreamingAPI
|
||||||
@@ -185,6 +194,9 @@ func (c *Client) initialize() {
|
|||||||
c.MSP = &MSPAPI{c}
|
c.MSP = &MSPAPI{c}
|
||||||
c.EDR = &EDRAPI{c}
|
c.EDR = &EDRAPI{c}
|
||||||
c.SCIM = &SCIMAPI{c}
|
c.SCIM = &SCIMAPI{c}
|
||||||
|
c.GoogleIDP = &GoogleIDPAPI{c}
|
||||||
|
c.AzureIDP = &AzureIDPAPI{c}
|
||||||
|
c.OktaScimIDP = &OktaScimIDPAPI{c}
|
||||||
c.EventStreaming = &EventStreamingAPI{c}
|
c.EventStreaming = &EventStreamingAPI{c}
|
||||||
c.IdentityProviders = &IdentityProvidersAPI{c}
|
c.IdentityProviders = &IdentityProvidersAPI{c}
|
||||||
c.Ingress = &IngressAPI{c}
|
c.Ingress = &IngressAPI{c}
|
||||||
|
|||||||
112
shared/management/client/rest/google_idp.go
Normal file
112
shared/management/client/rest/google_idp.go
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
package rest
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/netbirdio/netbird/shared/management/http/api"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GoogleIDPAPI APIs for Google Workspace IDP integrations
|
||||||
|
type GoogleIDPAPI struct {
|
||||||
|
c *Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// List retrieves all Google Workspace IDP integrations
|
||||||
|
func (a *GoogleIDPAPI) List(ctx context.Context) ([]api.GoogleIntegration, error) {
|
||||||
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/integrations/google-idp", nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if resp.Body != nil {
|
||||||
|
defer resp.Body.Close()
|
||||||
|
}
|
||||||
|
ret, err := parseResponse[[]api.GoogleIntegration](resp)
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get retrieves a specific Google Workspace IDP integration by ID
|
||||||
|
func (a *GoogleIDPAPI) Get(ctx context.Context, integrationID string) (*api.GoogleIntegration, error) {
|
||||||
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/integrations/google-idp/"+integrationID, nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if resp.Body != nil {
|
||||||
|
defer resp.Body.Close()
|
||||||
|
}
|
||||||
|
ret, err := parseResponse[api.GoogleIntegration](resp)
|
||||||
|
return &ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create creates a new Google Workspace IDP integration
|
||||||
|
func (a *GoogleIDPAPI) Create(ctx context.Context, request api.CreateGoogleIntegrationRequest) (*api.GoogleIntegration, error) {
|
||||||
|
requestBytes, err := json.Marshal(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
resp, err := a.c.NewRequest(ctx, "POST", "/api/integrations/google-idp", bytes.NewReader(requestBytes), nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if resp.Body != nil {
|
||||||
|
defer resp.Body.Close()
|
||||||
|
}
|
||||||
|
ret, err := parseResponse[api.GoogleIntegration](resp)
|
||||||
|
return &ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update updates an existing Google Workspace IDP integration
|
||||||
|
func (a *GoogleIDPAPI) Update(ctx context.Context, integrationID string, request api.UpdateGoogleIntegrationRequest) (*api.GoogleIntegration, error) {
|
||||||
|
requestBytes, err := json.Marshal(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
resp, err := a.c.NewRequest(ctx, "PUT", "/api/integrations/google-idp/"+integrationID, bytes.NewReader(requestBytes), nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if resp.Body != nil {
|
||||||
|
defer resp.Body.Close()
|
||||||
|
}
|
||||||
|
ret, err := parseResponse[api.GoogleIntegration](resp)
|
||||||
|
return &ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete deletes a Google Workspace IDP integration
|
||||||
|
func (a *GoogleIDPAPI) Delete(ctx context.Context, integrationID string) error {
|
||||||
|
resp, err := a.c.NewRequest(ctx, "DELETE", "/api/integrations/google-idp/"+integrationID, nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if resp.Body != nil {
|
||||||
|
defer resp.Body.Close()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sync triggers a manual sync for a Google Workspace IDP integration
|
||||||
|
func (a *GoogleIDPAPI) Sync(ctx context.Context, integrationID string) (*api.SyncResult, error) {
|
||||||
|
resp, err := a.c.NewRequest(ctx, "POST", "/api/integrations/google-idp/"+integrationID+"/sync", nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if resp.Body != nil {
|
||||||
|
defer resp.Body.Close()
|
||||||
|
}
|
||||||
|
ret, err := parseResponse[api.SyncResult](resp)
|
||||||
|
return &ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetLogs retrieves synchronization logs for a Google Workspace IDP integration
|
||||||
|
func (a *GoogleIDPAPI) GetLogs(ctx context.Context, integrationID string) ([]api.IdpIntegrationSyncLog, error) {
|
||||||
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/integrations/google-idp/"+integrationID+"/logs", nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if resp.Body != nil {
|
||||||
|
defer resp.Body.Close()
|
||||||
|
}
|
||||||
|
ret, err := parseResponse[[]api.IdpIntegrationSyncLog](resp)
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
248
shared/management/client/rest/google_idp_test.go
Normal file
248
shared/management/client/rest/google_idp_test.go
Normal file
@@ -0,0 +1,248 @@
|
|||||||
|
//go:build integration
|
||||||
|
|
||||||
|
package rest_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/netbirdio/netbird/shared/management/client/rest"
|
||||||
|
"github.com/netbirdio/netbird/shared/management/http/api"
|
||||||
|
"github.com/netbirdio/netbird/shared/management/http/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
var testGoogleIntegration = api.GoogleIntegration{
|
||||||
|
Id: 1,
|
||||||
|
Enabled: true,
|
||||||
|
CustomerId: "C01234567",
|
||||||
|
SyncInterval: 300,
|
||||||
|
GroupPrefixes: []string{"eng-"},
|
||||||
|
UserGroupPrefixes: []string{"dev-"},
|
||||||
|
LastSyncedAt: time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGoogleIDP_List_200(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/google-idp", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
assert.Equal(t, "GET", r.Method)
|
||||||
|
retBytes, _ := json.Marshal([]api.GoogleIntegration{testGoogleIntegration})
|
||||||
|
_, err := w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.GoogleIDP.List(context.Background())
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Len(t, ret, 1)
|
||||||
|
assert.Equal(t, testGoogleIntegration, ret[0])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGoogleIDP_List_Err(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/google-idp", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||||
|
w.WriteHeader(400)
|
||||||
|
_, err := w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.GoogleIDP.List(context.Background())
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "No", err.Error())
|
||||||
|
assert.Empty(t, ret)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGoogleIDP_Get_200(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/google-idp/int-1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
assert.Equal(t, "GET", r.Method)
|
||||||
|
retBytes, _ := json.Marshal(testGoogleIntegration)
|
||||||
|
_, err := w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.GoogleIDP.Get(context.Background(), "int-1")
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, testGoogleIntegration, *ret)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGoogleIDP_Get_Err(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/google-idp/int-1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "Not found", Code: 404})
|
||||||
|
w.WriteHeader(404)
|
||||||
|
_, err := w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.GoogleIDP.Get(context.Background(), "int-1")
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "Not found", err.Error())
|
||||||
|
assert.Nil(t, ret)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGoogleIDP_Create_200(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/google-idp", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
assert.Equal(t, "POST", r.Method)
|
||||||
|
reqBytes, err := io.ReadAll(r.Body)
|
||||||
|
require.NoError(t, err)
|
||||||
|
var req api.CreateGoogleIntegrationRequest
|
||||||
|
err = json.Unmarshal(reqBytes, &req)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, "C01234567", req.CustomerId)
|
||||||
|
retBytes, _ := json.Marshal(testGoogleIntegration)
|
||||||
|
_, err = w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.GoogleIDP.Create(context.Background(), api.CreateGoogleIntegrationRequest{
|
||||||
|
CustomerId: "C01234567",
|
||||||
|
ServiceAccountKey: "key-data",
|
||||||
|
GroupPrefixes: &[]string{"eng-"},
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, testGoogleIntegration, *ret)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGoogleIDP_Create_Err(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/google-idp", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||||
|
w.WriteHeader(400)
|
||||||
|
_, err := w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.GoogleIDP.Create(context.Background(), api.CreateGoogleIntegrationRequest{})
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "No", err.Error())
|
||||||
|
assert.Nil(t, ret)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGoogleIDP_Update_200(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/google-idp/int-1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
assert.Equal(t, "PUT", r.Method)
|
||||||
|
reqBytes, err := io.ReadAll(r.Body)
|
||||||
|
require.NoError(t, err)
|
||||||
|
var req api.UpdateGoogleIntegrationRequest
|
||||||
|
err = json.Unmarshal(reqBytes, &req)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, true, *req.Enabled)
|
||||||
|
retBytes, _ := json.Marshal(testGoogleIntegration)
|
||||||
|
_, err = w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.GoogleIDP.Update(context.Background(), "int-1", api.UpdateGoogleIntegrationRequest{
|
||||||
|
Enabled: ptr(true),
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, testGoogleIntegration, *ret)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGoogleIDP_Update_Err(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/google-idp/int-1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||||
|
w.WriteHeader(400)
|
||||||
|
_, err := w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.GoogleIDP.Update(context.Background(), "int-1", api.UpdateGoogleIntegrationRequest{})
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "No", err.Error())
|
||||||
|
assert.Nil(t, ret)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGoogleIDP_Delete_200(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/google-idp/int-1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
assert.Equal(t, "DELETE", r.Method)
|
||||||
|
w.WriteHeader(200)
|
||||||
|
})
|
||||||
|
err := c.GoogleIDP.Delete(context.Background(), "int-1")
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGoogleIDP_Delete_Err(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/google-idp/int-1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "Not found", Code: 404})
|
||||||
|
w.WriteHeader(404)
|
||||||
|
_, err := w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
err := c.GoogleIDP.Delete(context.Background(), "int-1")
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "Not found", err.Error())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGoogleIDP_Sync_200(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/google-idp/int-1/sync", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
assert.Equal(t, "POST", r.Method)
|
||||||
|
retBytes, _ := json.Marshal(api.SyncResult{Result: ptr("ok")})
|
||||||
|
_, err := w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.GoogleIDP.Sync(context.Background(), "int-1")
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, "ok", *ret.Result)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGoogleIDP_Sync_Err(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/google-idp/int-1/sync", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "Not found", Code: 404})
|
||||||
|
w.WriteHeader(404)
|
||||||
|
_, err := w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.GoogleIDP.Sync(context.Background(), "int-1")
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "Not found", err.Error())
|
||||||
|
assert.Nil(t, ret)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGoogleIDP_GetLogs_200(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/google-idp/int-1/logs", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
assert.Equal(t, "GET", r.Method)
|
||||||
|
retBytes, _ := json.Marshal([]api.IdpIntegrationSyncLog{testSyncLog})
|
||||||
|
_, err := w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.GoogleIDP.GetLogs(context.Background(), "int-1")
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Len(t, ret, 1)
|
||||||
|
assert.Equal(t, testSyncLog, ret[0])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGoogleIDP_GetLogs_Err(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/google-idp/int-1/logs", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "Not found", Code: 404})
|
||||||
|
w.WriteHeader(404)
|
||||||
|
_, err := w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.GoogleIDP.GetLogs(context.Background(), "int-1")
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "Not found", err.Error())
|
||||||
|
assert.Empty(t, ret)
|
||||||
|
})
|
||||||
|
}
|
||||||
112
shared/management/client/rest/okta_scim_idp.go
Normal file
112
shared/management/client/rest/okta_scim_idp.go
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
package rest
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/netbirdio/netbird/shared/management/http/api"
|
||||||
|
)
|
||||||
|
|
||||||
|
// OktaScimIDPAPI APIs for Okta SCIM IDP integrations
|
||||||
|
type OktaScimIDPAPI struct {
|
||||||
|
c *Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// List retrieves all Okta SCIM IDP integrations
|
||||||
|
func (a *OktaScimIDPAPI) List(ctx context.Context) ([]api.OktaScimIntegration, error) {
|
||||||
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/integrations/okta-scim-idp", nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if resp.Body != nil {
|
||||||
|
defer resp.Body.Close()
|
||||||
|
}
|
||||||
|
ret, err := parseResponse[[]api.OktaScimIntegration](resp)
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get retrieves a specific Okta SCIM IDP integration by ID
|
||||||
|
func (a *OktaScimIDPAPI) Get(ctx context.Context, integrationID string) (*api.OktaScimIntegration, error) {
|
||||||
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/integrations/okta-scim-idp/"+integrationID, nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if resp.Body != nil {
|
||||||
|
defer resp.Body.Close()
|
||||||
|
}
|
||||||
|
ret, err := parseResponse[api.OktaScimIntegration](resp)
|
||||||
|
return &ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create creates a new Okta SCIM IDP integration
|
||||||
|
func (a *OktaScimIDPAPI) Create(ctx context.Context, request api.CreateOktaScimIntegrationRequest) (*api.OktaScimIntegration, error) {
|
||||||
|
requestBytes, err := json.Marshal(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
resp, err := a.c.NewRequest(ctx, "POST", "/api/integrations/okta-scim-idp", bytes.NewReader(requestBytes), nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if resp.Body != nil {
|
||||||
|
defer resp.Body.Close()
|
||||||
|
}
|
||||||
|
ret, err := parseResponse[api.OktaScimIntegration](resp)
|
||||||
|
return &ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update updates an existing Okta SCIM IDP integration
|
||||||
|
func (a *OktaScimIDPAPI) Update(ctx context.Context, integrationID string, request api.UpdateOktaScimIntegrationRequest) (*api.OktaScimIntegration, error) {
|
||||||
|
requestBytes, err := json.Marshal(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
resp, err := a.c.NewRequest(ctx, "PUT", "/api/integrations/okta-scim-idp/"+integrationID, bytes.NewReader(requestBytes), nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if resp.Body != nil {
|
||||||
|
defer resp.Body.Close()
|
||||||
|
}
|
||||||
|
ret, err := parseResponse[api.OktaScimIntegration](resp)
|
||||||
|
return &ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete deletes an Okta SCIM IDP integration
|
||||||
|
func (a *OktaScimIDPAPI) Delete(ctx context.Context, integrationID string) error {
|
||||||
|
resp, err := a.c.NewRequest(ctx, "DELETE", "/api/integrations/okta-scim-idp/"+integrationID, nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if resp.Body != nil {
|
||||||
|
defer resp.Body.Close()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegenerateToken regenerates the SCIM API token for an Okta SCIM integration
|
||||||
|
func (a *OktaScimIDPAPI) RegenerateToken(ctx context.Context, integrationID string) (*api.ScimTokenResponse, error) {
|
||||||
|
resp, err := a.c.NewRequest(ctx, "POST", "/api/integrations/okta-scim-idp/"+integrationID+"/token", nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if resp.Body != nil {
|
||||||
|
defer resp.Body.Close()
|
||||||
|
}
|
||||||
|
ret, err := parseResponse[api.ScimTokenResponse](resp)
|
||||||
|
return &ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetLogs retrieves synchronization logs for an Okta SCIM IDP integration
|
||||||
|
func (a *OktaScimIDPAPI) GetLogs(ctx context.Context, integrationID string) ([]api.IdpIntegrationSyncLog, error) {
|
||||||
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/integrations/okta-scim-idp/"+integrationID+"/logs", nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if resp.Body != nil {
|
||||||
|
defer resp.Body.Close()
|
||||||
|
}
|
||||||
|
ret, err := parseResponse[[]api.IdpIntegrationSyncLog](resp)
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
246
shared/management/client/rest/okta_scim_idp_test.go
Normal file
246
shared/management/client/rest/okta_scim_idp_test.go
Normal file
@@ -0,0 +1,246 @@
|
|||||||
|
//go:build integration
|
||||||
|
|
||||||
|
package rest_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/netbirdio/netbird/shared/management/client/rest"
|
||||||
|
"github.com/netbirdio/netbird/shared/management/http/api"
|
||||||
|
"github.com/netbirdio/netbird/shared/management/http/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
var testOktaScimIntegration = api.OktaScimIntegration{
|
||||||
|
Id: 1,
|
||||||
|
AuthToken: "****",
|
||||||
|
Enabled: true,
|
||||||
|
GroupPrefixes: []string{"eng-"},
|
||||||
|
UserGroupPrefixes: []string{"dev-"},
|
||||||
|
LastSyncedAt: time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOktaScimIDP_List_200(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/okta-scim-idp", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
assert.Equal(t, "GET", r.Method)
|
||||||
|
retBytes, _ := json.Marshal([]api.OktaScimIntegration{testOktaScimIntegration})
|
||||||
|
_, err := w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.OktaScimIDP.List(context.Background())
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Len(t, ret, 1)
|
||||||
|
assert.Equal(t, testOktaScimIntegration, ret[0])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOktaScimIDP_List_Err(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/okta-scim-idp", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||||
|
w.WriteHeader(400)
|
||||||
|
_, err := w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.OktaScimIDP.List(context.Background())
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "No", err.Error())
|
||||||
|
assert.Empty(t, ret)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOktaScimIDP_Get_200(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/okta-scim-idp/int-1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
assert.Equal(t, "GET", r.Method)
|
||||||
|
retBytes, _ := json.Marshal(testOktaScimIntegration)
|
||||||
|
_, err := w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.OktaScimIDP.Get(context.Background(), "int-1")
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, testOktaScimIntegration, *ret)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOktaScimIDP_Get_Err(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/okta-scim-idp/int-1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "Not found", Code: 404})
|
||||||
|
w.WriteHeader(404)
|
||||||
|
_, err := w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.OktaScimIDP.Get(context.Background(), "int-1")
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "Not found", err.Error())
|
||||||
|
assert.Nil(t, ret)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOktaScimIDP_Create_200(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/okta-scim-idp", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
assert.Equal(t, "POST", r.Method)
|
||||||
|
reqBytes, err := io.ReadAll(r.Body)
|
||||||
|
require.NoError(t, err)
|
||||||
|
var req api.CreateOktaScimIntegrationRequest
|
||||||
|
err = json.Unmarshal(reqBytes, &req)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, "my-okta-connection", req.ConnectionName)
|
||||||
|
retBytes, _ := json.Marshal(testOktaScimIntegration)
|
||||||
|
_, err = w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.OktaScimIDP.Create(context.Background(), api.CreateOktaScimIntegrationRequest{
|
||||||
|
ConnectionName: "my-okta-connection",
|
||||||
|
GroupPrefixes: &[]string{"eng-"},
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, testOktaScimIntegration, *ret)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOktaScimIDP_Create_Err(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/okta-scim-idp", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||||
|
w.WriteHeader(400)
|
||||||
|
_, err := w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.OktaScimIDP.Create(context.Background(), api.CreateOktaScimIntegrationRequest{})
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "No", err.Error())
|
||||||
|
assert.Nil(t, ret)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOktaScimIDP_Update_200(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/okta-scim-idp/int-1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
assert.Equal(t, "PUT", r.Method)
|
||||||
|
reqBytes, err := io.ReadAll(r.Body)
|
||||||
|
require.NoError(t, err)
|
||||||
|
var req api.UpdateOktaScimIntegrationRequest
|
||||||
|
err = json.Unmarshal(reqBytes, &req)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, true, *req.Enabled)
|
||||||
|
retBytes, _ := json.Marshal(testOktaScimIntegration)
|
||||||
|
_, err = w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.OktaScimIDP.Update(context.Background(), "int-1", api.UpdateOktaScimIntegrationRequest{
|
||||||
|
Enabled: ptr(true),
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, testOktaScimIntegration, *ret)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOktaScimIDP_Update_Err(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/okta-scim-idp/int-1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||||
|
w.WriteHeader(400)
|
||||||
|
_, err := w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.OktaScimIDP.Update(context.Background(), "int-1", api.UpdateOktaScimIntegrationRequest{})
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "No", err.Error())
|
||||||
|
assert.Nil(t, ret)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOktaScimIDP_Delete_200(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/okta-scim-idp/int-1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
assert.Equal(t, "DELETE", r.Method)
|
||||||
|
w.WriteHeader(200)
|
||||||
|
})
|
||||||
|
err := c.OktaScimIDP.Delete(context.Background(), "int-1")
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOktaScimIDP_Delete_Err(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/okta-scim-idp/int-1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "Not found", Code: 404})
|
||||||
|
w.WriteHeader(404)
|
||||||
|
_, err := w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
err := c.OktaScimIDP.Delete(context.Background(), "int-1")
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "Not found", err.Error())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOktaScimIDP_RegenerateToken_200(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/okta-scim-idp/int-1/token", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
assert.Equal(t, "POST", r.Method)
|
||||||
|
retBytes, _ := json.Marshal(testScimToken)
|
||||||
|
_, err := w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.OktaScimIDP.RegenerateToken(context.Background(), "int-1")
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, testScimToken, *ret)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOktaScimIDP_RegenerateToken_Err(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/okta-scim-idp/int-1/token", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "Not found", Code: 404})
|
||||||
|
w.WriteHeader(404)
|
||||||
|
_, err := w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.OktaScimIDP.RegenerateToken(context.Background(), "int-1")
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "Not found", err.Error())
|
||||||
|
assert.Nil(t, ret)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOktaScimIDP_GetLogs_200(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/okta-scim-idp/int-1/logs", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
assert.Equal(t, "GET", r.Method)
|
||||||
|
retBytes, _ := json.Marshal([]api.IdpIntegrationSyncLog{testSyncLog})
|
||||||
|
_, err := w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.OktaScimIDP.GetLogs(context.Background(), "int-1")
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Len(t, ret, 1)
|
||||||
|
assert.Equal(t, testSyncLog, ret[0])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOktaScimIDP_GetLogs_Err(t *testing.T) {
|
||||||
|
withMockClient(func(c *rest.Client, mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("/api/integrations/okta-scim-idp/int-1/logs", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "Not found", Code: 404})
|
||||||
|
w.WriteHeader(404)
|
||||||
|
_, err := w.Write(retBytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
ret, err := c.OktaScimIDP.GetLogs(context.Background(), "int-1")
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "Not found", err.Error())
|
||||||
|
assert.Empty(t, ret)
|
||||||
|
})
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -17,6 +17,24 @@ const (
|
|||||||
TokenAuthScopes = "TokenAuth.Scopes"
|
TokenAuthScopes = "TokenAuth.Scopes"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Defines values for CreateAzureIntegrationRequestHost.
|
||||||
|
const (
|
||||||
|
CreateAzureIntegrationRequestHostMicrosoftCom CreateAzureIntegrationRequestHost = "microsoft.com"
|
||||||
|
CreateAzureIntegrationRequestHostMicrosoftUs CreateAzureIntegrationRequestHost = "microsoft.us"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Valid indicates whether the value is a known member of the CreateAzureIntegrationRequestHost enum.
|
||||||
|
func (e CreateAzureIntegrationRequestHost) Valid() bool {
|
||||||
|
switch e {
|
||||||
|
case CreateAzureIntegrationRequestHostMicrosoftCom:
|
||||||
|
return true
|
||||||
|
case CreateAzureIntegrationRequestHostMicrosoftUs:
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Defines values for CreateIntegrationRequestPlatform.
|
// Defines values for CreateIntegrationRequestPlatform.
|
||||||
const (
|
const (
|
||||||
CreateIntegrationRequestPlatformDatadog CreateIntegrationRequestPlatform = "datadog"
|
CreateIntegrationRequestPlatformDatadog CreateIntegrationRequestPlatform = "datadog"
|
||||||
@@ -1469,6 +1487,36 @@ type AvailablePorts struct {
|
|||||||
Udp int `json:"udp"`
|
Udp int `json:"udp"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AzureIntegration defines model for AzureIntegration.
|
||||||
|
type AzureIntegration struct {
|
||||||
|
// ClientId Azure AD application (client) ID
|
||||||
|
ClientId string `json:"client_id"`
|
||||||
|
|
||||||
|
// Enabled Whether the integration is enabled
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
|
||||||
|
// GroupPrefixes List of start_with string patterns for groups to sync
|
||||||
|
GroupPrefixes []string `json:"group_prefixes"`
|
||||||
|
|
||||||
|
// Host Azure host domain for the Graph API
|
||||||
|
Host string `json:"host"`
|
||||||
|
|
||||||
|
// Id The unique identifier for the integration
|
||||||
|
Id int64 `json:"id"`
|
||||||
|
|
||||||
|
// LastSyncedAt Timestamp of the last synchronization
|
||||||
|
LastSyncedAt time.Time `json:"last_synced_at"`
|
||||||
|
|
||||||
|
// SyncInterval Sync interval in seconds
|
||||||
|
SyncInterval int `json:"sync_interval"`
|
||||||
|
|
||||||
|
// TenantId Azure AD tenant ID
|
||||||
|
TenantId string `json:"tenant_id"`
|
||||||
|
|
||||||
|
// UserGroupPrefixes List of start_with string patterns for groups which users to sync
|
||||||
|
UserGroupPrefixes []string `json:"user_group_prefixes"`
|
||||||
|
}
|
||||||
|
|
||||||
// BearerAuthConfig defines model for BearerAuthConfig.
|
// BearerAuthConfig defines model for BearerAuthConfig.
|
||||||
type BearerAuthConfig struct {
|
type BearerAuthConfig struct {
|
||||||
// DistributionGroups List of group IDs that can use bearer auth
|
// DistributionGroups List of group IDs that can use bearer auth
|
||||||
@@ -1576,6 +1624,51 @@ type Country struct {
|
|||||||
// CountryCode 2-letter ISO 3166-1 alpha-2 code that represents the country
|
// CountryCode 2-letter ISO 3166-1 alpha-2 code that represents the country
|
||||||
type CountryCode = string
|
type CountryCode = string
|
||||||
|
|
||||||
|
// CreateAzureIntegrationRequest defines model for CreateAzureIntegrationRequest.
|
||||||
|
type CreateAzureIntegrationRequest struct {
|
||||||
|
// ClientId Azure AD application (client) ID
|
||||||
|
ClientId string `json:"client_id"`
|
||||||
|
|
||||||
|
// ClientSecret Base64-encoded Azure AD client secret
|
||||||
|
ClientSecret string `json:"client_secret"`
|
||||||
|
|
||||||
|
// GroupPrefixes List of start_with string patterns for groups to sync
|
||||||
|
GroupPrefixes *[]string `json:"group_prefixes,omitempty"`
|
||||||
|
|
||||||
|
// Host Azure host domain for the Graph API
|
||||||
|
Host CreateAzureIntegrationRequestHost `json:"host"`
|
||||||
|
|
||||||
|
// SyncInterval Sync interval in seconds (minimum 300). Defaults to 300 if not specified.
|
||||||
|
SyncInterval *int `json:"sync_interval,omitempty"`
|
||||||
|
|
||||||
|
// TenantId Azure AD tenant ID
|
||||||
|
TenantId string `json:"tenant_id"`
|
||||||
|
|
||||||
|
// UserGroupPrefixes List of start_with string patterns for groups which users to sync
|
||||||
|
UserGroupPrefixes *[]string `json:"user_group_prefixes,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateAzureIntegrationRequestHost Azure host domain for the Graph API
|
||||||
|
type CreateAzureIntegrationRequestHost string
|
||||||
|
|
||||||
|
// CreateGoogleIntegrationRequest defines model for CreateGoogleIntegrationRequest.
|
||||||
|
type CreateGoogleIntegrationRequest struct {
|
||||||
|
// CustomerId Customer ID from Google Workspace Account Settings
|
||||||
|
CustomerId string `json:"customer_id"`
|
||||||
|
|
||||||
|
// GroupPrefixes List of start_with string patterns for groups to sync
|
||||||
|
GroupPrefixes *[]string `json:"group_prefixes,omitempty"`
|
||||||
|
|
||||||
|
// ServiceAccountKey Base64-encoded Google service account key
|
||||||
|
ServiceAccountKey string `json:"service_account_key"`
|
||||||
|
|
||||||
|
// SyncInterval Sync interval in seconds (minimum 300). Defaults to 300 if not specified.
|
||||||
|
SyncInterval *int `json:"sync_interval,omitempty"`
|
||||||
|
|
||||||
|
// UserGroupPrefixes List of start_with string patterns for groups which users to sync
|
||||||
|
UserGroupPrefixes *[]string `json:"user_group_prefixes,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// CreateIntegrationRequest Request payload for creating a new event streaming integration. Also used as the structure for the PUT request body, but not all fields are applicable for updates (see PUT operation description).
|
// CreateIntegrationRequest Request payload for creating a new event streaming integration. Also used as the structure for the PUT request body, but not all fields are applicable for updates (see PUT operation description).
|
||||||
type CreateIntegrationRequest struct {
|
type CreateIntegrationRequest struct {
|
||||||
// Config Platform-specific configuration as key-value pairs. For creation, all necessary credentials and settings must be provided. For updates, provide the fields to change or the entire new configuration.
|
// Config Platform-specific configuration as key-value pairs. For creation, all necessary credentials and settings must be provided. For updates, provide the fields to change or the entire new configuration.
|
||||||
@@ -1591,7 +1684,19 @@ type CreateIntegrationRequest struct {
|
|||||||
// CreateIntegrationRequestPlatform The event streaming platform to integrate with (e.g., "datadog", "s3", "firehose"). This field is used for creation. For updates (PUT), this field, if sent, is ignored by the backend.
|
// CreateIntegrationRequestPlatform The event streaming platform to integrate with (e.g., "datadog", "s3", "firehose"). This field is used for creation. For updates (PUT), this field, if sent, is ignored by the backend.
|
||||||
type CreateIntegrationRequestPlatform string
|
type CreateIntegrationRequestPlatform string
|
||||||
|
|
||||||
// CreateScimIntegrationRequest Request payload for creating an SCIM IDP integration
|
// CreateOktaScimIntegrationRequest defines model for CreateOktaScimIntegrationRequest.
|
||||||
|
type CreateOktaScimIntegrationRequest struct {
|
||||||
|
// ConnectionName The Okta enterprise connection name on Auth0
|
||||||
|
ConnectionName string `json:"connection_name"`
|
||||||
|
|
||||||
|
// GroupPrefixes List of start_with string patterns for groups to sync
|
||||||
|
GroupPrefixes *[]string `json:"group_prefixes,omitempty"`
|
||||||
|
|
||||||
|
// UserGroupPrefixes List of start_with string patterns for groups which users to sync
|
||||||
|
UserGroupPrefixes *[]string `json:"user_group_prefixes,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateScimIntegrationRequest defines model for CreateScimIntegrationRequest.
|
||||||
type CreateScimIntegrationRequest struct {
|
type CreateScimIntegrationRequest struct {
|
||||||
// GroupPrefixes List of start_with string patterns for groups to sync
|
// GroupPrefixes List of start_with string patterns for groups to sync
|
||||||
GroupPrefixes *[]string `json:"group_prefixes,omitempty"`
|
GroupPrefixes *[]string `json:"group_prefixes,omitempty"`
|
||||||
@@ -1972,6 +2077,30 @@ type GeoLocationCheckAction string
|
|||||||
// GetTenantsResponse defines model for GetTenantsResponse.
|
// GetTenantsResponse defines model for GetTenantsResponse.
|
||||||
type GetTenantsResponse = []TenantResponse
|
type GetTenantsResponse = []TenantResponse
|
||||||
|
|
||||||
|
// GoogleIntegration defines model for GoogleIntegration.
|
||||||
|
type GoogleIntegration struct {
|
||||||
|
// CustomerId Customer ID from Google Workspace
|
||||||
|
CustomerId string `json:"customer_id"`
|
||||||
|
|
||||||
|
// Enabled Whether the integration is enabled
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
|
||||||
|
// GroupPrefixes List of start_with string patterns for groups to sync
|
||||||
|
GroupPrefixes []string `json:"group_prefixes"`
|
||||||
|
|
||||||
|
// Id The unique identifier for the integration
|
||||||
|
Id int64 `json:"id"`
|
||||||
|
|
||||||
|
// LastSyncedAt Timestamp of the last synchronization
|
||||||
|
LastSyncedAt time.Time `json:"last_synced_at"`
|
||||||
|
|
||||||
|
// SyncInterval Sync interval in seconds
|
||||||
|
SyncInterval int `json:"sync_interval"`
|
||||||
|
|
||||||
|
// UserGroupPrefixes List of start_with string patterns for groups which users to sync
|
||||||
|
UserGroupPrefixes []string `json:"user_group_prefixes"`
|
||||||
|
}
|
||||||
|
|
||||||
// Group defines model for Group.
|
// Group defines model for Group.
|
||||||
type Group struct {
|
type Group struct {
|
||||||
// Id Group ID
|
// Id Group ID
|
||||||
@@ -2263,6 +2392,12 @@ type InstanceVersionInfo struct {
|
|||||||
ManagementUpdateAvailable bool `json:"management_update_available"`
|
ManagementUpdateAvailable bool `json:"management_update_available"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IntegrationEnabled defines model for IntegrationEnabled.
|
||||||
|
type IntegrationEnabled struct {
|
||||||
|
// Enabled Whether the integration is enabled
|
||||||
|
Enabled *bool `json:"enabled,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// IntegrationResponse Represents an event streaming integration.
|
// IntegrationResponse Represents an event streaming integration.
|
||||||
type IntegrationResponse struct {
|
type IntegrationResponse struct {
|
||||||
// AccountId The identifier of the account this integration belongs to.
|
// AccountId The identifier of the account this integration belongs to.
|
||||||
@@ -2290,6 +2425,15 @@ type IntegrationResponse struct {
|
|||||||
// IntegrationResponsePlatform The event streaming platform.
|
// IntegrationResponsePlatform The event streaming platform.
|
||||||
type IntegrationResponsePlatform string
|
type IntegrationResponsePlatform string
|
||||||
|
|
||||||
|
// IntegrationSyncFilters defines model for IntegrationSyncFilters.
|
||||||
|
type IntegrationSyncFilters struct {
|
||||||
|
// GroupPrefixes List of start_with string patterns for groups to sync
|
||||||
|
GroupPrefixes *[]string `json:"group_prefixes,omitempty"`
|
||||||
|
|
||||||
|
// UserGroupPrefixes List of start_with string patterns for groups which users to sync
|
||||||
|
UserGroupPrefixes *[]string `json:"user_group_prefixes,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// InvoicePDFResponse defines model for InvoicePDFResponse.
|
// InvoicePDFResponse defines model for InvoicePDFResponse.
|
||||||
type InvoicePDFResponse struct {
|
type InvoicePDFResponse struct {
|
||||||
// Url URL to redirect the user to invoice.
|
// Url URL to redirect the user to invoice.
|
||||||
@@ -2770,6 +2914,27 @@ type OSVersionCheck struct {
|
|||||||
Windows *MinKernelVersionCheck `json:"windows,omitempty"`
|
Windows *MinKernelVersionCheck `json:"windows,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OktaScimIntegration defines model for OktaScimIntegration.
|
||||||
|
type OktaScimIntegration struct {
|
||||||
|
// AuthToken SCIM API token (full on creation/regeneration, masked on retrieval)
|
||||||
|
AuthToken string `json:"auth_token"`
|
||||||
|
|
||||||
|
// Enabled Whether the integration is enabled
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
|
||||||
|
// GroupPrefixes List of start_with string patterns for groups to sync
|
||||||
|
GroupPrefixes []string `json:"group_prefixes"`
|
||||||
|
|
||||||
|
// Id The unique identifier for the integration
|
||||||
|
Id int64 `json:"id"`
|
||||||
|
|
||||||
|
// LastSyncedAt Timestamp of the last synchronization
|
||||||
|
LastSyncedAt time.Time `json:"last_synced_at"`
|
||||||
|
|
||||||
|
// UserGroupPrefixes List of start_with string patterns for groups which users to sync
|
||||||
|
UserGroupPrefixes []string `json:"user_group_prefixes"`
|
||||||
|
}
|
||||||
|
|
||||||
// PINAuthConfig defines model for PINAuthConfig.
|
// PINAuthConfig defines model for PINAuthConfig.
|
||||||
type PINAuthConfig struct {
|
type PINAuthConfig struct {
|
||||||
// Enabled Whether PIN auth is enabled
|
// Enabled Whether PIN auth is enabled
|
||||||
@@ -3619,12 +3784,12 @@ type RulePortRange struct {
|
|||||||
Start int `json:"start"`
|
Start int `json:"start"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ScimIntegration Represents a SCIM IDP integration
|
// ScimIntegration defines model for ScimIntegration.
|
||||||
type ScimIntegration struct {
|
type ScimIntegration struct {
|
||||||
// AuthToken SCIM API token (full on creation, masked otherwise)
|
// AuthToken SCIM API token (full on creation, masked otherwise)
|
||||||
AuthToken string `json:"auth_token"`
|
AuthToken string `json:"auth_token"`
|
||||||
|
|
||||||
// Enabled Indicates whether the integration is enabled
|
// Enabled Whether the integration is enabled
|
||||||
Enabled bool `json:"enabled"`
|
Enabled bool `json:"enabled"`
|
||||||
|
|
||||||
// GroupPrefixes List of start_with string patterns for groups to sync
|
// GroupPrefixes List of start_with string patterns for groups to sync
|
||||||
@@ -3636,6 +3801,9 @@ type ScimIntegration struct {
|
|||||||
// LastSyncedAt Timestamp of when the integration was last synced
|
// LastSyncedAt Timestamp of when the integration was last synced
|
||||||
LastSyncedAt time.Time `json:"last_synced_at"`
|
LastSyncedAt time.Time `json:"last_synced_at"`
|
||||||
|
|
||||||
|
// Prefix The connection prefix used for the SCIM provider
|
||||||
|
Prefix string `json:"prefix"`
|
||||||
|
|
||||||
// Provider Name of the SCIM identity provider
|
// Provider Name of the SCIM identity provider
|
||||||
Provider string `json:"provider"`
|
Provider string `json:"provider"`
|
||||||
|
|
||||||
@@ -4040,6 +4208,11 @@ type Subscription struct {
|
|||||||
UpdatedAt time.Time `json:"updated_at"`
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SyncResult Response for a manual sync trigger
|
||||||
|
type SyncResult struct {
|
||||||
|
Result *string `json:"result,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// TenantGroupResponse defines model for TenantGroupResponse.
|
// TenantGroupResponse defines model for TenantGroupResponse.
|
||||||
type TenantGroupResponse struct {
|
type TenantGroupResponse struct {
|
||||||
// Id The Group ID
|
// Id The Group ID
|
||||||
@@ -4085,14 +4258,74 @@ type TenantResponse struct {
|
|||||||
// TenantResponseStatus The status of the tenant
|
// TenantResponseStatus The status of the tenant
|
||||||
type TenantResponseStatus string
|
type TenantResponseStatus string
|
||||||
|
|
||||||
// UpdateScimIntegrationRequest Request payload for updating an SCIM IDP integration
|
// UpdateAzureIntegrationRequest defines model for UpdateAzureIntegrationRequest.
|
||||||
type UpdateScimIntegrationRequest struct {
|
type UpdateAzureIntegrationRequest struct {
|
||||||
// Enabled Indicates whether the integration is enabled
|
// ClientId Azure AD application (client) ID
|
||||||
|
ClientId *string `json:"client_id,omitempty"`
|
||||||
|
|
||||||
|
// ClientSecret Base64-encoded Azure AD client secret
|
||||||
|
ClientSecret *string `json:"client_secret,omitempty"`
|
||||||
|
|
||||||
|
// Enabled Whether the integration is enabled
|
||||||
Enabled *bool `json:"enabled,omitempty"`
|
Enabled *bool `json:"enabled,omitempty"`
|
||||||
|
|
||||||
// GroupPrefixes List of start_with string patterns for groups to sync
|
// GroupPrefixes List of start_with string patterns for groups to sync
|
||||||
GroupPrefixes *[]string `json:"group_prefixes,omitempty"`
|
GroupPrefixes *[]string `json:"group_prefixes,omitempty"`
|
||||||
|
|
||||||
|
// SyncInterval Sync interval in seconds (minimum 300)
|
||||||
|
SyncInterval *int `json:"sync_interval,omitempty"`
|
||||||
|
|
||||||
|
// TenantId Azure AD tenant ID
|
||||||
|
TenantId *string `json:"tenant_id,omitempty"`
|
||||||
|
|
||||||
|
// UserGroupPrefixes List of start_with string patterns for groups which users to sync
|
||||||
|
UserGroupPrefixes *[]string `json:"user_group_prefixes,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateGoogleIntegrationRequest defines model for UpdateGoogleIntegrationRequest.
|
||||||
|
type UpdateGoogleIntegrationRequest struct {
|
||||||
|
// CustomerId Customer ID from Google Workspace Account Settings
|
||||||
|
CustomerId *string `json:"customer_id,omitempty"`
|
||||||
|
|
||||||
|
// Enabled Whether the integration is enabled
|
||||||
|
Enabled *bool `json:"enabled,omitempty"`
|
||||||
|
|
||||||
|
// GroupPrefixes List of start_with string patterns for groups to sync
|
||||||
|
GroupPrefixes *[]string `json:"group_prefixes,omitempty"`
|
||||||
|
|
||||||
|
// ServiceAccountKey Base64-encoded Google service account key
|
||||||
|
ServiceAccountKey *string `json:"service_account_key,omitempty"`
|
||||||
|
|
||||||
|
// SyncInterval Sync interval in seconds (minimum 300)
|
||||||
|
SyncInterval *int `json:"sync_interval,omitempty"`
|
||||||
|
|
||||||
|
// UserGroupPrefixes List of start_with string patterns for groups which users to sync
|
||||||
|
UserGroupPrefixes *[]string `json:"user_group_prefixes,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateOktaScimIntegrationRequest defines model for UpdateOktaScimIntegrationRequest.
|
||||||
|
type UpdateOktaScimIntegrationRequest struct {
|
||||||
|
// Enabled Whether the integration is enabled
|
||||||
|
Enabled *bool `json:"enabled,omitempty"`
|
||||||
|
|
||||||
|
// GroupPrefixes List of start_with string patterns for groups to sync
|
||||||
|
GroupPrefixes *[]string `json:"group_prefixes,omitempty"`
|
||||||
|
|
||||||
|
// UserGroupPrefixes List of start_with string patterns for groups which users to sync
|
||||||
|
UserGroupPrefixes *[]string `json:"user_group_prefixes,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateScimIntegrationRequest defines model for UpdateScimIntegrationRequest.
|
||||||
|
type UpdateScimIntegrationRequest struct {
|
||||||
|
// Enabled Whether the integration is enabled
|
||||||
|
Enabled *bool `json:"enabled,omitempty"`
|
||||||
|
|
||||||
|
// GroupPrefixes List of start_with string patterns for groups to sync
|
||||||
|
GroupPrefixes *[]string `json:"group_prefixes,omitempty"`
|
||||||
|
|
||||||
|
// Prefix The connection prefix used for the SCIM provider
|
||||||
|
Prefix *string `json:"prefix,omitempty"`
|
||||||
|
|
||||||
// UserGroupPrefixes List of start_with string patterns for groups which users to sync
|
// UserGroupPrefixes List of start_with string patterns for groups which users to sync
|
||||||
UserGroupPrefixes *[]string `json:"user_group_prefixes,omitempty"`
|
UserGroupPrefixes *[]string `json:"user_group_prefixes,omitempty"`
|
||||||
}
|
}
|
||||||
@@ -4612,6 +4845,12 @@ type PostApiIngressPeersJSONRequestBody = IngressPeerCreateRequest
|
|||||||
// PutApiIngressPeersIngressPeerIdJSONRequestBody defines body for PutApiIngressPeersIngressPeerId for application/json ContentType.
|
// PutApiIngressPeersIngressPeerIdJSONRequestBody defines body for PutApiIngressPeersIngressPeerId for application/json ContentType.
|
||||||
type PutApiIngressPeersIngressPeerIdJSONRequestBody = IngressPeerUpdateRequest
|
type PutApiIngressPeersIngressPeerIdJSONRequestBody = IngressPeerUpdateRequest
|
||||||
|
|
||||||
|
// CreateAzureIntegrationJSONRequestBody defines body for CreateAzureIntegration for application/json ContentType.
|
||||||
|
type CreateAzureIntegrationJSONRequestBody = CreateAzureIntegrationRequest
|
||||||
|
|
||||||
|
// UpdateAzureIntegrationJSONRequestBody defines body for UpdateAzureIntegration for application/json ContentType.
|
||||||
|
type UpdateAzureIntegrationJSONRequestBody = UpdateAzureIntegrationRequest
|
||||||
|
|
||||||
// PostApiIntegrationsBillingAwsMarketplaceActivateJSONRequestBody defines body for PostApiIntegrationsBillingAwsMarketplaceActivate for application/json ContentType.
|
// PostApiIntegrationsBillingAwsMarketplaceActivateJSONRequestBody defines body for PostApiIntegrationsBillingAwsMarketplaceActivate for application/json ContentType.
|
||||||
type PostApiIntegrationsBillingAwsMarketplaceActivateJSONRequestBody PostApiIntegrationsBillingAwsMarketplaceActivateJSONBody
|
type PostApiIntegrationsBillingAwsMarketplaceActivateJSONRequestBody PostApiIntegrationsBillingAwsMarketplaceActivateJSONBody
|
||||||
|
|
||||||
@@ -4648,6 +4887,12 @@ type CreateSentinelOneEDRIntegrationJSONRequestBody = EDRSentinelOneRequest
|
|||||||
// UpdateSentinelOneEDRIntegrationJSONRequestBody defines body for UpdateSentinelOneEDRIntegration for application/json ContentType.
|
// UpdateSentinelOneEDRIntegrationJSONRequestBody defines body for UpdateSentinelOneEDRIntegration for application/json ContentType.
|
||||||
type UpdateSentinelOneEDRIntegrationJSONRequestBody = EDRSentinelOneRequest
|
type UpdateSentinelOneEDRIntegrationJSONRequestBody = EDRSentinelOneRequest
|
||||||
|
|
||||||
|
// CreateGoogleIntegrationJSONRequestBody defines body for CreateGoogleIntegration for application/json ContentType.
|
||||||
|
type CreateGoogleIntegrationJSONRequestBody = CreateGoogleIntegrationRequest
|
||||||
|
|
||||||
|
// UpdateGoogleIntegrationJSONRequestBody defines body for UpdateGoogleIntegration for application/json ContentType.
|
||||||
|
type UpdateGoogleIntegrationJSONRequestBody = UpdateGoogleIntegrationRequest
|
||||||
|
|
||||||
// PostApiIntegrationsMspTenantsJSONRequestBody defines body for PostApiIntegrationsMspTenants for application/json ContentType.
|
// PostApiIntegrationsMspTenantsJSONRequestBody defines body for PostApiIntegrationsMspTenants for application/json ContentType.
|
||||||
type PostApiIntegrationsMspTenantsJSONRequestBody = CreateTenantRequest
|
type PostApiIntegrationsMspTenantsJSONRequestBody = CreateTenantRequest
|
||||||
|
|
||||||
@@ -4669,6 +4914,12 @@ type CreateNotificationChannelJSONRequestBody = NotificationChannelRequest
|
|||||||
// UpdateNotificationChannelJSONRequestBody defines body for UpdateNotificationChannel for application/json ContentType.
|
// UpdateNotificationChannelJSONRequestBody defines body for UpdateNotificationChannel for application/json ContentType.
|
||||||
type UpdateNotificationChannelJSONRequestBody = NotificationChannelRequest
|
type UpdateNotificationChannelJSONRequestBody = NotificationChannelRequest
|
||||||
|
|
||||||
|
// CreateOktaScimIntegrationJSONRequestBody defines body for CreateOktaScimIntegration for application/json ContentType.
|
||||||
|
type CreateOktaScimIntegrationJSONRequestBody = CreateOktaScimIntegrationRequest
|
||||||
|
|
||||||
|
// UpdateOktaScimIntegrationJSONRequestBody defines body for UpdateOktaScimIntegration for application/json ContentType.
|
||||||
|
type UpdateOktaScimIntegrationJSONRequestBody = UpdateOktaScimIntegrationRequest
|
||||||
|
|
||||||
// CreateSCIMIntegrationJSONRequestBody defines body for CreateSCIMIntegration for application/json ContentType.
|
// CreateSCIMIntegrationJSONRequestBody defines body for CreateSCIMIntegration for application/json ContentType.
|
||||||
type CreateSCIMIntegrationJSONRequestBody = CreateScimIntegrationRequest
|
type CreateSCIMIntegrationJSONRequestBody = CreateScimIntegrationRequest
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user