Skip to content
Snippets Groups Projects
main.go 7.62 KiB
Newer Older
Hugo Hörnquist's avatar
Hugo Hörnquist committed
package main

import (
Hugo Hörnquist's avatar
Hugo Hörnquist committed
	"fmt"
Hugo Hörnquist's avatar
Hugo Hörnquist committed
	"log"
	"os"
	"context"
	"syscall"
Hugo Hörnquist's avatar
Hugo Hörnquist committed
	"crypto/tls"
	"encoding/json"
	"net/http"

	"bazil.org/fuse"
	"bazil.org/fuse/fs"
	_ "bazil.org/fuse/fs/fstestutil"
var data []ResultRecord
Hugo Hörnquist's avatar
Hugo Hörnquist committed
var client *http.Client
var password string
var classes map[float64]Puppetclass
Hugo Hörnquist's avatar
Hugo Hörnquist committed
func main() {
Hugo Hörnquist's avatar
Hugo Hörnquist committed
	password = os.Args[1:][0]

	classes = map[float64]Puppetclass{}
Hugo Hörnquist's avatar
Hugo Hörnquist committed

	tr := &http.Transport {
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}

Hugo Hörnquist's avatar
Hugo Hörnquist committed
	client = &http.Client { Transport: tr }

Hugo Hörnquist's avatar
Hugo Hörnquist committed

	// request, err := http.NewRequest("GET", "https://chapman.lysator.liu.se/api/hosts", nil)
	request, err := http.NewRequest("GET", "http://localhost:8000/hosts.json", nil)
	if err != nil {
		log.Fatal(err);
	}
	request.SetBasicAuth("hugo", password);

	resp, err := client.Do(request)
	if err != nil {
		log.Fatal(err);
	}
	defer resp.Body.Close()
Hugo Hörnquist's avatar
Hugo Hörnquist committed



	// echo curl --user "hugo:$(pass lysator/hugo)" -k https://chapman.lysator.liu.se/api/hosts 


	decoder := json.NewDecoder(resp.Body);
	var m Message
	err = decoder.Decode(&m)
	if err != nil {
		log.Fatal(err);
	}
	data = m.Results
Hugo Hörnquist's avatar
Hugo Hörnquist committed

Hugo Hörnquist's avatar
Hugo Hörnquist committed
	for _, record := range m.Results {
		if record.Owner_name == "Hugo Hörnquist" {
			fmt.Printf("%v\n", record.Name)
		}
	}
Hugo Hörnquist's avatar
Hugo Hörnquist committed

	c, err := fuse.Mount(
		"mnt",
		fuse.FSName("Foreman"),
		fuse.Subtype("foreman"),
	)
	if err != nil {
		log.Fatal(err)
	}
	// defer c.Unmount()
	defer c.Close()

	err = fs.Serve(c, FS{})
	if err != nil {
		log.Fatal(err)
	}

}


type ResultRecord struct {
	Ip string // "130.236.254.139",
	Ip6 string // "2001:6b0:17:f0a0::8b",
	Environment_id float64 // 1,
	Environment_name string // "production",
	Last_report string // "2020-10-28 19:10:57 UTC",
	Mac string // "1c:c1:de:03:e7:b6",
	/*
	"realm_id": null,
	"realm_name": null,
	"sp_mac": null,
	"sp_ip": null,
	"sp_name": null,
	*/
	Domain_id float64 // 1,
	Domain_name string // "lysator.liu.se",
	Architecture_id float64 // 1,
	Architecture_name string // "x86_64",
	Operatingsystem_id float64 // 6,
	Operatingsystem_name string // "CentOS Linux 7.8.2003",
	/*
	"subnet_id": null,
	"subnet_name": null,
	"subnet6_id": null,
	"subnet6_name": null,
	"sp_subnet_id": null,
	"ptable_id": null,
	"ptable_name": null,
	"medium_id": null,
	"medium_name": null,
	"pxe_loader": null,
	"build": false,
	*/
	Comment string // "",
	/*
	"disk": null,
	"installed_at": null,
	*/
	Model_id float64 // 3,
	Hostgroup_id float64 // 6,
	Owner_id float64 // 5,
	Owner_name string // "Henrik Henriksson",
	Owner_type string // "User",
	Enabled bool // true,
	Managed bool // false,
	/*
	"use_image": null,
	*/
	Image_file string // "",
	/*
	"uuid": null,
	"compute_resource_id": null,
	"compute_resource_name": null,
	"compute_profile_id": null,
	"compute_profile_name": null,
	*/
	// capabilities []interface{} // [ "build" ],
	Provision_method string // "build",
	Certname string // "analysator-system.lysator.liu.se",
	/*
	"image_id": null,
	"image_name": null,
	*/
	Created_at string // "2020-08-16 19:51:59 UTC",
	Updated_at string // "2020-10-28 19:11:26 UTC",
	/*
	"last_compile": null,
	*/
	Global_status float64 // 0,
	Global_status_label string // "OK",
	Uptime_seconds float64 // 20857465,
	Organization_id float64 // 1,
	Organization_name string // "Lysator",
	Location_id float64 // 2,
	Location_name string // "Foo",
	Puppet_status float64 // 0,
	Model_name string // "ProLiant DL180 G6",
	Configuration_status float64 // 0,
	Configuration_status_label string // "No changes",
	Name string // "analysator-system.lysator.liu.se",
	Id float64 // 13,
	Puppet_proxy_id float64 // 1,
	Puppet_proxy_name string // "chapman.lysator.liu.se",
	Puppet_ca_proxy_id float64 // 1,
	Puppet_ca_proxy_name string // "chapman.lysator.liu.se",
	/*
	"puppet_proxy": {
		"name": "chapman.lysator.liu.se",
		"id": 1,
		"url": "https://chapman.lysator.liu.se:8443"
	},
	"puppet_ca_proxy": {
		"name": "chapman.lysator.liu.se",
		"id": 1,
		"url": "https://chapman.lysator.liu.se:8443"
	},
	*/
	Hostgroup_name string // "System",
	Hostgroup_title string // "Analysator/System"
}

type Message struct {
	Total, Subtotal, Page/*, Per_page*/ float64
	Results []ResultRecord
	// search
	// sort { by, order null }
}

type FS struct{
	// data []ResultRecord
}

func (fs FS) Root() (fs.Node, error) {
Hugo Hörnquist's avatar
Hugo Hörnquist committed
	return Dir{ "" /*fs.data*/ }, nil
}

func (FS) GenerateInode(parentInode uint64, name string) uint64 {
	sum := uint64(0)
	sum += parentInode
	for _, c := range []byte(name) {
		sum += uint64(c)
	}
Hugo Hörnquist's avatar
Hugo Hörnquist committed
	log.Printf("Generating inode for %v (inode = %v, parent = %v)",
		name, sum, parentInode)
Hugo Hörnquist's avatar
Hugo Hörnquist committed
/* dir hashable? */
/* TODO does two Dir object with same value hash become the same
* object? */
type Dir struct{
	// data []ResultRecord
Hugo Hörnquist's avatar
Hugo Hörnquist committed
	name string
}
func (Dir) Attr(ctx context.Context, a *fuse.Attr) error {
Hugo Hörnquist's avatar
Hugo Hörnquist committed
	// log.Print("Stat dir")
	a.Inode = 0
	a.Mode = os.ModeDir | 0o555
	return nil
}

func (d Dir) Lookup(ctx context.Context, name string) (fs.Node, error) {
Hugo Hörnquist's avatar
Hugo Hörnquist committed

	log.Printf("Lookup '%v' in '%v'", name, d.name)

	if name == "hosts" {
		return Dir{ d.name + "/" + name }, nil
	}

	for _, item := range data {
		if item.Name == name {
			log.Printf("Found %v", name)
Hugo Hörnquist's avatar
Hugo Hörnquist committed
			return File{item}, nil
		}
	}
	log.Printf("File %v missing", name)
	return nil, syscall.ENOENT
}

type File struct {
Hugo Hörnquist's avatar
Hugo Hörnquist committed
	record ResultRecord
}

func (d Dir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {
	var dirents []fuse.Dirent
Hugo Hörnquist's avatar
Hugo Hörnquist committed
	dirents = append(dirents, fuse.Dirent{Inode: 0, Name: "hosts", Type: fuse.DT_Dir})
	/*
	for _, item := range data {
		dirents = append(dirents, fuse.Dirent{Inode: 0, Name: item.Name, Type: fuse.DT_File})
	}
Hugo Hörnquist's avatar
Hugo Hörnquist committed
	*/
	return dirents, nil
}

func (f File) Attr(ctx context.Context, a *fuse.Attr) error {
	a.Inode = 0
	a.Mode = 0o444
Hugo Hörnquist's avatar
Hugo Hörnquist committed
	a.Size = uint64(len(fmt.Sprintf("%+v\n", f.record)))
	// a.Size = uint64(len(greeting))
Hugo Hörnquist's avatar
Hugo Hörnquist committed
type Puppetclass struct {

	Profiles []struct {
		Id float64
		Name string
		Created_at string
		Updated_at string
	}

	/*
	[{"id":433,"name":"profiles::elvisp","created_at":"2020-10-27T07:57:47.102Z","updated_at":"2020-10-27T07:57:47.102Z"},
	 {"id":243,"name":"profiles::service","created_at":"2020-08-16T15:07:23.431Z","updated_at":"2020-08-16T15:07:23.431Z"},
	 {"id":434,"name":"profiles::vitellary","created_at":"2020 -10-27T07:57:47.130Z","updated_at":"2020-10-27T07:57:47.130Z"}]}
	 */

	/*
	{
		"total": 3,
		"subtotal": 3,
		"page": 1,
		"per_page": 50,
		"search": null,
		"sort": {
			"by": null,
			"order": null
		},
		"results": {"profiles":[{"id":433,"name":"profiles::elvisp","created_at":"2020-10-27T07:57:47.102Z","updated_at":"2020-10-27T07:57:47.102Z"},{"id":243,"name"
		:"profiles::service","created_at":"2020-08-16T15:07:23.431Z","updated_at":"2020-08-16T15:07:23.431Z"},{"id":434,"name":"profiles::vitellary","created_at":"2020
		-10-27T07:57:47.130Z","updated_at":"2020-10-27T07:57:47.130Z"}]}
	}
	*/
}

type PuppetclassMessage struct {
	Total, Subtotal, Page/*, Per_page*/ float64
	Results Puppetclass
}


func (f File) ReadAll(ctx context.Context) ([]byte, error) {
Hugo Hörnquist's avatar
Hugo Hörnquist committed

	var record Puppetclass

	if val, ok := classes[f.record.Id]; ok {
		record = val
	} else {
		url := fmt.Sprintf("https://chapman.lysator.liu.se/api/hosts/%d/puppetclasses", int(f.record.Id));
		request, err := http.NewRequest("GET",url, nil)
		if err != nil {
			log.Fatal(err);
		}
		request.SetBasicAuth("hugo", password);

		resp, err := client.Do(request)
		if err != nil {
			log.Fatal(err);
		}
		defer resp.Body.Close()

		decoder := json.NewDecoder(resp.Body);
		var m PuppetclassMessage
		err = decoder.Decode(&m)
		if err != nil {
			log.Fatal(err);
		}

		classes[f.record.Id] = m.Results
		record = m.Results
	}

	str := ""
	for _, r := range record.Profiles {
		str += r.Name + "\n"
	}

	//return []byte(fmt.Sprintf("%+v\n", f.record)), nil
	return []byte(str), nil
Hugo Hörnquist's avatar
Hugo Hörnquist committed
	// return []byte(greeting), nil
Hugo Hörnquist's avatar
Hugo Hörnquist committed
}