Skip to content

Commit

Permalink
implement application filter
Browse files Browse the repository at this point in the history
Signed-off-by: Yuji Ito <llamerada.jp@gmail.com>
  • Loading branch information
llamerada-jp committed Nov 11, 2023
1 parent fb6e210 commit 8f33304
Show file tree
Hide file tree
Showing 8 changed files with 202 additions and 4 deletions.
5 changes: 3 additions & 2 deletions cmd/node/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,9 @@ func (na *nodeAgent) OnConnect(nodeName string, nodeType api.NodeType) error {
coreDriverManager := core.NewCoreDriverManager(na.cl)

// controllers
appFilter := controller.NewApplicationFilter(account)
accountCtrl := controller.NewAccountController(account, localNid, accountKvs)
containerCtrl := controller.NewContainerController(localNid, cri, podKvs, recordKVS, coreDriverManager)
containerCtrl := controller.NewContainerController(localNid, cri, appFilter, podKvs, recordKVS, coreDriverManager)
nodeCtrl := controller.NewNodeController(ctx, na.col, messaging, account, nodeName, nodeType)
podCtrl := controller.NewPodController(podKvs, messaging, localNid)
objectCtrl := threeController.NewObjectController(objectKVS, na.frontendDriver, threeMessaging, nodeCtrl, podCtrl)
Expand All @@ -160,7 +161,7 @@ func (na *nodeAgent) OnConnect(nodeName string, nodeType api.NodeType) error {
// handlers
cmh.InitMessagingHandler(na.col, containerCtrl, nodeCtrl)
tmh.InitMessagingHandler(na.col, objectCtrl)
fh.InitResourceHandler(na.nodeMpx, accountCtrl, containerCtrl, nodeCtrl, podCtrl)
fh.InitResourceHandler(na.nodeMpx, appFilter, accountCtrl, containerCtrl, nodeCtrl, podCtrl)
ch.InitHandler(na.apiMpx, coreDriverManager, cri, podKvs, recordKVS)
th.InitHandler(na.apiMpx, objectCtrl)

Expand Down
76 changes: 76 additions & 0 deletions node/controller/application_filter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright 2018 Yuji Ito <llamerada.jp@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package controller

import (
"strings"

coreAPI "github.com/llamerada-jp/oinari/api/core"
)

type ApplicationFilter interface {
SetFilter(filter string)
SetSamplePrefix(prefix string)
IsAllowed(pod *coreAPI.Pod) bool
}

type applicationFilterImpl struct {
filter string
samplePrefix string
account string
}

func NewApplicationFilter(account string) ApplicationFilter {
return &applicationFilterImpl{
filter: "samples",
account: account,
}
}

func (impl *applicationFilterImpl) SetFilter(filter string) {
impl.filter = filter
}

func (impl *applicationFilterImpl) SetSamplePrefix(prefix string) {
impl.samplePrefix = prefix
}

func (impl *applicationFilterImpl) IsAllowed(pod *coreAPI.Pod) bool {
if impl.filter == "any" {
return true
}

if impl.filter == "samples" || impl.filter == "samplesAndMyself" {
isSample := true
for _, container := range pod.Spec.Containers {
if !strings.HasPrefix(container.Image, impl.samplePrefix) {
isSample = false
break
}
}
if isSample {
return true
}
}

if impl.filter == "myself" || impl.filter == "samplesAndMyself" {
if pod.Meta.Owner == impl.account {
return true
}
}

return false
}
9 changes: 8 additions & 1 deletion node/controller/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ type reconcileState struct {
type containerControllerImpl struct {
localNid string
cri cri.CRI
appFilter ApplicationFilter
podKvs kvs.PodKvs
recordKvs kvs.RecordKvs
apiCoreDriverManager *coreAPI.Manager
Expand All @@ -62,10 +63,11 @@ type containerControllerImpl struct {
mtx sync.Mutex
}

func NewContainerController(localNid string, cri cri.CRI, podKvs kvs.PodKvs, recordKVS kvs.RecordKvs, apiCoreDriverManager *coreAPI.Manager) ContainerController {
func NewContainerController(localNid string, cri cri.CRI, appFilter ApplicationFilter, podKvs kvs.PodKvs, recordKVS kvs.RecordKvs, apiCoreDriverManager *coreAPI.Manager) ContainerController {
return &containerControllerImpl{
localNid: localNid,
cri: cri,
appFilter: appFilter,
podKvs: podKvs,
recordKvs: recordKVS,
apiCoreDriverManager: apiCoreDriverManager,
Expand Down Expand Up @@ -184,6 +186,11 @@ func (impl *containerControllerImpl) Reconcile(ctx context.Context, podUUID stri

// return sandboxId
func (impl *containerControllerImpl) letRunning(state *reconcileState, pod *core.Pod) error {
if !impl.appFilter.IsAllowed(pod) {
log.Printf("the application is not allowed to run on this node: %s/%s", pod.Meta.Owner, pod.Meta.Name)
return nil
}

// create sandbox if it isn't exist
if len(state.containerInfo.SandboxID) == 0 {
res, err := impl.cri.RunPodSandbox(&cri.RunPodSandboxRequest{
Expand Down
20 changes: 19 additions & 1 deletion node/frontend/handler/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,12 @@ type deletePodRequest struct {
Uuid string `json:"uuid"`
}

func InitResourceHandler(nodeMpx crosslink.MultiPlexer, accCtrl controller.AccountController, containerCtrl controller.ContainerController, nodeCtrl controller.NodeController, podCtrl controller.PodController) {
type configRequest struct {
Key string `json:"key"`
Value string `json:"value"`
}

func InitResourceHandler(nodeMpx crosslink.MultiPlexer, appFilter controller.ApplicationFilter, accCtrl controller.AccountController, containerCtrl controller.ContainerController, nodeCtrl controller.NodeController, podCtrl controller.PodController) {
mpx := crosslink.NewMultiPlexer()
nodeMpx.SetHandler("resource", mpx)

Expand Down Expand Up @@ -209,4 +214,17 @@ func InitResourceHandler(nodeMpx crosslink.MultiPlexer, accCtrl controller.Accou
}
writer.ReplySuccess(nil)
}))

mpx.SetHandler("config", crosslink.NewFuncHandler(
func(param *configRequest, tags map[string]string, writer crosslink.ResponseWriter) {
switch param.Key {
case "allowApplications":
appFilter.SetFilter(param.Value)
case "samplePrefix":
appFilter.SetSamplePrefix(param.Value)
default:
log.Fatalln("unknown config key: ", param.Key)
}
writer.ReplySuccess(nil)
}))
}
15 changes: 15 additions & 0 deletions src/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import * as CL from "./crosslink";
const CL_SYSTEM_PATH: string = "node/system";
const CL_RESOURCE_PATH: string = "node/resource";

export const CONFIG_KEY_ALLOW_APPLICATIONS: string = "allowApplications";
export const CONFIG_KEY_SAMPLE_PREFIX: string = "samplePrefix";

export interface ConnectInfo {
account: string
node: string
Expand Down Expand Up @@ -92,6 +95,11 @@ interface EnvVar {
// valueFrom is not supported yet.
}

interface Config {
key: string
value: string
}

export class Commands {
private cl: CL.Crosslink;
constructor(cl: CL.Crosslink) {
Expand Down Expand Up @@ -182,4 +190,11 @@ export class Commands {
uuid: uuid,
} as DeletePodRequest);
}

setConfiguration(key: string, value: string): void {
this.cl.call(CL_RESOURCE_PATH + "/config", {
key: key,
value: value,
} as Config);
}
}
33 changes: 33 additions & 0 deletions src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@
data-mdb-target="#modalProcList">
<i class="fas bi-compass fa-2x"></i>
</button>
<button type="button" class="btn btn-light" id="settingsButton" data-mdb-toggle="modal"
data-mdb-target="#modalSettings">
<i class="fas bi-gear fa-2x"></i>
</button>
</div>
</nav>

Expand Down Expand Up @@ -163,6 +167,35 @@ <h6 class="fw-bold appName"></h6>&nbsp;
</div>
</div>

<!-- Modal for settings -->
<div class="modal fade" id="modalSettings" tabindex="-1" aria-labelledby="modalSettingsLabel" aria-hidden="true">
<div class="modal-dialog modal-xl modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header" role="tablist">
<h5 class="modal-title">Settings</h5>
<div>
<button type="button" class="btn-close" id="settingsClose" data-mdb-dismiss="modal"
aria-label="Close"></button>
</div>
</div><!-- End of modal-header -->

<div class="modal-body">
<ul class="list-group list-group-light">
<li class="list-group-item">
Allow applications to run on this node.
<select class="form-select" id="settingsAllowApplications">
<option value="samples" selected>Provided as samples</option>
<option value="myself">Launched by myself</option>
<option value="samplesAndMyself">Provided as samples and launch by myself</option>
<option value="any">Any</option>
</select>
</li>
</ul>
</div><!-- End of modal-body -->
</div>
</div>
</div>

<!-- Modal for migrate -->
<div class="modal fade" id="modalMigrate" tabindex="-1" aria-labelledby="modalMigrateLabel" aria-hidden="true">
<div class="modal-dialog modal-xl modal-dialog-centered">
Expand Down
3 changes: 3 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import * as UI_AL from "./ui/app_loader";
import * as UI_MAP from "./ui/map";
import * as UI_MI from "./ui/migrate";
import * as UI_PL from "./ui/proc_list";
import * as UI_SE from "./ui/settings";
import * as UI_SI from "./ui/system_info";

declare function ColonioModule(): Promise<any>;
Expand Down Expand Up @@ -72,6 +73,7 @@ function initUI() {
UI_AL.init(command);
UI_MI.init(command);
UI_PL.init(command);
UI_SE.init(command);
if (readyMap) {
UI_MAP.init(frontendMpx);
}
Expand Down Expand Up @@ -114,6 +116,7 @@ async function main(): Promise<void> {
"PC");
UI_SI.set(info.account, info.node);
UI_PL.setNodeInfo(info.account, info.node);
UI_SE.setInitConfigs();

// set a position for sample playing
await command.setPosition(35.6594945, 139.6999859, 0);
Expand Down
45 changes: 45 additions & 0 deletions src/ui/settings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright 2018 Yuji Ito <llamerada.jp@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import * as CM from "../command";

const allowApplicationsID = "settingsAllowApplications";

let command: CM.Commands;

export function init(cmd: CM.Commands): void {
command = cmd;

initAllowApplications();
}

export function setInitConfigs(): void {
let allowApplications = document.getElementById(allowApplicationsID) as HTMLSelectElement;
command.setConfiguration(CM.CONFIG_KEY_ALLOW_APPLICATIONS, allowApplications.options[allowApplications.selectedIndex].value);
command.setConfiguration(CM.CONFIG_KEY_SAMPLE_PREFIX, document.location.origin);
}

function initAllowApplications(): void {
let allowApplications = document.getElementById(allowApplicationsID) as HTMLSelectElement;
// set default value
allowApplications.selectedIndex = 0;

allowApplications.addEventListener("change", () => {
let opt = allowApplications.options[allowApplications.selectedIndex];
let value = opt.value;
command.setConfiguration(CM.CONFIG_KEY_ALLOW_APPLICATIONS, value);
});
}

0 comments on commit 8f33304

Please sign in to comment.