Skip to content

Commit

Permalink
issue-2732: add config flag for buttons
Browse files Browse the repository at this point in the history
  • Loading branch information
vladstepanyuk committed Jan 10, 2025
1 parent cdcd0f1 commit 124edf0
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 29 deletions.
7 changes: 7 additions & 0 deletions cloud/blockstore/config/storage.proto
Original file line number Diff line number Diff line change
Expand Up @@ -1083,4 +1083,11 @@ message TStorageServiceConfig
// percentage, then the rejection of such agents does not occur - we assume
// a connectivity failure in the cluster.
optional double DiskRegistryInitialAgentRejectionThreshold = 396;

// Enable buttons for agent/device state changing.
optional bool EnableToChangeStatesFromMonpage = 397;

// Enable buttons for agent/device state changing,
// when they in unavailable/error state.
optional bool EnableToChangeErrorStatesFromMonpage = 398;
}
2 changes: 2 additions & 0 deletions cloud/blockstore/libs/storage/core/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,8 @@ TDuration MSeconds(ui32 value)
xxx(EncryptionAtRestForDiskRegistryBasedDisksEnabled, bool, false )\
xxx(DisableFullPlacementGroupCountCalculation, bool, false )\
xxx(DiskRegistryInitialAgentRejectionThreshold, double, 50 )\
xxx(EnableToChangeStatesFromMonpage, bool, false )\
xxx(EnableToChangeErrorStatesFromMonpage, bool, false )\
// BLOCKSTORE_STORAGE_CONFIG_RW

#define BLOCKSTORE_STORAGE_CONFIG(xxx) \
Expand Down
2 changes: 2 additions & 0 deletions cloud/blockstore/libs/storage/core/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,8 @@ class TStorageConfig

[[nodiscard]] bool GetDisableFullPlacementGroupCountCalculation() const;
[[nodiscard]] double GetDiskRegistryInitialAgentRejectionThreshold() const;
[[nodiscard]] bool GetEnableToChangeStatesFromMonpage() const;
[[nodiscard]] bool GetEnableToChangeErrorStatesFromMonpage() const;
};

ui64 GetAllocationUnit(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ void TChangeAgentStateActor::HandlePoisonPill(
const TActorContext& ctx)
{
Y_UNUSED(ev);
ReplyAndDie(ctx, MakeError(E_REJECTED, "Tablet is dead"));
ReplyAndDie(ctx, MakeTabletIsDeadError(E_REJECTED, __LOCATION__));
}

void TChangeAgentStateActor::HandleChangeAgentStateResponse(
Expand Down Expand Up @@ -170,6 +170,11 @@ void TDiskRegistryActor::HandleHttpInfo_ChangeAgentState(
const TCgiParameters& params,
TRequestInfoPtr requestInfo)
{
if (!Config->GetEnableToChangeStatesFromMonpage()) {
RejectHttpRequest(ctx, *requestInfo, "Can't change state from monpage");
return;
}

const auto& newStateRaw = params.Get("NewState");
const auto& agentId = params.Get("AgentID");

Expand All @@ -189,7 +194,7 @@ void TDiskRegistryActor::HandleHttpInfo_ChangeAgentState(
return;
}

static const THashSet<NProto::EAgentState> NewStateWhiteList = {
static const THashSet<NProto::EAgentState> NewStateWhiteList{
NProto::EAgentState::AGENT_STATE_ONLINE,
NProto::EAgentState::AGENT_STATE_WARNING,
};
Expand All @@ -199,6 +204,35 @@ void TDiskRegistryActor::HandleHttpInfo_ChangeAgentState(
return;
}

const auto agentState = State->GetAgentState(agentId);
if (agentState.Empty()) {
RejectHttpRequest(ctx, *requestInfo, "Unknown agent");
return;
}

static const auto OldStateWhiteList = [&]()
{
THashSet<NProto::EAgentState> whitelist = {
NProto::EAgentState::AGENT_STATE_ONLINE,
NProto::EAgentState::AGENT_STATE_WARNING,
};

if (Config->GetEnableToChangeErrorStatesFromMonpage()) {
whitelist.emplace(NProto::EAgentState::AGENT_STATE_UNAVAILABLE);
}

return whitelist;
}();


if (!OldStateWhiteList.contains(*agentState.Get())) {
RejectHttpRequest(
ctx,
*requestInfo,
"Can't change agent state from " +
EAgentState_Name(*agentState.Get()));
}

LOG_INFO(
ctx,
TBlockStoreComponents::DISK_REGISTRY,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ void TChangeDeviceStateActor::HandlePoisonPill(
const TActorContext& ctx)
{
Y_UNUSED(ev);
ReplyAndDie(ctx, MakeError(E_REJECTED, "Tablet is dead"));
ReplyAndDie(ctx, MakeTabletIsDeadError(E_REJECTED, __LOCATION__));
}

void TChangeDeviceStateActor::HandleChangeDeviceStateResponse(
Expand Down Expand Up @@ -171,15 +171,17 @@ void TDiskRegistryActor::HandleHttpInfo_ChangeDeviseState(
const TCgiParameters& params,
TRequestInfoPtr requestInfo)
{
if (!Config->GetEnableToChangeStatesFromMonpage()) {
RejectHttpRequest(ctx, *requestInfo, "Can't change state from monpage");
return;
}
const auto& newStateRaw = params.Get("NewState");
const auto& deviceUUID = params.Get("DeviceUUID");


if (!newStateRaw) {
RejectHttpRequest(ctx, *requestInfo, "No new state is given");
return;
}

if (!deviceUUID) {
RejectHttpRequest(ctx, *requestInfo, "No device id is given");
return;
Expand All @@ -195,18 +197,32 @@ void TDiskRegistryActor::HandleHttpInfo_ChangeDeviseState(
NProto::EDeviceState::DEVICE_STATE_ONLINE,
NProto::EDeviceState::DEVICE_STATE_WARNING,
};

if (!NewStateWhiteList.contains(newState)) {
RejectHttpRequest(ctx, *requestInfo, "Invalid new state");
return;
}

static const auto OldStateWhiteList = [&]()
{
THashSet<NProto::EDeviceState> whitelist = {
NProto::EDeviceState::DEVICE_STATE_ONLINE,
NProto::EDeviceState::DEVICE_STATE_WARNING,
};

if (Config->GetEnableToChangeErrorStatesFromMonpage()) {
whitelist.emplace(NProto::EDeviceState::DEVICE_STATE_ERROR);
}

return whitelist;
}();

const auto& device = State->GetDevice(deviceUUID);
if (device.GetState() == NProto::DEVICE_STATE_ERROR) {
if (!OldStateWhiteList.contains(device.GetState())) {
RejectHttpRequest(
ctx,
*requestInfo,
"Can't change state of device in ERROR state");
"Can't change device state from " +
EDeviceState_Name(device.GetState()));
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -512,13 +512,17 @@ void TDiskRegistryActor::RenderDeviceHtmlInfo(
}
DIV() { out << "State Message: " << device.GetStateMessage(); }

if (device.GetState() != NProto::EDeviceState::DEVICE_STATE_ERROR) {
DIV()
if (Config->GetEnableToChangeStatesFromMonpage()) {
if (device.GetState() != NProto::EDeviceState::DEVICE_STATE_ERROR ||
Config->GetEnableToChangeErrorStatesFromMonpage())
{
BuildChangeDeviceStateButton(
out,
TabletID(),
device.GetDeviceUUID());
DIV()
{
BuildChangeDeviceStateButton(
out,
TabletID(),
device.GetDeviceUUID());
}
}
}

Expand Down Expand Up @@ -593,7 +597,18 @@ void TDiskRegistryActor::RenderAgentHtmlInfo(
<< TInstant::MicroSeconds(agent->GetStateTs());
}
DIV() {
BuildChangeAgentStateButton(out, TabletID(), agent->GetAgentId());
if (Config->GetEnableToChangeStatesFromMonpage()) {
if (agent->GetState() !=
NProto::EAgentState::AGENT_STATE_UNAVAILABLE ||
Config->GetEnableToChangeErrorStatesFromMonpage())
{
BuildChangeAgentStateButton(
out,
TabletID(),
agent->GetAgentId());
}
}

}
DIV() { out << "State Message: " << agent->GetStateMessage(); }
DIV() {
Expand Down
17 changes: 3 additions & 14 deletions cloud/blockstore/tests/monitoring/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -436,20 +436,6 @@ def check_change_device_state(self):
self.session, self.base_url,
self.dr_id, params, "<h2>Invalid new state</h2>")

self.client.change_device_state("FileDevice-1", "2")

params = {
"action": "changeDeviceState",
"NewState" : "DEVICE_STATE_ONLINE",
"DeviceUUID": "FileDevice-1"
}

check_tablet_post_redirect(
self.session, self.base_url,
self.dr_id, params, "<h2>Can't change state of device in ERROR state</h2>")

self.client.change_device_state("FileDevice-1", "0")

params = {
"action": "changeDeviceState",
"NewState" : "DEVICE_STATE_WARNING",
Expand Down Expand Up @@ -879,6 +865,9 @@ def __run_test(test_case):
storage.NonReplicatedAgentMaxTimeout = 3000
storage.NonReplicatedDiskRecyclingPeriod = 5000

storage.EnableToChangeStatesFromMonpage = True
storage.EnableToChangeErrorStatesFromMonpage = True

nbs = Nbs(
kikimr_port,
configurator.domains_txt,
Expand Down

0 comments on commit 124edf0

Please sign in to comment.