Skip to content

Commit d5decd5

Browse files
authored
Merge pull request #27 from kubescape/command-crd
command crd
2 parents 00ebf35 + 00ac53f commit d5decd5

File tree

7 files changed

+141
-1
lines changed

7 files changed

+141
-1
lines changed

pkg/command/commands.go

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package command
2+
3+
type OperatorCommandType string
4+
5+
const (
6+
OperatorCommandAppNameLabelKey string = "kubescape.io/app-name" // holds the app name label, which should execute the command (optional)
7+
OperatorCommandNodeNameLabelKey string = "kubescape.io/node-name" // holds the node name label, app running on this node name should execute the command (optional)
8+
9+
// command types will be defined here
10+
OperatorCommandTypeRuntimeResponse OperatorCommandType = "RuntimeResponse"
11+
)
12+
13+
// ResponseCommand
14+
type ResponseAction string
15+
16+
const (
17+
ResponseActionKill ResponseAction = "Kill"
18+
ResponseActionStop ResponseAction = "Stop"
19+
ResponseActionPause ResponseAction = "Pause"
20+
ResponseActionUnpause ResponseAction = "Unpause"
21+
)
22+
23+
type ResponseCommand struct {
24+
Namespace string `json:"namespace,omitempty"`
25+
PodName string `json:"podName,omitempty"`
26+
ContainerName string `json:"containerName,omitempty"`
27+
Pid *uint32 `json:"pid,omitempty"`
28+
Action ResponseAction `json:"action,omitempty"`
29+
}

pkg/command/types/api.go

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package types
2+
3+
const (
4+
OperatorCommandGroup string = "kubescape.io"
5+
OperatorCommandKind string = "OperatorCommand"
6+
OperatorCommandPlural string = "operatorcommands"
7+
)

pkg/command/types/v1alpha1/README.md

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# OperatorCommand
2+
3+
The OperatorCommand CRD is designed to enable the execution of various actions within the cluster and reporting their status back to the backend. This CRD serves as a central mechanism for triggering and managing actions, replacing the functionality previously provided by the gateway and kollector.
4+
5+
How it Works
6+
7+
1. Creation: The backend creates a Command CRD instance, specifying the desired action and any necessary parameters for the action.
8+
2. Synchronization: The Synchronizer, responsible for two-way communication, receives the Command CRD from the backend and saves it in the cluster.
9+
3. Execution: The designated component in the cluster, identifies the new command via a watcher on the Kubernetes API, processes the Command CRD and performs the requested action within the cluster.
10+
4. Status Reporting: Upon completion, the component updates the command CRD resource with the status of the action, providing information about success or failure, any relevant details, and potentially updating the Command CRD. The synchronizer, watching over the command CRD, will send it back to the backend for further processing.

pkg/command/types/v1alpha1/api.go

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package v1alpha1
2+
3+
import (
4+
"github.com/kubescape/backend/pkg/command/types"
5+
"k8s.io/apimachinery/pkg/runtime/schema"
6+
)
7+
8+
const (
9+
OperatorCommandVersion string = "v1alpha1"
10+
)
11+
12+
var SchemaGroupVersionResource = schema.GroupVersionResource{
13+
Group: types.OperatorCommandGroup,
14+
Version: OperatorCommandVersion,
15+
Resource: types.OperatorCommandPlural,
16+
}

pkg/command/types/v1alpha1/types.go

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package v1alpha1
2+
3+
import (
4+
"time"
5+
6+
"github.com/armosec/armoapi-go/identifiers"
7+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
8+
)
9+
10+
type OperatorCommandList struct {
11+
metav1.TypeMeta `json:",inline"`
12+
metav1.ListMeta `json:"metadata,omitempty"`
13+
14+
Items []OperatorCommand `json:"items"`
15+
}
16+
17+
type OperatorCommand struct {
18+
metav1.TypeMeta `json:",inline"`
19+
metav1.ObjectMeta `json:"metadata,omitempty"`
20+
21+
Spec OperatorCommandSpec `json:"spec,omitempty"`
22+
Status OperatorCommandStatus `json:"status,omitempty"`
23+
}
24+
25+
type OperatorCommandSpec struct {
26+
GUID string `json:"guid"` // GUID is a unique identifier for the command
27+
CommandType string `json:"commandType"` // CommandType is the type of the command
28+
CommandVersion string `json:"commandVersion,omitempty"` // CommandVersion is the version of the command
29+
Designators []identifiers.PortalDesignator `json:"designators,omitempty"` // Designators are the designators for the command
30+
Body []byte `json:"body,omitempty"` // Body is the body of the command
31+
TTL time.Duration `json:"ttl,omitempty"` // TTL is the time to live for the command
32+
Args map[string]interface{} `json:"args,omitempty"` // Args are the arguments for the command
33+
CommandIndex *int `json:"commandIndex,omitempty"` // CommandIndex is the index of the command in the sequence
34+
CommandCount *int `json:"commandCount,omitempty"` // CommandCount is the total number of commands in the sequence
35+
}
36+
37+
type OperatorCommandStatus struct {
38+
Started bool `json:"started"` // Started indicates if the command has started
39+
StartedAt *metav1.Time `json:"startedAt,omitempty"` // StartedAt is the time at which the command was started
40+
Completed bool `json:"completed"` // Completed indicates if the command has completed
41+
CompletedAt *metav1.Time `json:"completedAt,omitempty"` // CompletedAt is the time at which the command was completed
42+
Executer string `json:"executer,omitempty"` // Executer is the entity that executed the command
43+
Error *OperatorCommandStatusError `json:"error,omitempty"` // Error is the error that occurred during the execution of the command (if any)
44+
}
45+
46+
type OperatorCommandStatusError struct {
47+
Reason string `json:"reason,omitempty"` // reason for the error (optional)
48+
Message string `json:"message,omitempty"` // error message (optional)
49+
ErrorCode int `json:"errorCode,omitempty"` // error code (optional)
50+
}

pkg/command/utils/utils.go

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package utils
2+
3+
import (
4+
"bytes"
5+
"encoding/json"
6+
)
7+
8+
func EncodeCommandBody[T any](data T) ([]byte, error) {
9+
buffer := bytes.Buffer{}
10+
encoder := json.NewEncoder(&buffer)
11+
err := encoder.Encode(data)
12+
if err != nil {
13+
return nil, err
14+
}
15+
return buffer.Bytes(), nil
16+
}
17+
18+
func DecodeCommandBody[T any](b []byte) (T, error) {
19+
buffer := bytes.Buffer{}
20+
buffer.Write(b)
21+
decoder := json.NewDecoder(&buffer)
22+
var data T
23+
err := decoder.Decode(&data)
24+
if err != nil {
25+
return data, err
26+
}
27+
return data, nil
28+
}

pkg/versioncheck/versioncheck_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ func TestVersionCheckHandler_getLatestVersion(t *testing.T) {
8787
},
8888
want: &VersionCheckResponse{
8989
Client: "kubescape",
90-
ClientUpdate: "v3.0.9",
90+
ClientUpdate: "v3.0.15",
9191
},
9292
wantErr: false,
9393
},

0 commit comments

Comments
 (0)