Skip to content

Commit

Permalink
feat: return the production enclave information if present via GetEnc…
Browse files Browse the repository at this point in the history
…laves API (#1395)

This PR returns whether the enclave is running in production mode via
GetEnclaves() api.

Sample Response for test enclave:
{
           "enclaveUuid": "1a8396beea6a464d83ee27900eea012e",
            "name": "vibrant-volcano",
            "shortenedUuid": "1a8396beea6a",
            "containersStatus": "EnclaveContainersStatus_RUNNING",
            "apiContainerStatus": "EnclaveAPIContainerStatus_RUNNING",
            ...
}

Sample Response for prod enclave:
{
             "enclaveUuid": "1a8396beea6a464d83ee27900eea012e",
            "name": "vibrant-volcano",
            "shortenedUuid": "1a8396beea6a",
            "containersStatus": "EnclaveContainersStatus_RUNNING",
            "apiContainerStatus": "EnclaveAPIContainerStatus_RUNNING",
            "mode":"PRODUCTION"
}
  • Loading branch information
Peeeekay committed Sep 26, 2023
1 parent 993a7a3 commit ef22820
Show file tree
Hide file tree
Showing 13 changed files with 352 additions and 237 deletions.
464 changes: 238 additions & 226 deletions api/golang/engine/kurtosis_engine_rpc_api_bindings/engine_service.pb.go

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions api/protobuf/engine/engine_service.proto
Expand Up @@ -138,6 +138,8 @@ message EnclaveInfo {

//The enclave's creation time
google.protobuf.Timestamp creation_time = 8;

EnclaveMode mode =9;
}

message GetEnclavesResponse {
Expand Down
2 changes: 2 additions & 0 deletions api/rust/src/engine_api.rs
Expand Up @@ -91,6 +91,8 @@ pub struct EnclaveInfo {
/// The enclave's creation time
#[prost(message, optional, tag = "8")]
pub creation_time: ::core::option::Option<::prost_types::Timestamp>,
#[prost(enumeration = "EnclaveMode", tag = "9")]
pub mode: i32,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
Expand Down
Expand Up @@ -362,6 +362,11 @@ export declare class EnclaveInfo extends Message<EnclaveInfo> {
*/
creationTime?: Timestamp;

/**
* @generated from field: engine_api.EnclaveMode mode = 9;
*/
mode: EnclaveMode;

constructor(data?: PartialMessage<EnclaveInfo>);

static readonly runtime: typeof proto3;
Expand Down
Expand Up @@ -147,6 +147,7 @@ export const EnclaveInfo = proto3.makeMessageType(
{ no: 6, name: "api_container_info", kind: "message", T: EnclaveAPIContainerInfo },
{ no: 7, name: "api_container_host_machine_info", kind: "message", T: EnclaveAPIContainerHostMachineInfo },
{ no: 8, name: "creation_time", kind: "message", T: Timestamp },
{ no: 9, name: "mode", kind: "enum", T: proto3.getEnumType(EnclaveMode) },
],
);

Expand Down
Expand Up @@ -155,6 +155,9 @@ export class EnclaveInfo extends jspb.Message {
hasCreationTime(): boolean;
clearCreationTime(): EnclaveInfo;

getMode(): EnclaveMode;
setMode(value: EnclaveMode): EnclaveInfo;

serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): EnclaveInfo.AsObject;
static toObject(includeInstance: boolean, msg: EnclaveInfo): EnclaveInfo.AsObject;
Expand All @@ -173,6 +176,7 @@ export namespace EnclaveInfo {
apiContainerInfo?: EnclaveAPIContainerInfo.AsObject,
apiContainerHostMachineInfo?: EnclaveAPIContainerHostMachineInfo.AsObject,
creationTime?: google_protobuf_timestamp_pb.Timestamp.AsObject,
mode: EnclaveMode,
}
}

Expand Down
Expand Up @@ -1345,7 +1345,8 @@ proto.engine_api.EnclaveInfo.toObject = function(includeInstance, msg) {
apiContainerStatus: jspb.Message.getFieldWithDefault(msg, 5, 0),
apiContainerInfo: (f = msg.getApiContainerInfo()) && proto.engine_api.EnclaveAPIContainerInfo.toObject(includeInstance, f),
apiContainerHostMachineInfo: (f = msg.getApiContainerHostMachineInfo()) && proto.engine_api.EnclaveAPIContainerHostMachineInfo.toObject(includeInstance, f),
creationTime: (f = msg.getCreationTime()) && google_protobuf_timestamp_pb.Timestamp.toObject(includeInstance, f)
creationTime: (f = msg.getCreationTime()) && google_protobuf_timestamp_pb.Timestamp.toObject(includeInstance, f),
mode: jspb.Message.getFieldWithDefault(msg, 9, 0)
};

if (includeInstance) {
Expand Down Expand Up @@ -1417,6 +1418,10 @@ proto.engine_api.EnclaveInfo.deserializeBinaryFromReader = function(msg, reader)
reader.readMessage(value,google_protobuf_timestamp_pb.Timestamp.deserializeBinaryFromReader);
msg.setCreationTime(value);
break;
case 9:
var value = /** @type {!proto.engine_api.EnclaveMode} */ (reader.readEnum());
msg.setMode(value);
break;
default:
reader.skipField();
break;
Expand Down Expand Up @@ -1505,6 +1510,13 @@ proto.engine_api.EnclaveInfo.serializeBinaryToWriter = function(message, writer)
google_protobuf_timestamp_pb.Timestamp.serializeBinaryToWriter
);
}
f = message.getMode();
if (f !== 0.0) {
writer.writeEnum(
9,
f
);
}
};


Expand Down Expand Up @@ -1709,6 +1721,24 @@ proto.engine_api.EnclaveInfo.prototype.hasCreationTime = function() {
};


/**
* optional EnclaveMode mode = 9;
* @return {!proto.engine_api.EnclaveMode}
*/
proto.engine_api.EnclaveInfo.prototype.getMode = function() {
return /** @type {!proto.engine_api.EnclaveMode} */ (jspb.Message.getFieldWithDefault(this, 9, 0));
};


/**
* @param {!proto.engine_api.EnclaveMode} value
* @return {!proto.engine_api.EnclaveInfo} returns this
*/
proto.engine_api.EnclaveInfo.prototype.setMode = function(value) {
return jspb.Message.setProto3EnumField(this, 9, value);
};





Expand Down
Expand Up @@ -2,6 +2,7 @@ package docker_kurtosis_backend

import (
"context"
"encoding/json"
"github.com/docker/docker/api/types/volume"
"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/consts"
"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/shared_helpers"
Expand All @@ -24,6 +25,8 @@ const (

defaultHttpLogsCollectorPortNum = uint16(9712)
defaultTcpLogsCollectorPortNum = uint16(9713)

serializedArgs = "SERIALIZED_ARGS"
)

// TODO: MIGRATE THIS FOLDER TO USE STRUCTURE OF USER_SERVICE_FUNCTIONS MODULE
Expand Down Expand Up @@ -143,8 +146,8 @@ func (backend *DockerKurtosisBackend) CreateEnclave(ctx context.Context, enclave
}
}()

newEnclave := enclave.NewEnclave(enclaveUuid, enclaveName, enclave.EnclaveStatus_Empty, &creationTime)

// TODO: return production mode for create enclave request as well
newEnclave := enclave.NewEnclave(enclaveUuid, enclaveName, enclave.EnclaveStatus_Empty, &creationTime, false)
// TODO the logs collector has a random private ip address in the enclave network that must be tracked
if _, err := backend.CreateLogsCollectorForEnclave(ctx, enclaveUuid, defaultTcpLogsCollectorPortNum, defaultHttpLogsCollectorPortNum); err != nil {
return nil, stacktrace.Propagate(err, "An error occurred creating the logs collector with TCP port number '%v' and HTTP port number '%v'", defaultTcpLogsCollectorPortNum, defaultHttpLogsCollectorPortNum)
Expand Down Expand Up @@ -181,19 +184,42 @@ func (backend *DockerKurtosisBackend) GetEnclaves(

result := map[enclave.EnclaveUUID]*enclave.Enclave{}
for enclaveUuid, matchingNetworkInfo := range allMatchingNetworkInfo {

productionMode := false
creationTime, err := getEnclaveCreationTimeFromNetwork(matchingNetworkInfo.dockerNetwork)
if err != nil {
return nil, stacktrace.Propagate(err, "An error occurred getting the enclave's creation time value from enclave's Docker network '%+v'", matchingNetworkInfo.dockerNetwork)
}

enclaveName := getEnclaveNameFromNetwork(matchingNetworkInfo.dockerNetwork)

// This method just looks for api-container ( which only can be one) for an enclave
// and extracts out whether enclave is running on production mode
for _, container := range matchingNetworkInfo.containers {
labels := container.GetLabels()
containerType, ok := labels[label_key_consts.ContainerTypeDockerLabelKey.GetString()]
if !ok {
continue
}

if containerType == label_value_consts.APIContainerContainerTypeDockerLabelValue.GetString() {
envVars := container.GetEnvVars()
serializedArgsValue, found := envVars[serializedArgs]
if found {
productionMode, err = getProductionModeFromEnvVars(serializedArgsValue)
if err != nil {
return nil, stacktrace.Propagate(err, "Error occurred while parsing env vars from api container for %v", enclaveName)
}
}
break
}
}

result[enclaveUuid] = enclave.NewEnclave(
enclaveUuid,
enclaveName,
matchingNetworkInfo.enclaveStatus,
creationTime,
productionMode,
)
}

Expand Down Expand Up @@ -748,3 +774,18 @@ func getEnclaveNameFromNetwork(network *types.Network) string {

return enclaveNameStr
}

func getProductionModeFromEnvVars(serializedParamsStr string) (bool, error) {
type Args struct {
IsProductionEnclave bool `json:"isProductionEnclave"`
}

var args Args
paramsJsonBytes := []byte(serializedParamsStr)
if err := json.Unmarshal(paramsJsonBytes, &args); err != nil {
return false, stacktrace.Propagate(err, "An error occurred deserializing the args JSON '%v'", serializedParamsStr)
}

return args.IsProductionEnclave, nil

}
Expand Up @@ -1740,7 +1740,6 @@ func (manager *DockerManager) getContainersByFilterArgs(ctx context.Context, fil
if err != nil {
return nil, stacktrace.Propagate(err, "An error occurred creating new containers list from Docker containers list")
}

return containers, nil
}

Expand Down
Expand Up @@ -587,6 +587,7 @@ func getEnclaveObjectsFromKubernetesResources(
enclaveName,
enclaveStatus,
enclaveCreationTime,
false,
)

result[enclaveId] = enclaveObj
Expand Down
Expand Up @@ -5,14 +5,15 @@ import "time"
type EnclaveUUID string

type Enclave struct {
uuid EnclaveUUID
name string
status EnclaveStatus
creationTime *time.Time
uuid EnclaveUUID
name string
status EnclaveStatus
creationTime *time.Time
isProductionEnclave bool
}

func NewEnclave(id EnclaveUUID, name string, status EnclaveStatus, creationTime *time.Time) *Enclave {
return &Enclave{uuid: id, name: name, status: status, creationTime: creationTime}
func NewEnclave(id EnclaveUUID, name string, status EnclaveStatus, creationTime *time.Time, productionMode bool) *Enclave {
return &Enclave{uuid: id, name: name, status: status, creationTime: creationTime, isProductionEnclave: productionMode}
}

func (enclave *Enclave) GetUUID() EnclaveUUID {
Expand All @@ -30,3 +31,7 @@ func (enclave *Enclave) GetCreationTime() *time.Time {
func (enclave *Enclave) GetName() string {
return enclave.name
}

func (enclave *Enclave) IsProductionEnclave() bool {
return enclave.isProductionEnclave
}
7 changes: 7 additions & 0 deletions engine/server/engine/enclave_manager/enclave_creator.go
Expand Up @@ -120,6 +120,12 @@ func (creator *EnclaveCreator) CreateEnclave(
if apiContainer.GetBridgeNetworkIPAddress() != nil {
bridgeIpAddr = apiContainer.GetBridgeNetworkIPAddress().String()
}

mode := kurtosis_engine_rpc_api_bindings.EnclaveMode_TEST
if newEnclave.IsProductionEnclave() {
mode = kurtosis_engine_rpc_api_bindings.EnclaveMode_PRODUCTION
}

newEnclaveInfo := &kurtosis_engine_rpc_api_bindings.EnclaveInfo{
EnclaveUuid: newEnclaveUuidStr,
Name: newEnclave.GetName(),
Expand All @@ -134,6 +140,7 @@ func (creator *EnclaveCreator) CreateEnclave(
},
ApiContainerHostMachineInfo: apiContainerHostMachineInfo,
CreationTime: creationTimestamp,
Mode: mode,
}

// Everything started successfully, so the responsibility of deleting the enclave is now transferred to the caller
Expand Down
6 changes: 6 additions & 0 deletions engine/server/engine/enclave_manager/enclave_manager.go
Expand Up @@ -560,6 +560,11 @@ func getEnclaveInfoForEnclave(ctx context.Context, kurtosisBackend backend_inter

enclaveName := enclave.GetName()

mode := kurtosis_engine_rpc_api_bindings.EnclaveMode_TEST
if enclave.IsProductionEnclave() {
mode = kurtosis_engine_rpc_api_bindings.EnclaveMode_PRODUCTION
}

return &kurtosis_engine_rpc_api_bindings.EnclaveInfo{
EnclaveUuid: enclaveUuidStr,
ShortenedUuid: uuid_generator.ShortenedUUIDString(enclaveUuidStr),
Expand All @@ -569,6 +574,7 @@ func getEnclaveInfoForEnclave(ctx context.Context, kurtosisBackend backend_inter
ApiContainerInfo: apiContainerInfo,
ApiContainerHostMachineInfo: apiContainerHostMachineInfo,
CreationTime: creationTimestamp,
Mode: mode,
}, nil
}

Expand Down

0 comments on commit ef22820

Please sign in to comment.