Skip to content

Commit

Permalink
Merge pull request #5969 from jtopjian/provider-cobbler
Browse files Browse the repository at this point in the history
Cobbler Provider
  • Loading branch information
phinze committed Apr 16, 2016
2 parents 12118b6 + 17e5032 commit 0db3a57
Show file tree
Hide file tree
Showing 52 changed files with 8,406 additions and 1 deletion.
13 changes: 13 additions & 0 deletions Godeps/Godeps.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions builtin/bins/provider-cobbler/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package main

import (
"github.com/hashicorp/terraform/builtin/providers/cobbler"
"github.com/hashicorp/terraform/plugin"
)

func main() {
plugin.Serve(&plugin.ServeOpts{
ProviderFunc: cobbler.Provider,
})
}
94 changes: 94 additions & 0 deletions builtin/providers/cobbler/acceptance_env/deploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#!/bin/bash

set -e

# This script assumes Ubuntu 14.04 is being used.
# It will create a standard Cobbler environment that can be used for acceptance testing.

# With this enviornment spun up, the config should be:
# COBBLER_URL=http://127.0.0.1:25151
# COBBLER_USERNAME=cobbler
# COBBLER_PASSWORD=cobbler

sudo apt-get update
sudo apt-get install -y build-essential git mercurial

cd
echo 'export PATH=$PATH:$HOME/terraform:$HOME/go/bin' >> ~/.bashrc
export PATH=$PATH:$HOME/terraform:$HOME/go/bin

sudo wget -O /usr/local/bin/gimme https://raw.githubusercontent.com/travis-ci/gimme/master/gimme
sudo chmod +x /usr/local/bin/gimme
/usr/local/bin/gimme 1.6 >> ~/.bashrc
eval "$(/usr/local/bin/gimme 1.6)"

mkdir ~/go
echo 'export GOPATH=$HOME/go' >> ~/.bashrc
echo 'export GO15VENDOREXPERIMENT=1' >> ~/.bashrc
export GOPATH=$HOME/go
source ~/.bashrc

go get github.com/tools/godep
go get github.com/hashicorp/terraform
cd $GOPATH/src/github.com/hashicorp/terraform
godep restore

# Cobbler
sudo apt-get install -y cobbler cobbler-web debmirror dnsmasq

sudo tee /etc/cobbler/modules.conf <<EOF
[authentication]
module = authn_configfile
[authorization]
module = authz_allowall
[dns]
module = manage_dnsmasq
[dhcp]
module = manage_dnsmasq
[tftpd]
module = manage_in_tftpd
EOF

sudo tee /etc/cobbler/dnsmasq.template <<EOF
dhcp-range = 192.168.255.200,192.168.255.250
server = 8.8.8.8
read-ethers
addn-hosts = /var/lib/cobbler/cobbler_hosts
dhcp-option=3,\$next_server
dhcp-lease-max=1000
dhcp-authoritative
dhcp-boot=pxelinux.0
dhcp-boot=net:normalarch,pxelinux.0
dhcp-boot=net:ia64,\$elilo
\$insert_cobbler_system_definitions
EOF

sudo sed -i -e 's/^manage_dhcp: 0/manage_dhcp: 1/' /etc/cobbler/settings
sudo sed -i -e 's/^manage_dns: 0/manage_dns: 1/' /etc/cobbler/settings
sudo sed -i -e 's/^next_server:.*/next_server: 127.0.0.1/' /etc/cobbler/settings
sudo sed -i -e 's/^server:.*/server: 127.0.0.1/' /etc/cobbler/settings

# User: cobbler / Pass: cobbler
sudo tee /etc/cobbler/users.digest <<EOF
cobbler:Cobbler:2d6bae81669d707b72c0bd9806e01f3
EOF

# The stock version of Cobbler in the Ubuntu repository still has the old cobbler homepage URL
sudo sed -i -e 's#content_server = "http://www.cobblerd.org/loaders"#content_server = "http://cobbler.github.com/loaders"#' /usr/lib/python2.7/dist-packages/cobbler/action_dlcontent.py
sudo rm /usr/lib/python2.7/dist-packages/cobbler/action_dlcontent.pyc

sudo /etc/init.d/apache2 restart
sudo stop cobbler
sleep 2
sudo start cobbler
sleep 10
sudo cobbler get-loaders
sudo cobbler sync

# Import an Ubuntu 1404 distro
cd /tmp
wget http://old-releases.ubuntu.com/releases/14.04.2/ubuntu-14.04-server-amd64.iso
sudo mount -o loop ubuntu-14.04-server-amd64.iso /mnt
sudo cobbler import --name Ubuntu-14.04 --breed ubuntu --path /mnt
74 changes: 74 additions & 0 deletions builtin/providers/cobbler/acceptance_env/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# This will spin up an instance and install cobbler onto it so we can run

# the Terraform acceptance tests against it.

module "ami" {
source = "github.com/terraform-community-modules/tf_aws_ubuntu_ami/ebs"
region = "us-west-2"
distribution = "trusty"
instance_type = "t2.nano"
}

module "vpc" {
source = "github.com/terraform-community-modules/tf_aws_vpc"

name = "cobbler"
cidr = "10.0.0.0/16"
private_subnets = "10.0.1.0/24"
public_subnets = "10.0.101.0/24"
azs = "us-west-2a"
}

resource "aws_key_pair" "cobbler" {
key_name = "tf-cobbler-acctests"
public_key = "${file("~/.ssh/id_rsa.pub")}"
}

resource "aws_security_group" "cobbler" {
vpc_id = "${module.vpc.vpc_id}"

ingress {
protocol = "tcp"
from_port = 22
to_port = 22
cidr_blocks = ["0.0.0.0/0"]
}

egress {
protocol = "-1"
from_port = 0
to_port = 0
cidr_blocks = ["0.0.0.0/0"]
}
}

resource "aws_instance" "cobbler" {
instance_type = "t2.medium"
ami = "${module.ami.ami_id}"
subnet_id = "${module.vpc.public_subnets}"
key_name = "${aws_key_pair.cobbler.id}"
vpc_security_group_ids = ["${aws_security_group.cobbler.id}"]

root_block_device {
volume_type = "gp2"
volume_size = 40
}

connection {
user = "ubuntu"
}

provisioner "remote-exec" {
inline = <<-WAIT
while [ ! -f /var/lib/cloud/instance/boot-finished ]; do echo 'Waiting for cloud-init...'; sleep 1; done
WAIT
}

provisioner "remote-exec" {
script = "${path.module}/deploy.sh"
}
}

output "ssh" {
value = "ubuntu@${aws_instance.cobbler.public_ip}"
}
33 changes: 33 additions & 0 deletions builtin/providers/cobbler/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package cobbler

import (
"net/http"

cobbler "github.com/jtopjian/cobblerclient"
)

type Config struct {
Url string
Username string
Password string

cobblerClient cobbler.Client
}

func (c *Config) loadAndValidate() error {
config := cobbler.ClientConfig{
Url: c.Url,
Username: c.Username,
Password: c.Password,
}

client := cobbler.NewClient(http.DefaultClient, config)
_, err := client.Login()
if err != nil {
return err
}

c.cobblerClient = client

return nil
}
76 changes: 76 additions & 0 deletions builtin/providers/cobbler/provider.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package cobbler

import (
"os"

"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/terraform"
)

func Provider() terraform.ResourceProvider {
return &schema.Provider{
Schema: map[string]*schema.Schema{
"url": &schema.Schema{
Type: schema.TypeString,
Required: true,
Description: "Cobbler URL",
DefaultFunc: envDefaultFunc("COBBLER_URL"),
},

"username": &schema.Schema{
Type: schema.TypeString,
Required: true,
Description: "The username for accessing Cobbler.",
DefaultFunc: envDefaultFunc("COBBLER_USERNAME"),
},

"password": &schema.Schema{
Type: schema.TypeString,
Required: true,
Description: "The password for accessing Cobbler.",
DefaultFunc: envDefaultFunc("COBBLER_PASSWORD"),
},
},

ResourcesMap: map[string]*schema.Resource{
"cobbler_distro": resourceDistro(),
"cobbler_kickstart_file": resourceKickstartFile(),
"cobbler_profile": resourceProfile(),
"cobbler_snippet": resourceSnippet(),
"cobbler_system": resourceSystem(),
},

ConfigureFunc: configureProvider,
}
}

func configureProvider(d *schema.ResourceData) (interface{}, error) {
config := Config{
Url: d.Get("url").(string),
Username: d.Get("username").(string),
Password: d.Get("password").(string),
}

if err := config.loadAndValidate(); err != nil {
return nil, err
}

return &config, nil
}

func envDefaultFunc(k string) schema.SchemaDefaultFunc {
return func() (interface{}, error) {
if v := os.Getenv(k); v != "" {
return v, nil
}

return nil, nil
}
}

func envDefaultFuncAllowMissing(k string) schema.SchemaDefaultFunc {
return func() (interface{}, error) {
v := os.Getenv(k)
return v, nil
}
}
46 changes: 46 additions & 0 deletions builtin/providers/cobbler/provider_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package cobbler

import (
"os"
"testing"

"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/terraform"
)

var testAccCobblerProviders map[string]terraform.ResourceProvider
var testAccCobblerProvider *schema.Provider

func init() {
testAccCobblerProvider = Provider().(*schema.Provider)
testAccCobblerProviders = map[string]terraform.ResourceProvider{
"cobbler": testAccCobblerProvider,
}
}

func TestProvider(t *testing.T) {
if err := Provider().(*schema.Provider).InternalValidate(); err != nil {
t.Fatalf("err: %s", err)
}
}

func TestProvider_impl(t *testing.T) {
var _ terraform.ResourceProvider = Provider()
}

func testAccCobblerPreCheck(t *testing.T) {
v := os.Getenv("COBBLER_USERNAME")
if v == "" {
t.Fatal("COBBLER_USERNAME must be set for acceptance tests.")
}

v = os.Getenv("COBBLER_PASSWORD")
if v == "" {
t.Fatal("COBBLER_PASSWORD must be set for acceptance tests.")
}

v = os.Getenv("COBBLER_URL")
if v == "" {
t.Fatal("COBBLER_URL must be set for acceptance tests.")
}
}
Loading

0 comments on commit 0db3a57

Please sign in to comment.