Files
vm/object/machine_cloud.go
zooqueenandHanzo Dev a121f8d0d0 refactor: rebrand from casvisor to hanzoai/visor, remove hardcoded credentials
- Rename Go module from github.com/casvisor/casvisor to github.com/hanzoai/visor
- Update all copyright headers from casbin to Hanzo Industries Inc
- Remove all hardcoded passwords and credentials from config files
- All credentials now sourced from environment variables / Hanzo KMS
- Switch default database from MySQL to PostgreSQL (matching production)
- Rename binary output from server/casvisor to visor
- Update Dockerfile, build.sh, docker-compose.yml, docker-entrypoint.sh
- Replace casdoor* config key references with iam* equivalents
- Update CI to use PostgreSQL service and mark CI-only test password
- Add visor and casvisor binaries to .gitignore
- Add envFrom secretRef for visor-env in K8s deployment
- Add ExternalSecret template for Hanzo KMS credential provisioning

Co-authored-by: Hanzo Dev <[email protected]>
2026-02-21 00:04:31 -08:00

186 lines
5.0 KiB
Go

// Copyright 2025 Hanzo Industries Inc. All Rights Reserved.
//
// 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 object
import (
"fmt"
"github.com/hanzoai/visor/service"
)
func getMachineFromService(owner string, provider string, clientMachine *service.Machine) *Machine {
return &Machine{
Owner: owner,
Name: clientMachine.Name,
Id: clientMachine.Id,
Provider: provider,
CreatedTime: clientMachine.CreatedTime,
UpdatedTime: clientMachine.UpdatedTime,
ExpireTime: clientMachine.ExpireTime,
DisplayName: clientMachine.DisplayName,
Region: clientMachine.Region,
Zone: clientMachine.Zone,
Category: clientMachine.Category,
Type: clientMachine.Type,
Size: clientMachine.Size,
Tag: clientMachine.Tag,
State: clientMachine.State,
Image: clientMachine.Image,
Os: clientMachine.Os,
PublicIp: clientMachine.PublicIp,
PrivateIp: clientMachine.PrivateIp,
CpuSize: clientMachine.CpuSize,
MemSize: clientMachine.MemSize,
}
}
func getMachinesCloud(owner string) ([]*Machine, error) {
machines := []*Machine{}
providers, err := getActiveCloudProviders(owner)
if err != nil {
return nil, err
}
for _, provider := range providers {
client, err2 := service.NewMachineClient(provider.Type, provider.ClientId, provider.ClientSecret, provider.Region)
if err2 != nil {
return nil, err2
}
clientMachines, err2 := client.GetMachines()
if err2 != nil {
if provider.Type != "VMware" {
return nil, err2
}
}
for _, clientMachine := range clientMachines {
machine := getMachineFromService(owner, provider.Name, clientMachine)
machines = append(machines, machine)
}
}
return machines, nil
}
func SyncMachinesCloud(owner string) (bool, error) {
machines, err := getMachinesCloud(owner)
if err != nil {
return false, err
}
dbMachines, err := GetMachines(owner)
if err != nil {
return false, err
}
dbMachineMap := map[string]*Machine{}
for _, dbMachine := range dbMachines {
dbMachineMap[dbMachine.GetId()] = dbMachine
}
for _, machine := range machines {
if dbMachine, ok := dbMachineMap[machine.GetId()]; ok {
machine.RemoteProtocol = dbMachine.RemoteProtocol
machine.RemotePort = dbMachine.RemotePort
machine.RemoteUsername = dbMachine.RemoteUsername
machine.RemotePassword = dbMachine.RemotePassword
}
}
_, err = deleteMachines(owner)
if err != nil {
return false, err
}
if len(machines) == 0 {
return false, nil
}
affected, err := addMachines(machines)
return affected, err
}
// CreateMachineCloud launches a new VM via the cloud provider and registers it in the DB.
func CreateMachineCloud(owner string, providerName string, spec *service.CreateMachineSpec) (*Machine, error) {
provider, err := getProvider(owner, providerName)
if err != nil {
return nil, err
}
if provider == nil {
return nil, fmt.Errorf("provider %q not found for owner %q", providerName, owner)
}
client, err := service.NewMachineClient(provider.Type, provider.ClientId, provider.ClientSecret, provider.Region)
if err != nil {
return nil, fmt.Errorf("failed to create machine client: %w", err)
}
clientMachine, err := client.CreateMachine(spec)
if err != nil {
return nil, fmt.Errorf("failed to create cloud machine: %w", err)
}
machine := getMachineFromService(owner, providerName, clientMachine)
machine.Os = spec.OS
// Set remote access defaults based on OS
switch spec.OS {
case "windows":
machine.RemoteProtocol = "RDP"
machine.RemotePort = 3389
case "macos":
machine.RemoteProtocol = "VNC"
machine.RemotePort = 5900
default:
machine.RemoteProtocol = "SSH"
machine.RemotePort = 22
}
// Persist to DB
_, err = AddMachine(machine)
if err != nil {
return nil, fmt.Errorf("machine created in cloud but DB insert failed: %w", err)
}
return machine, nil
}
func updateMachineCloud(oldMachine *Machine, machine *Machine) (bool, error) {
provider, err := getProvider(oldMachine.Owner, oldMachine.Provider)
if err != nil {
return false, err
}
if provider == nil {
return false, fmt.Errorf("The provider: %s does not exist", machine.Provider)
}
client, err := service.NewMachineClient(provider.Type, provider.ClientId, provider.ClientSecret, provider.Region)
if err != nil {
return false, err
}
if oldMachine.State != machine.State {
affected, _, err := client.UpdateMachineState(oldMachine.Name, machine.State)
if err != nil {
return false, err
}
return affected, nil
}
return false, nil
}