From 049befcb01b46a4aa541df8b1d4f538418f734cc Mon Sep 17 00:00:00 2001 From: Marco Bedulli <104758750+mbedulli@users.noreply.github.com> Date: Mon, 12 Feb 2024 10:56:14 +0100 Subject: [PATCH] create keys (#199) * create keys * update * Hashed formatting * fix error messages * fix get key value from plan * add data and tests * rm stg * docs * PlanModifier --- .github/workflows/acc-test.yml | 2 + coralogix/clientset/apikeys-client.go | 66 ++ coralogix/clientset/clientset.go | 6 + .../clientset/grpc/apikeys/api_keys.pb.go | 964 ++++++++++++++++++ .../grpc/apikeys/api_keys_grpc.pb.go | 213 ++++ coralogix/data_source_coralogix_api_key.go | 108 ++ .../data_source_coralogix_api_key_test.go | 35 + coralogix/provider.go | 2 + coralogix/provider_test.go | 3 + coralogix/resource_coralogix_api_key.go | 440 ++++++++ coralogix/resource_coralogix_api_key_test.go | 71 ++ docs/data-sources/api_key.md | 37 + docs/resources/api_key.md | 40 + examples/apikeys/main.tf | 28 + 14 files changed, 2015 insertions(+) create mode 100644 coralogix/clientset/apikeys-client.go create mode 100644 coralogix/clientset/grpc/apikeys/api_keys.pb.go create mode 100644 coralogix/clientset/grpc/apikeys/api_keys_grpc.pb.go create mode 100644 coralogix/data_source_coralogix_api_key.go create mode 100644 coralogix/data_source_coralogix_api_key_test.go create mode 100644 coralogix/resource_coralogix_api_key.go create mode 100644 coralogix/resource_coralogix_api_key_test.go create mode 100644 docs/data-sources/api_key.md create mode 100644 docs/resources/api_key.md create mode 100644 examples/apikeys/main.tf diff --git a/.github/workflows/acc-test.yml b/.github/workflows/acc-test.yml index 656dad78..6addbada 100644 --- a/.github/workflows/acc-test.yml +++ b/.github/workflows/acc-test.yml @@ -29,5 +29,7 @@ jobs: env: CORALOGIX_ENV: ${{ secrets.CORALOGIX_ENV }} CORALOGIX_API_KEY: ${{ secrets.CORALOGIX_API_KEY }} + CORALOGIX_ORG_KEY: ${{ secrets.CORALOGIX_ORG_KEY }} + run: | make testacc \ No newline at end of file diff --git a/coralogix/clientset/apikeys-client.go b/coralogix/clientset/apikeys-client.go new file mode 100644 index 00000000..14d67c22 --- /dev/null +++ b/coralogix/clientset/apikeys-client.go @@ -0,0 +1,66 @@ +package clientset + +import ( + "context" + apikeys "terraform-provider-coralogix/coralogix/clientset/grpc/apikeys" +) + +type ApikeysClient struct { + callPropertiesCreator *CallPropertiesCreator +} + +func (t ApikeysClient) CreateApiKey(ctx context.Context, req *apikeys.CreateApiKeyRequest) (*apikeys.CreateApiKeyResponse, error) { + callProperties, err := t.callPropertiesCreator.GetCallProperties(ctx) + if err != nil { + return nil, err + } + + conn := callProperties.Connection + defer conn.Close() + client := apikeys.NewApiKeysServiceClient(conn) + + return client.CreateApiKey(callProperties.Ctx, req, callProperties.CallOptions...) +} + +func (t ApikeysClient) GetApiKey(ctx context.Context, req *apikeys.GetApiKeyRequest) (*apikeys.GetApiKeyResponse, error) { + callProperties, err := t.callPropertiesCreator.GetCallProperties(ctx) + if err != nil { + return nil, err + } + + conn := callProperties.Connection + defer conn.Close() + client := apikeys.NewApiKeysServiceClient(conn) + + return client.GetApiKey(callProperties.Ctx, req, callProperties.CallOptions...) +} + +func (t ApikeysClient) UpdateApiKey(ctx context.Context, req *apikeys.UpdateApiKeyRequest) (*apikeys.UpdateApiKeyResponse, error) { + callProperties, err := t.callPropertiesCreator.GetCallProperties(ctx) + if err != nil { + return nil, err + } + + conn := callProperties.Connection + defer conn.Close() + client := apikeys.NewApiKeysServiceClient(conn) + + return client.UpdateApiKey(callProperties.Ctx, req, callProperties.CallOptions...) +} + +func (t ApikeysClient) DeleteApiKey(ctx context.Context, req *apikeys.DeleteApiKeyRequest) (*apikeys.DeleteApiKeyResponse, error) { + callProperties, err := t.callPropertiesCreator.GetCallProperties(ctx) + if err != nil { + return nil, err + } + + conn := callProperties.Connection + defer conn.Close() + client := apikeys.NewApiKeysServiceClient(conn) + + return client.DeleteApiKey(callProperties.Ctx, req, callProperties.CallOptions...) +} + +func NewApiKeysClient(c *CallPropertiesCreator) *ApikeysClient { + return &ApikeysClient{callPropertiesCreator: c} +} diff --git a/coralogix/clientset/clientset.go b/coralogix/clientset/clientset.go index 431996df..9ef2b949 100644 --- a/coralogix/clientset/clientset.go +++ b/coralogix/clientset/clientset.go @@ -20,6 +20,7 @@ type ClientSet struct { teams *TeamsClient slos *SLOsClient dahboardsFolders *DashboardsFoldersClient + apiKeys *ApikeysClient } func (c *ClientSet) RuleGroups() *RuleGroupsClient { @@ -90,6 +91,10 @@ func (c *ClientSet) Teams() *TeamsClient { return c.teams } +func (c *ClientSet) ApiKeys() *ApikeysClient { + return c.apiKeys +} + func (c *ClientSet) SLOs() *SLOsClient { return c.slos } @@ -122,5 +127,6 @@ func NewClientSet(targetUrl, apiKey, orgKey string) *ClientSet { teams: NewTeamsClient(teamsCPC), slos: NewSLOsClient(apikeyCPC), dahboardsFolders: NewDashboardsFoldersClient(apikeyCPC), + apiKeys: NewApiKeysClient(teamsCPC), } } diff --git a/coralogix/clientset/grpc/apikeys/api_keys.pb.go b/coralogix/clientset/grpc/apikeys/api_keys.pb.go new file mode 100644 index 00000000..d3fd21ec --- /dev/null +++ b/coralogix/clientset/grpc/apikeys/api_keys.pb.go @@ -0,0 +1,964 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc v4.25.1 +// source: api_keys.proto + +package __ + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Owner struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Owner: + // *Owner_UserId + // *Owner_TeamId + // *Owner_OrganisationId + Owner isOwner_Owner `protobuf_oneof:"owner"` +} + +func (x *Owner) Reset() { + *x = Owner{} + if protoimpl.UnsafeEnabled { + mi := &file_api_keys_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Owner) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Owner) ProtoMessage() {} + +func (x *Owner) ProtoReflect() protoreflect.Message { + mi := &file_api_keys_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Owner.ProtoReflect.Descriptor instead. +func (*Owner) Descriptor() ([]byte, []int) { + return file_api_keys_proto_rawDescGZIP(), []int{0} +} + +func (m *Owner) GetOwner() isOwner_Owner { + if m != nil { + return m.Owner + } + return nil +} + +func (x *Owner) GetUserId() string { + if x, ok := x.GetOwner().(*Owner_UserId); ok { + return x.UserId + } + return "" +} + +func (x *Owner) GetTeamId() uint32 { + if x, ok := x.GetOwner().(*Owner_TeamId); ok { + return x.TeamId + } + return 0 +} + +func (x *Owner) GetOrganisationId() string { + if x, ok := x.GetOwner().(*Owner_OrganisationId); ok { + return x.OrganisationId + } + return "" +} + +type isOwner_Owner interface { + isOwner_Owner() +} + +type Owner_UserId struct { + UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3,oneof"` +} + +type Owner_TeamId struct { + TeamId uint32 `protobuf:"varint,2,opt,name=team_id,json=teamId,proto3,oneof"` +} + +type Owner_OrganisationId struct { + OrganisationId string `protobuf:"bytes,3,opt,name=organisation_id,json=organisationId,proto3,oneof"` +} + +func (*Owner_UserId) isOwner_Owner() {} + +func (*Owner_TeamId) isOwner_Owner() {} + +func (*Owner_OrganisationId) isOwner_Owner() {} + +type KeyInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Owner *Owner `protobuf:"bytes,2,opt,name=owner,proto3" json:"owner,omitempty"` + Active bool `protobuf:"varint,3,opt,name=active,proto3" json:"active,omitempty"` + Hashed bool `protobuf:"varint,4,opt,name=hashed,proto3" json:"hashed,omitempty"` + Roles []string `protobuf:"bytes,5,rep,name=roles,proto3" json:"roles,omitempty"` +} + +func (x *KeyInfo) Reset() { + *x = KeyInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_api_keys_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *KeyInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*KeyInfo) ProtoMessage() {} + +func (x *KeyInfo) ProtoReflect() protoreflect.Message { + mi := &file_api_keys_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use KeyInfo.ProtoReflect.Descriptor instead. +func (*KeyInfo) Descriptor() ([]byte, []int) { + return file_api_keys_proto_rawDescGZIP(), []int{1} +} + +func (x *KeyInfo) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *KeyInfo) GetOwner() *Owner { + if x != nil { + return x.Owner + } + return nil +} + +func (x *KeyInfo) GetActive() bool { + if x != nil { + return x.Active + } + return false +} + +func (x *KeyInfo) GetHashed() bool { + if x != nil { + return x.Hashed + } + return false +} + +func (x *KeyInfo) GetRoles() []string { + if x != nil { + return x.Roles + } + return nil +} + +type UpdateApiKeyRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + KeyId string `protobuf:"bytes,1,opt,name=key_id,json=keyId,proto3" json:"key_id,omitempty"` + NewName *string `protobuf:"bytes,2,opt,name=new_name,json=newName,proto3,oneof" json:"new_name,omitempty"` + IsActive *bool `protobuf:"varint,3,opt,name=is_active,json=isActive,proto3,oneof" json:"is_active,omitempty"` + Roles *UpdateApiKeyRequest_Roles `protobuf:"bytes,4,opt,name=roles,proto3,oneof" json:"roles,omitempty"` +} + +func (x *UpdateApiKeyRequest) Reset() { + *x = UpdateApiKeyRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_keys_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateApiKeyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateApiKeyRequest) ProtoMessage() {} + +func (x *UpdateApiKeyRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_keys_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateApiKeyRequest.ProtoReflect.Descriptor instead. +func (*UpdateApiKeyRequest) Descriptor() ([]byte, []int) { + return file_api_keys_proto_rawDescGZIP(), []int{2} +} + +func (x *UpdateApiKeyRequest) GetKeyId() string { + if x != nil { + return x.KeyId + } + return "" +} + +func (x *UpdateApiKeyRequest) GetNewName() string { + if x != nil && x.NewName != nil { + return *x.NewName + } + return "" +} + +func (x *UpdateApiKeyRequest) GetIsActive() bool { + if x != nil && x.IsActive != nil { + return *x.IsActive + } + return false +} + +func (x *UpdateApiKeyRequest) GetRoles() *UpdateApiKeyRequest_Roles { + if x != nil { + return x.Roles + } + return nil +} + +type UpdateApiKeyResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *UpdateApiKeyResponse) Reset() { + *x = UpdateApiKeyResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_keys_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateApiKeyResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateApiKeyResponse) ProtoMessage() {} + +func (x *UpdateApiKeyResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_keys_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateApiKeyResponse.ProtoReflect.Descriptor instead. +func (*UpdateApiKeyResponse) Descriptor() ([]byte, []int) { + return file_api_keys_proto_rawDescGZIP(), []int{3} +} + +type DeleteApiKeyRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + KeyId string `protobuf:"bytes,1,opt,name=key_id,json=keyId,proto3" json:"key_id,omitempty"` +} + +func (x *DeleteApiKeyRequest) Reset() { + *x = DeleteApiKeyRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_keys_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteApiKeyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteApiKeyRequest) ProtoMessage() {} + +func (x *DeleteApiKeyRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_keys_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteApiKeyRequest.ProtoReflect.Descriptor instead. +func (*DeleteApiKeyRequest) Descriptor() ([]byte, []int) { + return file_api_keys_proto_rawDescGZIP(), []int{4} +} + +func (x *DeleteApiKeyRequest) GetKeyId() string { + if x != nil { + return x.KeyId + } + return "" +} + +type DeleteApiKeyResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *DeleteApiKeyResponse) Reset() { + *x = DeleteApiKeyResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_keys_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteApiKeyResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteApiKeyResponse) ProtoMessage() {} + +func (x *DeleteApiKeyResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_keys_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteApiKeyResponse.ProtoReflect.Descriptor instead. +func (*DeleteApiKeyResponse) Descriptor() ([]byte, []int) { + return file_api_keys_proto_rawDescGZIP(), []int{5} +} + +type CreateApiKeyRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + KeyInfo *KeyInfo `protobuf:"bytes,1,opt,name=key_info,json=keyInfo,proto3" json:"key_info,omitempty"` +} + +func (x *CreateApiKeyRequest) Reset() { + *x = CreateApiKeyRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_keys_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateApiKeyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateApiKeyRequest) ProtoMessage() {} + +func (x *CreateApiKeyRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_keys_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateApiKeyRequest.ProtoReflect.Descriptor instead. +func (*CreateApiKeyRequest) Descriptor() ([]byte, []int) { + return file_api_keys_proto_rawDescGZIP(), []int{6} +} + +func (x *CreateApiKeyRequest) GetKeyInfo() *KeyInfo { + if x != nil { + return x.KeyInfo + } + return nil +} + +type CreateApiKeyResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + KeyId string `protobuf:"bytes,1,opt,name=key_id,json=keyId,proto3" json:"key_id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Value string `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *CreateApiKeyResponse) Reset() { + *x = CreateApiKeyResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_keys_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateApiKeyResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateApiKeyResponse) ProtoMessage() {} + +func (x *CreateApiKeyResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_keys_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateApiKeyResponse.ProtoReflect.Descriptor instead. +func (*CreateApiKeyResponse) Descriptor() ([]byte, []int) { + return file_api_keys_proto_rawDescGZIP(), []int{7} +} + +func (x *CreateApiKeyResponse) GetKeyId() string { + if x != nil { + return x.KeyId + } + return "" +} + +func (x *CreateApiKeyResponse) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *CreateApiKeyResponse) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +type GetApiKeyRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + KeyId string `protobuf:"bytes,1,opt,name=key_id,json=keyId,proto3" json:"key_id,omitempty"` +} + +func (x *GetApiKeyRequest) Reset() { + *x = GetApiKeyRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_keys_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetApiKeyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetApiKeyRequest) ProtoMessage() {} + +func (x *GetApiKeyRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_keys_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetApiKeyRequest.ProtoReflect.Descriptor instead. +func (*GetApiKeyRequest) Descriptor() ([]byte, []int) { + return file_api_keys_proto_rawDescGZIP(), []int{8} +} + +func (x *GetApiKeyRequest) GetKeyId() string { + if x != nil { + return x.KeyId + } + return "" +} + +type GetApiKeyResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + KeyInfo *KeyInfo `protobuf:"bytes,1,opt,name=key_info,json=keyInfo,proto3" json:"key_info,omitempty"` + Value *string `protobuf:"bytes,2,opt,name=value,proto3,oneof" json:"value,omitempty"` +} + +func (x *GetApiKeyResponse) Reset() { + *x = GetApiKeyResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_keys_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetApiKeyResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetApiKeyResponse) ProtoMessage() {} + +func (x *GetApiKeyResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_keys_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetApiKeyResponse.ProtoReflect.Descriptor instead. +func (*GetApiKeyResponse) Descriptor() ([]byte, []int) { + return file_api_keys_proto_rawDescGZIP(), []int{9} +} + +func (x *GetApiKeyResponse) GetKeyInfo() *KeyInfo { + if x != nil { + return x.KeyInfo + } + return nil +} + +func (x *GetApiKeyResponse) GetValue() string { + if x != nil && x.Value != nil { + return *x.Value + } + return "" +} + +type UpdateApiKeyRequest_Roles struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Roles []string `protobuf:"bytes,5,rep,name=roles,proto3" json:"roles,omitempty"` +} + +func (x *UpdateApiKeyRequest_Roles) Reset() { + *x = UpdateApiKeyRequest_Roles{} + if protoimpl.UnsafeEnabled { + mi := &file_api_keys_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateApiKeyRequest_Roles) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateApiKeyRequest_Roles) ProtoMessage() {} + +func (x *UpdateApiKeyRequest_Roles) ProtoReflect() protoreflect.Message { + mi := &file_api_keys_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateApiKeyRequest_Roles.ProtoReflect.Descriptor instead. +func (*UpdateApiKeyRequest_Roles) Descriptor() ([]byte, []int) { + return file_api_keys_proto_rawDescGZIP(), []int{2, 0} +} + +func (x *UpdateApiKeyRequest_Roles) GetRoles() []string { + if x != nil { + return x.Roles + } + return nil +} + +var File_api_keys_proto protoreflect.FileDescriptor + +var file_api_keys_proto_rawDesc = []byte{ + 0x0a, 0x0e, 0x61, 0x70, 0x69, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x12, 0x20, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x72, 0x61, 0x6c, 0x6f, 0x67, 0x69, 0x78, 0x61, + 0x70, 0x69, 0x73, 0x2e, 0x61, 0x61, 0x61, 0x2e, 0x61, 0x70, 0x69, 0x6b, 0x65, 0x79, 0x73, 0x2e, + 0x76, 0x32, 0x22, 0x71, 0x0a, 0x05, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x07, 0x75, + 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, + 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x07, 0x74, 0x65, 0x61, 0x6d, 0x5f, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x06, 0x74, 0x65, 0x61, 0x6d, 0x49, + 0x64, 0x12, 0x29, 0x0a, 0x0f, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x73, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0e, 0x6f, 0x72, + 0x67, 0x61, 0x6e, 0x69, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x42, 0x07, 0x0a, 0x05, + 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x22, 0xa2, 0x01, 0x0a, 0x07, 0x4b, 0x65, 0x79, 0x49, 0x6e, 0x66, + 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3d, 0x0a, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x72, 0x61, 0x6c, + 0x6f, 0x67, 0x69, 0x78, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x61, 0x61, 0x61, 0x2e, 0x61, 0x70, 0x69, + 0x6b, 0x65, 0x79, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x52, 0x05, 0x6f, + 0x77, 0x6e, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0x16, 0x0a, 0x06, + 0x68, 0x61, 0x73, 0x68, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x68, 0x61, + 0x73, 0x68, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x22, 0x8a, 0x02, 0x0a, 0x13, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x6b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x08, 0x6e, 0x65, 0x77, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x07, 0x6e, + 0x65, 0x77, 0x4e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x20, 0x0a, 0x09, 0x69, 0x73, 0x5f, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x48, 0x01, 0x52, 0x08, + 0x69, 0x73, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x88, 0x01, 0x01, 0x12, 0x56, 0x0a, 0x05, 0x72, + 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x63, 0x6f, 0x6d, + 0x2e, 0x63, 0x6f, 0x72, 0x61, 0x6c, 0x6f, 0x67, 0x69, 0x78, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x61, + 0x61, 0x61, 0x2e, 0x61, 0x70, 0x69, 0x6b, 0x65, 0x79, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x48, 0x02, 0x52, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, + 0x88, 0x01, 0x01, 0x1a, 0x1d, 0x0a, 0x05, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, + 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x72, 0x6f, 0x6c, + 0x65, 0x73, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x6e, 0x65, 0x77, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x42, + 0x0c, 0x0a, 0x0a, 0x5f, 0x69, 0x73, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x42, 0x08, 0x0a, + 0x06, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x22, 0x16, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x2c, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6b, 0x65, 0x79, 0x49, 0x64, 0x22, 0x16, 0x0a, + 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5b, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, + 0x70, 0x69, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x44, 0x0a, 0x08, + 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, + 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x72, 0x61, 0x6c, 0x6f, 0x67, 0x69, 0x78, 0x61, 0x70, + 0x69, 0x73, 0x2e, 0x61, 0x61, 0x61, 0x2e, 0x61, 0x70, 0x69, 0x6b, 0x65, 0x79, 0x73, 0x2e, 0x76, + 0x32, 0x2e, 0x4b, 0x65, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x49, 0x6e, + 0x66, 0x6f, 0x22, 0x57, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x70, 0x69, 0x4b, + 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x6b, 0x65, + 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6b, 0x65, 0x79, 0x49, + 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x29, 0x0a, 0x10, 0x47, + 0x65, 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x15, 0x0a, 0x06, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x6b, 0x65, 0x79, 0x49, 0x64, 0x22, 0x7e, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x41, 0x70, 0x69, + 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x08, 0x6b, + 0x65, 0x79, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, + 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x72, 0x61, 0x6c, 0x6f, 0x67, 0x69, 0x78, 0x61, 0x70, 0x69, + 0x73, 0x2e, 0x61, 0x61, 0x61, 0x2e, 0x61, 0x70, 0x69, 0x6b, 0x65, 0x79, 0x73, 0x2e, 0x76, 0x32, + 0x2e, 0x4b, 0x65, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x49, 0x6e, 0x66, + 0x6f, 0x12, 0x19, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x48, 0x00, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x88, 0x01, 0x01, 0x42, 0x08, 0x0a, 0x06, + 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x32, 0x8b, 0x04, 0x0a, 0x0e, 0x41, 0x70, 0x69, 0x4b, 0x65, + 0x79, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x7f, 0x0a, 0x0c, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x12, 0x35, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, + 0x63, 0x6f, 0x72, 0x61, 0x6c, 0x6f, 0x67, 0x69, 0x78, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x61, 0x61, + 0x61, 0x2e, 0x61, 0x70, 0x69, 0x6b, 0x65, 0x79, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x36, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x72, 0x61, 0x6c, 0x6f, 0x67, 0x69, 0x78, + 0x61, 0x70, 0x69, 0x73, 0x2e, 0x61, 0x61, 0x61, 0x2e, 0x61, 0x70, 0x69, 0x6b, 0x65, 0x79, 0x73, + 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x76, 0x0a, 0x09, 0x47, 0x65, + 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x12, 0x32, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, + 0x72, 0x61, 0x6c, 0x6f, 0x67, 0x69, 0x78, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x61, 0x61, 0x61, 0x2e, + 0x61, 0x70, 0x69, 0x6b, 0x65, 0x79, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x70, + 0x69, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x63, 0x6f, + 0x6d, 0x2e, 0x63, 0x6f, 0x72, 0x61, 0x6c, 0x6f, 0x67, 0x69, 0x78, 0x61, 0x70, 0x69, 0x73, 0x2e, + 0x61, 0x61, 0x61, 0x2e, 0x61, 0x70, 0x69, 0x6b, 0x65, 0x79, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x47, + 0x65, 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x7f, 0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x70, 0x69, 0x4b, + 0x65, 0x79, 0x12, 0x35, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x72, 0x61, 0x6c, 0x6f, 0x67, + 0x69, 0x78, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x61, 0x61, 0x61, 0x2e, 0x61, 0x70, 0x69, 0x6b, 0x65, + 0x79, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x70, 0x69, 0x4b, + 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, + 0x63, 0x6f, 0x72, 0x61, 0x6c, 0x6f, 0x67, 0x69, 0x78, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x61, 0x61, + 0x61, 0x2e, 0x61, 0x70, 0x69, 0x6b, 0x65, 0x79, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x7f, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x69, + 0x4b, 0x65, 0x79, 0x12, 0x35, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x72, 0x61, 0x6c, 0x6f, + 0x67, 0x69, 0x78, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x61, 0x61, 0x61, 0x2e, 0x61, 0x70, 0x69, 0x6b, + 0x65, 0x79, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x69, + 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x63, 0x6f, 0x6d, + 0x2e, 0x63, 0x6f, 0x72, 0x61, 0x6c, 0x6f, 0x67, 0x69, 0x78, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x61, + 0x61, 0x61, 0x2e, 0x61, 0x70, 0x69, 0x6b, 0x65, 0x79, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x42, 0x03, 0x5a, 0x01, 0x2e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, +} + +var ( + file_api_keys_proto_rawDescOnce sync.Once + file_api_keys_proto_rawDescData = file_api_keys_proto_rawDesc +) + +func file_api_keys_proto_rawDescGZIP() []byte { + file_api_keys_proto_rawDescOnce.Do(func() { + file_api_keys_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_keys_proto_rawDescData) + }) + return file_api_keys_proto_rawDescData +} + +var file_api_keys_proto_msgTypes = make([]protoimpl.MessageInfo, 11) +var file_api_keys_proto_goTypes = []interface{}{ + (*Owner)(nil), // 0: com.coralogixapis.aaa.apikeys.v2.Owner + (*KeyInfo)(nil), // 1: com.coralogixapis.aaa.apikeys.v2.KeyInfo + (*UpdateApiKeyRequest)(nil), // 2: com.coralogixapis.aaa.apikeys.v2.UpdateApiKeyRequest + (*UpdateApiKeyResponse)(nil), // 3: com.coralogixapis.aaa.apikeys.v2.UpdateApiKeyResponse + (*DeleteApiKeyRequest)(nil), // 4: com.coralogixapis.aaa.apikeys.v2.DeleteApiKeyRequest + (*DeleteApiKeyResponse)(nil), // 5: com.coralogixapis.aaa.apikeys.v2.DeleteApiKeyResponse + (*CreateApiKeyRequest)(nil), // 6: com.coralogixapis.aaa.apikeys.v2.CreateApiKeyRequest + (*CreateApiKeyResponse)(nil), // 7: com.coralogixapis.aaa.apikeys.v2.CreateApiKeyResponse + (*GetApiKeyRequest)(nil), // 8: com.coralogixapis.aaa.apikeys.v2.GetApiKeyRequest + (*GetApiKeyResponse)(nil), // 9: com.coralogixapis.aaa.apikeys.v2.GetApiKeyResponse + (*UpdateApiKeyRequest_Roles)(nil), // 10: com.coralogixapis.aaa.apikeys.v2.UpdateApiKeyRequest.Roles +} +var file_api_keys_proto_depIdxs = []int32{ + 0, // 0: com.coralogixapis.aaa.apikeys.v2.KeyInfo.owner:type_name -> com.coralogixapis.aaa.apikeys.v2.Owner + 10, // 1: com.coralogixapis.aaa.apikeys.v2.UpdateApiKeyRequest.roles:type_name -> com.coralogixapis.aaa.apikeys.v2.UpdateApiKeyRequest.Roles + 1, // 2: com.coralogixapis.aaa.apikeys.v2.CreateApiKeyRequest.key_info:type_name -> com.coralogixapis.aaa.apikeys.v2.KeyInfo + 1, // 3: com.coralogixapis.aaa.apikeys.v2.GetApiKeyResponse.key_info:type_name -> com.coralogixapis.aaa.apikeys.v2.KeyInfo + 6, // 4: com.coralogixapis.aaa.apikeys.v2.ApiKeysService.CreateApiKey:input_type -> com.coralogixapis.aaa.apikeys.v2.CreateApiKeyRequest + 8, // 5: com.coralogixapis.aaa.apikeys.v2.ApiKeysService.GetApiKey:input_type -> com.coralogixapis.aaa.apikeys.v2.GetApiKeyRequest + 4, // 6: com.coralogixapis.aaa.apikeys.v2.ApiKeysService.DeleteApiKey:input_type -> com.coralogixapis.aaa.apikeys.v2.DeleteApiKeyRequest + 2, // 7: com.coralogixapis.aaa.apikeys.v2.ApiKeysService.UpdateApiKey:input_type -> com.coralogixapis.aaa.apikeys.v2.UpdateApiKeyRequest + 7, // 8: com.coralogixapis.aaa.apikeys.v2.ApiKeysService.CreateApiKey:output_type -> com.coralogixapis.aaa.apikeys.v2.CreateApiKeyResponse + 9, // 9: com.coralogixapis.aaa.apikeys.v2.ApiKeysService.GetApiKey:output_type -> com.coralogixapis.aaa.apikeys.v2.GetApiKeyResponse + 5, // 10: com.coralogixapis.aaa.apikeys.v2.ApiKeysService.DeleteApiKey:output_type -> com.coralogixapis.aaa.apikeys.v2.DeleteApiKeyResponse + 3, // 11: com.coralogixapis.aaa.apikeys.v2.ApiKeysService.UpdateApiKey:output_type -> com.coralogixapis.aaa.apikeys.v2.UpdateApiKeyResponse + 8, // [8:12] is the sub-list for method output_type + 4, // [4:8] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name +} + +func init() { file_api_keys_proto_init() } +func file_api_keys_proto_init() { + if File_api_keys_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_api_keys_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Owner); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_keys_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*KeyInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_keys_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateApiKeyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_keys_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateApiKeyResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_keys_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteApiKeyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_keys_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteApiKeyResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_keys_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateApiKeyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_keys_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateApiKeyResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_keys_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetApiKeyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_keys_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetApiKeyResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_keys_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateApiKeyRequest_Roles); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_api_keys_proto_msgTypes[0].OneofWrappers = []interface{}{ + (*Owner_UserId)(nil), + (*Owner_TeamId)(nil), + (*Owner_OrganisationId)(nil), + } + file_api_keys_proto_msgTypes[2].OneofWrappers = []interface{}{} + file_api_keys_proto_msgTypes[9].OneofWrappers = []interface{}{} + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_api_keys_proto_rawDesc, + NumEnums: 0, + NumMessages: 11, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_api_keys_proto_goTypes, + DependencyIndexes: file_api_keys_proto_depIdxs, + MessageInfos: file_api_keys_proto_msgTypes, + }.Build() + File_api_keys_proto = out.File + file_api_keys_proto_rawDesc = nil + file_api_keys_proto_goTypes = nil + file_api_keys_proto_depIdxs = nil +} diff --git a/coralogix/clientset/grpc/apikeys/api_keys_grpc.pb.go b/coralogix/clientset/grpc/apikeys/api_keys_grpc.pb.go new file mode 100644 index 00000000..0d0ebe1a --- /dev/null +++ b/coralogix/clientset/grpc/apikeys/api_keys_grpc.pb.go @@ -0,0 +1,213 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v4.25.1 +// source: api_keys.proto + +package __ + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// ApiKeysServiceClient is the client API for ApiKeysService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type ApiKeysServiceClient interface { + CreateApiKey(ctx context.Context, in *CreateApiKeyRequest, opts ...grpc.CallOption) (*CreateApiKeyResponse, error) + GetApiKey(ctx context.Context, in *GetApiKeyRequest, opts ...grpc.CallOption) (*GetApiKeyResponse, error) + DeleteApiKey(ctx context.Context, in *DeleteApiKeyRequest, opts ...grpc.CallOption) (*DeleteApiKeyResponse, error) + UpdateApiKey(ctx context.Context, in *UpdateApiKeyRequest, opts ...grpc.CallOption) (*UpdateApiKeyResponse, error) +} + +type apiKeysServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewApiKeysServiceClient(cc grpc.ClientConnInterface) ApiKeysServiceClient { + return &apiKeysServiceClient{cc} +} + +func (c *apiKeysServiceClient) CreateApiKey(ctx context.Context, in *CreateApiKeyRequest, opts ...grpc.CallOption) (*CreateApiKeyResponse, error) { + out := new(CreateApiKeyResponse) + err := c.cc.Invoke(ctx, "/com.coralogixapis.aaa.apikeys.v2.ApiKeysService/CreateApiKey", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *apiKeysServiceClient) GetApiKey(ctx context.Context, in *GetApiKeyRequest, opts ...grpc.CallOption) (*GetApiKeyResponse, error) { + out := new(GetApiKeyResponse) + err := c.cc.Invoke(ctx, "/com.coralogixapis.aaa.apikeys.v2.ApiKeysService/GetApiKey", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *apiKeysServiceClient) DeleteApiKey(ctx context.Context, in *DeleteApiKeyRequest, opts ...grpc.CallOption) (*DeleteApiKeyResponse, error) { + out := new(DeleteApiKeyResponse) + err := c.cc.Invoke(ctx, "/com.coralogixapis.aaa.apikeys.v2.ApiKeysService/DeleteApiKey", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *apiKeysServiceClient) UpdateApiKey(ctx context.Context, in *UpdateApiKeyRequest, opts ...grpc.CallOption) (*UpdateApiKeyResponse, error) { + out := new(UpdateApiKeyResponse) + err := c.cc.Invoke(ctx, "/com.coralogixapis.aaa.apikeys.v2.ApiKeysService/UpdateApiKey", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ApiKeysServiceServer is the server API for ApiKeysService service. +// All implementations must embed UnimplementedApiKeysServiceServer +// for forward compatibility +type ApiKeysServiceServer interface { + CreateApiKey(context.Context, *CreateApiKeyRequest) (*CreateApiKeyResponse, error) + GetApiKey(context.Context, *GetApiKeyRequest) (*GetApiKeyResponse, error) + DeleteApiKey(context.Context, *DeleteApiKeyRequest) (*DeleteApiKeyResponse, error) + UpdateApiKey(context.Context, *UpdateApiKeyRequest) (*UpdateApiKeyResponse, error) + mustEmbedUnimplementedApiKeysServiceServer() +} + +// UnimplementedApiKeysServiceServer must be embedded to have forward compatible implementations. +type UnimplementedApiKeysServiceServer struct { +} + +func (UnimplementedApiKeysServiceServer) CreateApiKey(context.Context, *CreateApiKeyRequest) (*CreateApiKeyResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateApiKey not implemented") +} +func (UnimplementedApiKeysServiceServer) GetApiKey(context.Context, *GetApiKeyRequest) (*GetApiKeyResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetApiKey not implemented") +} +func (UnimplementedApiKeysServiceServer) DeleteApiKey(context.Context, *DeleteApiKeyRequest) (*DeleteApiKeyResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteApiKey not implemented") +} +func (UnimplementedApiKeysServiceServer) UpdateApiKey(context.Context, *UpdateApiKeyRequest) (*UpdateApiKeyResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateApiKey not implemented") +} +func (UnimplementedApiKeysServiceServer) mustEmbedUnimplementedApiKeysServiceServer() {} + +// UnsafeApiKeysServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ApiKeysServiceServer will +// result in compilation errors. +type UnsafeApiKeysServiceServer interface { + mustEmbedUnimplementedApiKeysServiceServer() +} + +func RegisterApiKeysServiceServer(s grpc.ServiceRegistrar, srv ApiKeysServiceServer) { + s.RegisterService(&ApiKeysService_ServiceDesc, srv) +} + +func _ApiKeysService_CreateApiKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateApiKeyRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ApiKeysServiceServer).CreateApiKey(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/com.coralogixapis.aaa.apikeys.v2.ApiKeysService/CreateApiKey", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ApiKeysServiceServer).CreateApiKey(ctx, req.(*CreateApiKeyRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ApiKeysService_GetApiKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetApiKeyRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ApiKeysServiceServer).GetApiKey(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/com.coralogixapis.aaa.apikeys.v2.ApiKeysService/GetApiKey", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ApiKeysServiceServer).GetApiKey(ctx, req.(*GetApiKeyRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ApiKeysService_DeleteApiKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteApiKeyRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ApiKeysServiceServer).DeleteApiKey(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/com.coralogixapis.aaa.apikeys.v2.ApiKeysService/DeleteApiKey", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ApiKeysServiceServer).DeleteApiKey(ctx, req.(*DeleteApiKeyRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ApiKeysService_UpdateApiKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateApiKeyRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ApiKeysServiceServer).UpdateApiKey(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/com.coralogixapis.aaa.apikeys.v2.ApiKeysService/UpdateApiKey", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ApiKeysServiceServer).UpdateApiKey(ctx, req.(*UpdateApiKeyRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// ApiKeysService_ServiceDesc is the grpc.ServiceDesc for ApiKeysService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var ApiKeysService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "com.coralogixapis.aaa.apikeys.v2.ApiKeysService", + HandlerType: (*ApiKeysServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "CreateApiKey", + Handler: _ApiKeysService_CreateApiKey_Handler, + }, + { + MethodName: "GetApiKey", + Handler: _ApiKeysService_GetApiKey_Handler, + }, + { + MethodName: "DeleteApiKey", + Handler: _ApiKeysService_DeleteApiKey_Handler, + }, + { + MethodName: "UpdateApiKey", + Handler: _ApiKeysService_UpdateApiKey_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "api_keys.proto", +} diff --git a/coralogix/data_source_coralogix_api_key.go b/coralogix/data_source_coralogix_api_key.go new file mode 100644 index 00000000..1c97d496 --- /dev/null +++ b/coralogix/data_source_coralogix_api_key.go @@ -0,0 +1,108 @@ +package coralogix + +import ( + "context" + "fmt" + "log" + apikeys "terraform-provider-coralogix/coralogix/clientset/grpc/apikeys" + + "google.golang.org/protobuf/encoding/protojson" + + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "terraform-provider-coralogix/coralogix/clientset" +) + +var _ datasource.DataSourceWithConfigure = &ApiKeyDataSource{} + +func NewApiKeyDataSource() datasource.DataSource { + return &ApiKeyDataSource{} +} + +type ApiKeyDataSource struct { + client *clientset.ApikeysClient +} + +func (d *ApiKeyDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_api_key" +} + +func (d *ApiKeyDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { + if req.ProviderData == nil { + return + } + + clientSet, ok := req.ProviderData.(*clientset.ClientSet) + if !ok { + resp.Diagnostics.AddError( + "Unexpected Resource Configure Type", + fmt.Sprintf("Expected *clientset.ClientSet, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + return + } + + d.client = clientSet.ApiKeys() +} + +func (d *ApiKeyDataSource) Schema(ctx context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { + var r ApiKeyResource + var resourceResp resource.SchemaResponse + r.Schema(ctx, resource.SchemaRequest{}, &resourceResp) + + resp.Schema = frameworkDatasourceSchemaFromFrameworkResourceSchema(resourceResp.Schema) +} + +func (d *ApiKeyDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var data *ApiKeyModel + resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) + log.Printf("[INFO] Reading ApiKey") + + if resp.Diagnostics.HasError() { + return + } + + //Get refreshed Action value from Coralogix + id := data.ID.ValueString() + log.Printf("[INFO] Reading ApiKey: %s", id) + getApiKey := &apikeys.GetApiKeyRequest{ + KeyId: id, + } + + getApiKeyResponse, err := d.client.GetApiKey(ctx, getApiKey) + if err != nil { + log.Printf("[ERROR] Received error: %#v", err) + if status.Code(err) == codes.NotFound { + data.ID = types.StringNull() + resp.Diagnostics.AddWarning( + fmt.Sprintf("Action %q is in state, but no longer exists in Coralogix backend", id), + fmt.Sprintf("%s will be recreated when you apply", id), + ) + } else { + resp.Diagnostics.AddError( + "Error reading Action", + formatRpcErrors(err, getActionURL, protojson.Format(getApiKey)), + ) + } + return + } + log.Printf("[INFO] Received Action: %s", protojson.Format(getApiKeyResponse)) + + if getApiKeyResponse.KeyInfo.Hashed { + resp.Diagnostics.AddError( + "Error reading Action", + "Reading an hashed key is impossible", + ) + return + } + response, diags := flattenGetApiKeyResponse(ctx, &id, getApiKeyResponse, getApiKeyResponse.Value) + if diags.HasError() { + resp.Diagnostics.Append(diags...) + return + } + + // Save data into Terraform state + resp.Diagnostics.Append(resp.State.Set(ctx, &response)...) +} diff --git a/coralogix/data_source_coralogix_api_key_test.go b/coralogix/data_source_coralogix_api_key_test.go new file mode 100644 index 00000000..0da7b674 --- /dev/null +++ b/coralogix/data_source_coralogix_api_key_test.go @@ -0,0 +1,35 @@ +package coralogix + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +var apiKeyDataSourceName = "data." + apiKeyResourceName + +func TestAccCoralogixDataSourceApiKey(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testApiKeyResource() + + testApiKeyResource_read(), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(apiKeyDataSourceName, "name", "Test Key 3"), + resource.TestCheckResourceAttr(apiKeyDataSourceName, "owner.team_id", targetTeam), + resource.TestCheckResourceAttr(apiKeyDataSourceName, "active", "true"), + resource.TestCheckResourceAttr(apiKeyDataSourceName, "hashed", "false"), + ), + }, + }, + }) +} + +func testApiKeyResource_read() string { + return `data "coralogix_api_key" "test" { + id = coralogix_api_key.test.id +} +` +} diff --git a/coralogix/provider.go b/coralogix/provider.go index 3236331b..6c357a2d 100644 --- a/coralogix/provider.go +++ b/coralogix/provider.go @@ -335,6 +335,7 @@ func (p *coralogixProvider) DataSources(context.Context) []func() datasource.Dat NewAlertsSchedulerDataSource, NewSLODataSource, NewDashboardsFoldersDataSource, + NewApiKeyDataSource, } } @@ -353,6 +354,7 @@ func (p *coralogixProvider) Resources(context.Context) []func() resource.Resourc NewArchiveLogsResource, NewAlertsSchedulerResource, NewTeamResource, + NewApiKeyResource, NewMovingQuotaResource, NewSLOResource, NewDashboardsFolderResource, diff --git a/coralogix/provider_test.go b/coralogix/provider_test.go index c1e35730..2e9b29db 100644 --- a/coralogix/provider_test.go +++ b/coralogix/provider_test.go @@ -47,6 +47,9 @@ func testAccPreCheck(t *testing.T) { t.Fatalf("CORALOGIX_ENV must be set for acceptance tests") } + if os.Getenv("CORALOGIX_ORG_KEY") == "" { + t.Fatalf("CORALOGIX_ORG_KEY must be set for acceptance tests") + } //diags := testAccProvider.Configure(ctx, terraform.NewResourceConfigRaw(nil)) //if diags.HasError() { // t.Fatal(diags[0].Summary) diff --git a/coralogix/resource_coralogix_api_key.go b/coralogix/resource_coralogix_api_key.go new file mode 100644 index 00000000..ab3f1f5b --- /dev/null +++ b/coralogix/resource_coralogix_api_key.go @@ -0,0 +1,440 @@ +package coralogix + +import ( + "context" + "fmt" + "github.com/hashicorp/terraform-plugin-framework-validators/int64validator" + "github.com/hashicorp/terraform-plugin-framework-validators/setvalidator" + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/encoding/protojson" + "log" + "reflect" + "terraform-provider-coralogix/coralogix/clientset" + apikeys "terraform-provider-coralogix/coralogix/clientset/grpc/apikeys" +) + +var ( + getApiKeyPath = "com.coralogixapis.aaa.apikeys.v2.ApiKeysService/GetApiKey" + createApiKeyPath = "com.coralogixapis.aaa.apikeys.v2.ApiKeysService/CreateApiKey" + deleteApiKeyPath = "com.coralogixapis.aaa.apikeys.v2.ApiKeysService/DeleteApiKey" + updateApiKeyPath = "com.coralogixapis.aaa.apikeys.v2.ApiKeysService/UpdateApiKey" +) + +func NewApiKeyResource() resource.Resource { + return &ApiKeyResource{} +} + +type ApiKeyResource struct { + client *clientset.ApikeysClient +} + +func (r *ApiKeyResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_api_key" + +} + +func (r *ApiKeyResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { + if req.ProviderData == nil { + return + } + + clientSet, ok := req.ProviderData.(*clientset.ClientSet) + if !ok { + resp.Diagnostics.AddError( + "Unexpected Resource Configure Type", + fmt.Sprintf("Expected *clientset.ClientSet, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + return + } + + r.client = clientSet.ApiKeys() +} + +func (r *ApiKeyResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { + resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) +} + +func (r *ApiKeyResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = schema.Schema{ + Version: 0, + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + MarkdownDescription: "ApiKey ID.", + }, + "name": schema.StringAttribute{ + Required: true, + MarkdownDescription: "Api Key name.", + }, + "value": schema.StringAttribute{ + Computed: true, + Sensitive: true, + MarkdownDescription: "Api Key value.", + }, + "owner": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{ + "team_id": schema.Int64Attribute{ + Optional: true, + Validators: []validator.Int64{ + int64validator.ExactlyOneOf( + path.MatchRelative().AtParent().AtName("user_id"), + ), + }, + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.RequiresReplace(), + }, + }, + "user_id": schema.StringAttribute{ + Optional: true, + Validators: []validator.String{ + stringvalidator.ExactlyOneOf( + path.MatchRelative().AtParent().AtName("team_id"), + ), + }, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + }, + Required: true, + MarkdownDescription: "Api Key Owner.It can either be a team_id or a user_id ", + }, + + "active": schema.BoolAttribute{ + Computed: true, + Optional: true, + Default: booldefault.StaticBool(true), + MarkdownDescription: "Api Key Is Active.", + }, + "hashed": schema.BoolAttribute{ + Computed: true, + Optional: true, + Default: booldefault.StaticBool(false), + MarkdownDescription: "Api Key Is Hashed.", + }, + "roles": schema.SetAttribute{ + Required: true, + ElementType: types.StringType, + MarkdownDescription: "Api Key Roles", + Validators: []validator.Set{ + setvalidator.SizeAtLeast(1), + }, + }, + }, + MarkdownDescription: "Coralogix Api keys.", + } +} + +type ApiKeyModel struct { + ID types.String `tfsdk:"id"` + Name types.String `tfsdk:"name"` + Owner *Owner `tfsdk:"owner"` + Active types.Bool `tfsdk:"active"` + Hashed types.Bool `tfsdk:"hashed"` + Roles types.Set `tfsdk:"roles"` + Value types.String `tfsdk:"value"` +} + +type Owner struct { + UserId types.String `tfsdk:"user_id"` + TeamId types.Int64 `tfsdk:"team_id"` +} + +func (r *ApiKeyResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + var desiredState *ApiKeyModel + diags := req.Plan.Get(ctx, &desiredState) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + createApiKeyRequest, diags := makeCreateApiKeyRequest(ctx, desiredState) + if diags.HasError() { + resp.Diagnostics = diags + return + } + log.Printf("[INFO] Creating new ApiKey: %s", protojson.Format(createApiKeyRequest)) + createApiKeyResp, err := r.client.CreateApiKey(ctx, createApiKeyRequest) + if err != nil { + log.Printf("[ERROR] Received error: %s", err.Error()) + if status.Code(err) == codes.PermissionDenied || status.Code(err) == codes.Unauthenticated { + resp.Diagnostics.AddError( + "Error creating Api Key", + fmt.Sprintf("permission denied for url - %s\ncheck your org-key and permissions", createApiKeyPath), + ) + } else { + resp.Diagnostics.AddError( + "Error creating Api Key", + formatRpcErrors(err, createApiKeyPath, protojson.Format(createApiKeyRequest)), + ) + } + return + } + log.Printf("[INFO] Create api key with ID: %s", createApiKeyResp.KeyId) + + currentKeyId := createApiKeyResp.GetKeyId() + key, diags := r.getKeyInfo(ctx, ¤tKeyId, &createApiKeyResp.Value, diags) + if diags.HasError() { + resp.Diagnostics.Append(diags...) + return + } + + // Set state to fully populated data + diags = resp.State.Set(ctx, key) + resp.Diagnostics.Append(diags...) +} + +func (r *ApiKeyResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + var currentState *ApiKeyModel + diags := req.State.Get(ctx, ¤tState) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + key, diags := r.getKeyInfo(ctx, currentState.ID.ValueStringPointer(), currentState.Value.ValueStringPointer(), diags) + + if diags.HasError() { + resp.Diagnostics.Append(diags...) + return + } + // Set state to fully populated data + diags = resp.State.Set(ctx, key) + resp.Diagnostics.Append(diags...) +} + +func (r *ApiKeyResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + var currentState, desiredState *ApiKeyModel + diags := req.State.Get(ctx, ¤tState) + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + diags = req.Plan.Get(ctx, &desiredState) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + id := currentState.ID.ValueString() + + var updateApiKeyRequest = apikeys.UpdateApiKeyRequest{ + KeyId: id, + } + if currentState.Name.ValueString() != desiredState.Name.ValueString() { + updateApiKeyRequest.NewName = desiredState.Name.ValueStringPointer() + } + if !reflect.DeepEqual(currentState.Roles.Elements(), desiredState.Roles.Elements()) { + roles, diags := typeStringSliceToStringSlice(ctx, desiredState.Roles.Elements()) + if diags.HasError() { + resp.Diagnostics.Append(diags...) + return + } + updateApiKeyRequest.Roles = &apikeys.UpdateApiKeyRequest_Roles{ + Roles: roles, + } + } + + if currentState.Active.ValueBool() != desiredState.Active.ValueBool() { + updateApiKeyRequest.IsActive = desiredState.Active.ValueBoolPointer() + } + + if currentState.Hashed.ValueBool() != desiredState.Hashed.ValueBool() { + resp.Diagnostics.AddError( + "Error updating ApiKey", + "ApiKey hashing can not be updated.", + ) + return + } + log.Printf("[INFO] Updating ApiKey %s to %s", id, protojson.Format(&updateApiKeyRequest)) + + _, err := r.client.UpdateApiKey(ctx, &updateApiKeyRequest) + if err != nil { + log.Printf("[ERROR] Received error: %s", err.Error()) + if status.Code(err) == codes.PermissionDenied || status.Code(err) == codes.Unauthenticated { + resp.Diagnostics.AddError( + "Error updating Api Key", + fmt.Sprintf("permission denied for url - %s\ncheck your org-key and permissions", updateApiKeyPath), + ) + } else { + resp.Diagnostics.AddError( + "Error updating Api Key", + formatRpcErrors(err, updateApiKeyPath, protojson.Format(&updateApiKeyRequest)), + ) + } + return + } + + key, diags := r.getKeyInfo(ctx, &id, currentState.Value.ValueStringPointer(), diags) + if diags.HasError() { + return + } + + resp.Diagnostics.Append(resp.State.Set(ctx, key)...) +} + +func (r *ApiKeyResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + var currentState *ApiKeyModel + diags := req.State.Get(ctx, ¤tState) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + id := currentState.ID.ValueString() + deleteApiKeyRequest, diags := makeDeleteApi(&id) + _, err := r.client.DeleteApiKey(ctx, deleteApiKeyRequest) + + if err != nil { + log.Printf("[ERROR] Received error: %s", err.Error()) + if status.Code(err) == codes.PermissionDenied || status.Code(err) == codes.Unauthenticated { + resp.Diagnostics.AddError( + "Error getting Api Key", + fmt.Sprintf("permission denied for url - %s\ncheck your org-key and permissions", deleteApiKeyPath), + ) + } else { + resp.Diagnostics.AddError( + "Error getting Api Key", + formatRpcErrors(err, deleteApiKeyPath, protojson.Format(deleteApiKeyRequest)), + ) + } + return + } + + log.Printf("[INFO] Dashboard %s deleted", id) +} + +func (r *ApiKeyResource) getKeyInfo(ctx context.Context, id *string, keyValue *string, diags diag.Diagnostics) (*ApiKeyModel, diag.Diagnostics) { + getApiKeyRequest, diags := makeGetApiKeyRequest(id) + + getApiKeyResponse, err := r.client.GetApiKey(ctx, getApiKeyRequest) + if err != nil { + log.Printf("[ERROR] Received error: %s", err.Error()) + if status.Code(err) == codes.PermissionDenied || status.Code(err) == codes.Unauthenticated { + diags.AddError( + "Error getting Api Key", + fmt.Sprintf("permission denied for url - %s\ncheck your org-key and permissions", getApiKeyPath), + ) + } else { + diags.AddError( + "Error getting Api Key", + formatRpcErrors(err, getApiKeyPath, protojson.Format(getApiKeyRequest)), + ) + } + return nil, diags + } + key, diags := flattenGetApiKeyResponse(ctx, id, getApiKeyResponse, keyValue) + if diags.HasError() { + return nil, diags + } + return key, nil +} + +func makeGetApiKeyRequest(apiKeyId *string) (*apikeys.GetApiKeyRequest, diag.Diagnostics) { + return &apikeys.GetApiKeyRequest{ + KeyId: *apiKeyId, + }, nil +} + +func makeDeleteApi(apiKeyId *string) (*apikeys.DeleteApiKeyRequest, diag.Diagnostics) { + return &apikeys.DeleteApiKeyRequest{ + KeyId: *apiKeyId, + }, nil +} + +func flattenGetApiKeyResponse(ctx context.Context, apiKeyId *string, response *apikeys.GetApiKeyResponse, keyValue *string) (*ApiKeyModel, diag.Diagnostics) { + var diags diag.Diagnostics + + roles, diags := types.SetValueFrom(ctx, types.StringType, response.KeyInfo.Roles) + if diags.HasError() { + return nil, diags + } + + var key types.String + if response.KeyInfo.Hashed && keyValue == nil { + diags.AddError("Key argument is require", "Key value is required") + return nil, diags + } else if !response.KeyInfo.Hashed { + key = types.StringValue(response.GetValue()) + } else { + key = types.StringValue(*keyValue) + } + + owner := flattenOwner(response.KeyInfo.Owner) + return &ApiKeyModel{ + ID: types.StringValue(*apiKeyId), + Value: key, + Name: types.StringValue(response.KeyInfo.Name), + Active: types.BoolValue(response.KeyInfo.Active), + Hashed: types.BoolValue(response.KeyInfo.Hashed), + Roles: roles, + Owner: &owner, + }, nil +} + +func makeCreateApiKeyRequest(ctx context.Context, apiKeyModel *ApiKeyModel) (*apikeys.CreateApiKeyRequest, diag.Diagnostics) { + roles, diags := typeStringSliceToStringSlice(ctx, apiKeyModel.Roles.Elements()) + + if diags.HasError() { + return nil, diags + } + + owner := extractOwner(apiKeyModel) + + return &apikeys.CreateApiKeyRequest{ + KeyInfo: &apikeys.KeyInfo{ + Name: apiKeyModel.Name.ValueString(), + Owner: &owner, + Active: apiKeyModel.Active.ValueBool(), + Hashed: apiKeyModel.Hashed.ValueBool(), + Roles: roles, + }, + }, nil +} + +func extractOwner(keyModel *ApiKeyModel) apikeys.Owner { + if keyModel.Owner.UserId.ValueString() != "" { + return apikeys.Owner{ + Owner: &apikeys.Owner_UserId{ + UserId: keyModel.Owner.UserId.ValueString(), + }, + } + } else { + return apikeys.Owner{ + Owner: &apikeys.Owner_TeamId{ + TeamId: uint32(keyModel.Owner.TeamId.ValueInt64()), + }, + } + } +} + +func flattenOwner(owner *apikeys.Owner) Owner { + var user types.String + userId := owner.GetUserId() + if userId == "" { + user = types.StringNull() + } else { + user = types.StringValue(userId) + } + + return Owner{ + UserId: user, + TeamId: types.Int64Value(int64(owner.GetTeamId())), + } + +} diff --git a/coralogix/resource_coralogix_api_key_test.go b/coralogix/resource_coralogix_api_key_test.go new file mode 100644 index 00000000..6d565ea1 --- /dev/null +++ b/coralogix/resource_coralogix_api_key_test.go @@ -0,0 +1,71 @@ +package coralogix + +import ( + "strings" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +var ( + apiKeyResourceName = "coralogix_api_key.test" + targetTeam = "4013254" +) + +func TestApiKeyResource(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testApiKeyResource(), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(apiKeyResourceName, "name", "Test Key 3"), + resource.TestCheckResourceAttr(apiKeyResourceName, "owner.team_id", targetTeam), + resource.TestCheckResourceAttr(apiKeyResourceName, "active", "true"), + resource.TestCheckResourceAttr(apiKeyResourceName, "hashed", "false"), + ), + }, + { + ResourceName: apiKeyResourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: updateApiKeyResource(), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(apiKeyResourceName, "name", "Test Key 5"), + resource.TestCheckResourceAttr(apiKeyResourceName, "owner.team_id", targetTeam), + resource.TestCheckResourceAttr(apiKeyResourceName, "active", "false"), + resource.TestCheckResourceAttr(apiKeyResourceName, "hashed", "false"), + ), + }, + }, + }) +} + +func testApiKeyResource() string { + return strings.Replace(`resource "coralogix_api_key" "test" { + name = "Test Key 3" + owner = { + team_id : "" + } + active = true + hashed = false + roles = ["SCIM"] +} +`, "", targetTeam, 1) +} + +func updateApiKeyResource() string { + return strings.Replace(`resource "coralogix_api_key" "test" { + name = "Test Key 5" + owner = { + team_id : "" + } + active = false + hashed = false + roles = ["SCIM"] +} +`, "", targetTeam, 1) +} diff --git a/docs/data-sources/api_key.md b/docs/data-sources/api_key.md new file mode 100644 index 00000000..4d6e60f5 --- /dev/null +++ b/docs/data-sources/api_key.md @@ -0,0 +1,37 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "coralogix_api_key Data Source - terraform-provider-coralogix" +subcategory: "" +description: |- + Coralogix Api keys. +--- + +# coralogix_api_key (Data Source) + +Coralogix Api keys. + + + + +## Schema + +### Required + +- `id` (String) ApiKey ID. + +### Read-Only + +- `active` (Boolean) Api Key Is Active. +- `hashed` (Boolean) Api Key Is Hashed. +- `name` (String) Api Key name. +- `owner` (Attributes) Api Key Owner.It can either be a team_id or a user_id (see [below for nested schema](#nestedatt--owner)) +- `roles` (Set of String) Api Key Roles +- `value` (String) Api Key value. + + +### Nested Schema for `owner` + +Read-Only: + +- `team_id` (Number) +- `user_id` (String) diff --git a/docs/resources/api_key.md b/docs/resources/api_key.md new file mode 100644 index 00000000..58577179 --- /dev/null +++ b/docs/resources/api_key.md @@ -0,0 +1,40 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "coralogix_api_key Resource - terraform-provider-coralogix" +subcategory: "" +description: |- + Coralogix Api keys. +--- + +# coralogix_api_key (Resource) + +Coralogix Api keys. + + + + +## Schema + +### Required + +- `name` (String) Api Key name. +- `owner` (Attributes) Api Key Owner.It can either be a team_id or a user_id (see [below for nested schema](#nestedatt--owner)) +- `roles` (Set of String) Api Key Roles + +### Optional + +- `active` (Boolean) Api Key Is Active. +- `hashed` (Boolean) Api Key Is Hashed. + +### Read-Only + +- `id` (String) ApiKey ID. +- `value` (String, Sensitive) Api Key value. + + +### Nested Schema for `owner` + +Optional: + +- `team_id` (Number) +- `user_id` (String) diff --git a/examples/apikeys/main.tf b/examples/apikeys/main.tf new file mode 100644 index 00000000..ad709b92 --- /dev/null +++ b/examples/apikeys/main.tf @@ -0,0 +1,28 @@ +terraform { + required_providers { + coralogix = { + version = "~> 1.10" + source = "coralogix/coralogix" + } + } +} + +provider "coralogix" { + org_key = "" + domain = "" +} + +resource "coralogix_api_key" "example" { + name = "My SCIM KEY" + owner = { + team_id : "" + } + active = false + hashed = false + roles = ["SCIM"] +} + +data "coralogix_api_key" "same_key_by_id" { + id = coralogix_api_key.example.id +} +