{"id":21003322,"url":"https://github.com/koding/kloud-provider-example","last_synced_at":"2025-03-13T14:14:35.892Z","repository":{"id":146362802,"uuid":"68011657","full_name":"koding/kloud-provider-example","owner":"koding","description":null,"archived":false,"fork":false,"pushed_at":"2016-10-06T00:59:53.000Z","size":18,"stargazers_count":1,"open_issues_count":1,"forks_count":1,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-01-20T10:11:30.472Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/koding.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-09-12T13:32:31.000Z","updated_at":"2016-09-27T16:15:20.000Z","dependencies_parsed_at":null,"dependency_job_id":"8cfc0368-9f3a-4651-bb95-5ed214c67e23","html_url":"https://github.com/koding/kloud-provider-example","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/koding%2Fkloud-provider-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/koding%2Fkloud-provider-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/koding%2Fkloud-provider-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/koding%2Fkloud-provider-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/koding","download_url":"https://codeload.github.com/koding/kloud-provider-example/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243419128,"owners_count":20287806,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-19T08:24:48.258Z","updated_at":"2025-03-13T14:14:35.862Z","avatar_url":"https://github.com/koding.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"kloud-provider-example\n----------------------\n\nThis repository is an example of custom Kloud provider plugin.\n\nKloud is a backend behind Koding that is responsible for bootstrapping, building and destroying user stacks and managing access to each machine instance within those stacks.\n\n## Requirements\n\n- [go1.6+](https://golang.org/dl/)\n\n## Installation\n\nA new Kloud provider can be added by simply clonning your provider plugin into `kloud/provider` directory and rebuilding Kloud.\n\n```bash\nkoding $ git clone git@github.com:kloud/kloud-provider-example go/src/koding/kites/kloud/provider/example\nkoding $ ./go/build.sh\n```\n\n## Plugins\n\nA Kloud provider is responsible for composing a single Terraform template from multiple data sources:\n\n- stack template\n- credentials\n- bootstrapped resources\n\nA single Kloud provider validates credentials provided by a user, bootstraps a stack by creating provider-specific, persistant resources and provisions a Klient service for each instance built within a stack. The Klient service is used to connect remote machine to Koding allowing for webterm sessions in the browser, machine-sharing with other Koding users and starting / stopping the machine itself.\n\n# Example plugin\n\nThis repository contains a documented example of a Kloud provider plugin - [example.go](./example.go).\n\nThe [Koding repository](https://github.com/koding/koding) contains more examples of Kloud providers:\n\n- [AWS](https://github.com/koding/koding/tree/master/go/src/koding/kites/kloud/provider/aws)\n- [Vagrant](https://github.com/koding/koding/tree/master/go/src/koding/kites/kloud/provider/vagrant)\n- [Digital Ocean](https://github.com/koding/koding/tree/master/go/src/koding/kites/kloud/provider/do)\n\n# Quick start\n\nGo services in Koding repository use currently project-based GOPATH, that's why ensure you point your GOPATH to the `go` directory inside Koding repository:\n\n```bash\n~ $ export GOPATH=~/github.com/koding/koding/go\n```\n\nA project structure of your Kloud provider may look like the following:\n\n```\nyour/\n├── your.go        \u003c-- registers *provider.Provider\n├── machine.go     \u003c-- defines *Machine struct\n├── schema.go      \u003c-- defines *Credential, *Bootstrap and *Metadata structs\n└── stack.go       \u003c-- defines *Stack struct\n```\n\n- `example.go` registers provider definition (like [this one](./example.go#L18-L105))\n\nThe content of this file is:\n\n```go\npackage your\n\nimport (\n\t\"koding/kites/kloud/stack\"\n\t\"koding/kites/kloud/stack/provider\"\n)\n\nvar p = \u0026provider.Provider{\n\tName:         \"your\",\n\tResourceName: \"instance\",\n\t\n\t// Machine type is defined in machine.go\n\tMachine: func(bm *provider.BaseMachine) (provider.Machine, error) {\n\t\treturn \u0026Machine{BaseMachine: bm}, nil\n\t},\n\t\n\t// Stack type is defined in stack.go\n\tStack: func(bs *provider.BaseStack) (provider.Stack, error) {\n\t\treturn \u0026Stack{BaseStack: bs}, nil\n\t},\n\t\n\t// Schema value is defined in schema.go \n\tSchema: Schema,\n}\n\nfunc init() {\n\tprovider.Register(p)\n}\n```\n\n- `schema.go` defines models which are used to persist provider data (like [this one](./example.go#L92-L104))\n\nAnd its contents:\n\n```go\npackage your\n\nimport \"koding/kites/kloud/stack/provider\"\n\nvar Schema = \u0026provider.Schema{\n\tNewCredential: func() interface{} { return \u0026Credential{} },\n\tNewBootstrap:  func() interface{} { return \u0026Bootstrap{} },\n\tNewMetadata:   func(*stack.Machine) interface{} { \u0026Metadata{} },\n}\n\ntype Credential struct {\n\tUser string\n\tPass string\n}\n\ntype Bootstrap struct {\n\tPersistentResourceName string\n}\n\ntype Metadata struct {\n\tMachineRegion string\n\tMachineCNAME  string\n}\n```\n\nIf any of the schema types implement the following interface:\n\n```go\ntype Validator interface {\n\tValid() error\n}\n```\n\nthe `Valid()` method is going to be called after reading the value from Koding database / safe store in order to validate it.\n\nMore details on schema can be found [here](./example.go#L71-L91), [here](./example.go#L134-L155) and [here](./example.go#L191-L216).\n\n- `stack.go` defines a Stack struct which implements the `provider.Stack` interface\n\nThe stub definition looks like:\n\n```go\npackage your\n\nimport (\n\t\"errors\"\n\n\t\"koding/kites/kloud/stack\"\n\t\"koding/kites/kloud/stack/provider\"\n)\n\nvar errNotImplemented = errors.New(\"not implemented\")\n\ntype Stack struct {\n\t*provider.BaseStack\n}\n\nfunc (*Stack) VerifyCredential(*stack.Credential) error {\n\treturn errNotImplemented\n}\n\nfunc (*Stack) BootstrapTemplates(*stack.Credential) ([]*stack.Template, error) {\n\treturn nil, errNotImplemented\n}\n\nfunc (*Stack) ApplyTemplate(*stack.Credential) (*stack.Template, error) {\n\treturn nil, errNotImplemented\n}\n```\n\nMore details on expected behavior of each method can be found [here](./example.go#L223-L236), [here](./example.go#L238-L247) and [here](./example.go#L249-L338).\n\n- and `machine.go`, which defines \\*Machine for controlling single remote machine\n\nThe stub:\n\n```go\npackage your\n\nimport (\n\t\"errors\"\n\n\t\"koding/kites/kloud/machinestate\"\n\t\"koding/kites/kloud/stack/provider\"\n\n\t\"golang.org/x/net/context\"\n)\n\nvar errNotImplemented = errors.New(\"not implemented\")\n\ntype Machine struct {\n\t*provider.BaseMachine\n}\n\nfunc (*Machine) Start(context.Context) (metadata interface{}, err error) {\n\treturn nil, errNotImplemented\n}\n\nfunc (*Machine) Stop(context.Context) (metadata interface{}, err error) {\n\treturn nil, errNotImplemented\n}\n\nfunc (*Machine) Info(context.Context) (state machinestate.State, metadata interface{}, err error) {\n\treturn 0, nil, errNotImplemented\n}\n```\n\nMore details [here](./example.go#L157-L189) and [an example of AWS implementation](https://github.com/koding/koding/blob/358a070fd24700cee4a39dc556ad79164f3b9918/go/src/koding/kites/kloud/provider/aws/machine.go#L42-L68).\n\n## Final notes\n\nThe `*provider.BaseMachine` and `*provider.BaseStack` API should be considered not stable, thus a subject to change. Usually it means a rename here and there or new fields that remove the boilerplate even further.\n\nRelavant issues:\n\n- https://github.com/koding/koding/issues/9127\n- https://github.com/koding/koding/issues/8903\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkoding%2Fkloud-provider-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkoding%2Fkloud-provider-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkoding%2Fkloud-provider-example/lists"}