Skip to content

title: CloudSlash - Building Plugins Reference description: Use the scaffold generator. It writes the boilerplate so you start at the part that actually differs between providers. This creates a complete project: Open...


Building Plugins

Use the scaffold generator. It writes the boilerplate so you start at the part that actually differs between providers.

Prerequisites

  • Go 1.23+
  • CloudSlash CLI installed
  • Familiarity with your target cloud API

Scaffold

cs plugin create digitalocean

This creates a complete project:

cloudslash-plugin-digitalocean/
├── main.go          # gRPC provider with Handshake + Scan stubs
├── go.mod           # Dependencies pre-configured
├── Makefile         # build, test, install targets
└── README.md        # Docs + registry manifest template

Implement Scanners

Open main.go and implement the Scan method. The engine calls this to discover resources:

func (p *DigitaloceanProvider) Scan(req *pb.ScanRequest, stream pb.Provider_ScanServer) error {
    // 1. Initialize your cloud SDK client.
    token := req.Config["DIGITALOCEAN_TOKEN"]
    client := godo.NewFromToken(token)

    // 2. List resources from the cloud API.
    droplets, _, _ := client.Droplets.List(stream.Context(), nil)

    // 3. For each resource, stream a node back to the engine.
    for _, d := range droplets {
        node := &pb.Node{
            Crn: fmt.Sprintf("crn:digitalocean::%s:compute:droplet:%s:%s",
                d.Region.Slug, "account-id", d.Name),
            Properties: map[string]string{
                "instance_type": d.SizeSlug,
                "vcpus":         fmt.Sprint(d.Vcpus),
                "memory_mb":     fmt.Sprint(d.Memory),
            },
            Cost: estimateCost(d.SizeSlug),
        }
        stream.Send(&pb.ScanResponse{Nodes: []*pb.Node{node}})
    }

    return nil
}

Key Concepts

Concept Description
CRN CloudSlash Resource Name: universal ID format: crn:<provider>:<region>:<service>:<type>:<account>:<id>
Streaming Send nodes in batches as you discover them: don't buffer everything in memory
Cost Estimate monthly cost per resource so the waste engine can calculate savings
Properties Attach metadata the heuristics engine uses to detect waste (CPU util, last access, etc.)

Build & Install

cd cloudslash-plugin-digitalocean
make build    # Compile the binary
make install  # Copy to ~/.cloudslash/plugins/

Verify

Restart the daemon and check doctor:

cs doctor

Your plugin appears in the Plugins section:

  Plugins
  cloudslash-plugin-digitalocean  [OK]  ~/.cloudslash/plugins/cloudslash-plugin-digitalocean

Publish

Optional

Create a manifest.yaml in your repo:

name: digitalocean
version: 1.0.0
type: plugin
author: your-github-handle
description: DigitalOcean provider for CloudSlash
tags: [digitalocean, cloud, droplets]
cloudslash_min_version: "2.0.0"
binaries:
  darwin-arm64: https://github.com/you/cloudslash-plugin-digitalocean/releases/download/v1.0.0/cloudslash-plugin-digitalocean-darwin-arm64
  linux-amd64: https://github.com/you/cloudslash-plugin-digitalocean/releases/download/v1.0.0/cloudslash-plugin-digitalocean-linux-amd64

Submit a PR to the cloudslash-plugins repository.

Category Assignment

Your plugin does not declare its own category. The registry maintainer (DrSkyle) assigns a category (cloud, database, infrastructure, saas, iot, devops, security) during PR review. This prevents miscategorization and ensures the workspace filtering system works correctly across all plugins. If your plugin doesn't fit an existing category, propose a new one in the PR description.