Files
vm/service/gcp.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

156 lines
4.4 KiB
Go

// Copyright 2024 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 service
import (
"context"
"fmt"
"cloud.google.com/go/compute/apiv1/computepb"
"google.golang.org/grpc"
)
type MachineGcpClient struct {
Client *computepb.InstancesClient
ProjectID string
Zone string
}
// hostname is the IP address of the target host and the configured port format is {IP}:{port}
func newMachineGcpClient(hostname string, projectID string, zone string) (MachineGcpClient, error) {
conn, err := grpc.Dial(
hostname,
)
if err != nil {
return MachineGcpClient{}, err
}
client := computepb.NewInstancesClient(conn)
return MachineGcpClient{Client: &client, ProjectID: projectID, Zone: zone}, nil
}
func getMachineFromComputepbInstance(instance *computepb.Instance) *Machine {
machine := &Machine{
Name: instance.GetName(),
Id: fmt.Sprintf("%d", instance.GetId()),
CreatedTime: getLocalTimestamp(instance.GetCreationTimestamp()),
UpdatedTime: getLocalTimestamp(instance.GetLastStartTimestamp()),
DisplayName: instance.GetName(),
Zone: instance.GetZone(),
Type: instance.GetMachineType(),
State: instance.GetStatus(),
Image: instance.GetSourceMachineImage(),
Os: instance.GetDisks()[0].GetGuestOsFeatures()[0].GetType(),
CpuSize: instance.GetCpuPlatform(),
}
for key, value := range instance.GetLabels() {
machine.Tag += fmt.Sprintf("%s=%s,", key, value)
}
if len(instance.GetNetworkInterfaces()) > 0 {
if len(instance.GetNetworkInterfaces()[0].GetAccessConfigs()) > 0 {
machine.PublicIp = instance.GetNetworkInterfaces()[0].GetAccessConfigs()[0].GetNatIP()
}
machine.PrivateIp = instance.GetNetworkInterfaces()[0].GetNetworkIP()
}
return machine
}
func (client MachineGcpClient) GetMachines() ([]*Machine, error) {
ctx := context.Background()
var maxResults *uint32
value := uint32(100)
maxResults = &value
req := &computepb.ListInstancesRequest{
Project: client.ProjectID,
Zone: client.Zone,
MaxResults: maxResults,
}
resp, err := computepb.InstancesClient.List(*client.Client, ctx, req)
if err != nil {
return nil, err
}
machines := []*Machine{}
for _, instance := range resp.GetItems() {
machine := getMachineFromComputepbInstance(instance)
machines = append(machines, machine)
}
return machines, nil
}
func (client MachineGcpClient) GetMachine(name string) (*Machine, error) {
ctx := context.Background()
req := &computepb.GetInstanceRequest{
Project: client.ProjectID,
Zone: client.Zone,
Instance: name,
}
instance, err := computepb.InstancesClient.Get(*client.Client, ctx, req)
if err != nil {
return nil, err
}
machine := getMachineFromComputepbInstance(instance)
return machine, nil
}
func (client MachineGcpClient) UpdateMachineState(name string, state string) (bool, string, error) {
machine, err := client.GetMachine(name)
if err != nil {
return false, "", err
}
if machine == nil {
return false, fmt.Sprintf("Instance: [%s] is not found", name), nil
}
instanceId := machine.Id
switch state {
case "Running":
startReq := &computepb.StartInstanceRequest{
Project: client.ProjectID,
Zone: client.Zone,
Instance: instanceId,
}
_, err = computepb.InstancesClient.Start(*client.Client, context.Background(), startReq)
case "Stopped":
stopReq := &computepb.StopInstanceRequest{
Project: client.ProjectID,
Zone: client.Zone,
Instance: instanceId,
}
_, err = computepb.InstancesClient.Stop(*client.Client, context.Background(), stopReq)
default:
return false, fmt.Sprintf("Unsupported state: %s", state), nil
}
if err != nil {
return false, "", err
}
return true, fmt.Sprintf("Instance: [%s]'s state has been successfully updated to: [%s]", name, state), nil
}
func (client MachineGcpClient) CreateMachine(spec *CreateMachineSpec) (*Machine, error) {
return nil, fmt.Errorf("CreateMachine not yet implemented for GCP")
}