<commit_before>// Copyright 2019 Google LLC
//
// 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 google

import (
	"context"
	"sort"
	"testing"

	"github.com/GoogleCloudPlatform/terraform-validator/ancestrymanager"
	tfjson "github.com/hashicorp/terraform-json"
	"github.com/pkg/errors"
	"github.com/stretchr/testify/assert"
)

const testProject = "test-project"

func newTestConverter() (*Converter, error) {
	ctx := context.Background()
	ancestry := ""
	project := testProject
	offline := true
	ancestryManager, err := ancestrymanager.New(context.Background(), project, ancestry, offline)
	if err != nil {
		return nil, errors.Wrap(err, "constructing resource manager client")
	}
	c, err := NewConverter(ctx, ancestryManager, project, "", offline)
	if err != nil {
		return nil, errors.Wrap(err, "building converter")
	}
	return c, nil
}

func TestSortByName(t *testing.T) {
	cases := []struct {
		name           string
		unsorted       []Asset
		expectedSorted []Asset
	}{
		{
			name:           "Empty",
			unsorted:       []Asset{},
			expectedSorted: []Asset{},
		},
		{
			name:           "BCAtoABC",
			unsorted:       []Asset{{Name: "b", Type: "b-type"}, {Name: "c", Type: "c-type"}, {Name: "a", Type: "a-type"}},
			expectedSorted: []Asset{{Name: "a", Type: "a-type"}, {Name: "b", Type: "b-type"}, {Name: "c", Type: "c-type"}},
		},
	}

	for _, c := range cases {
		t.Run(c.name, func(t *testing.T) {
			assets := c.unsorted
			sort.Sort(byName(assets))
			assert.EqualValues(t, c.expectedSorted, assets)
		})
	}
}

func TestAddResourceChanges_unknownResourceIgnored(t *testing.T) {
	rc := tfjson.ResourceChange{
		Address:      "whatever.google_unknown.foo",
		Mode:         "managed",
		Type:         "google_unknown",
		Name:         "foo",
		ProviderName: "google",
		Change: &tfjson.Change{
			Actions: tfjson.Actions{"change"},
			Before:  nil,
			After:   nil,
		},
	}
	c, err := newTestConverter()
	assert.Nil(t, err)
	err = c.AddResourceChanges([]*tfjson.ResourceChange{&rc})
	assert.Nil(t, err)
	assert.EqualValues(t, map[string]Asset{}, c.assets)
}

func TestAddResourceChanges_unsupportedResourceIgnored(t *testing.T) {
	rc := tfjson.ResourceChange{
		Address:      "whatever.google_unknown.foo",
		Mode:         "managed",
		Type:         "google_unsupported",
		Name:         "foo",
		ProviderName: "google",
		Change: &tfjson.Change{
			Actions: tfjson.Actions{"change"},
			Before:  nil,
			After:   nil,
		},
	}
	c, err := newTestConverter()
	assert.Nil(t, err)

	// fake that this resource is known to the provider; it will never be "supported" by the
	// converter.
	c.schema.ResourcesMap[rc.Type] = c.schema.ResourcesMap["google_compute_disk"]

	err = c.AddResourceChanges([]*tfjson.ResourceChange{&rc})
	assert.Nil(t, err)
	assert.EqualValues(t, map[string]Asset{}, c.assets)
}

func TestAddResourceChanges_noopIgnored(t *testing.T) {
	rc := tfjson.ResourceChange{
		Address:      "whatever.google_compute_disk.foo",
		Mode:         "managed",
		Type:         "google_compute_disk",
		Name:         "foo",
		ProviderName: "google",
		Change: &tfjson.Change{
			Actions: tfjson.Actions{"no-op"},
			Before:  nil,
			After:   nil,
		},
	}
	c, err := newTestConverter()
	assert.Nil(t, err)

	err = c.AddResourceChanges([]*tfjson.ResourceChange{&rc})
	assert.Nil(t, err)
	assert.EqualValues(t, map[string]Asset{}, c.assets)
}

func TestAddResourceChanges_deleteProcessed(t *testing.T) {
	rc := tfjson.ResourceChange{
		Address:      "whatever.google_compute_disk.foo",
		Mode:         "managed",
		Type:         "google_compute_disk",
		Name:         "foo",
		ProviderName: "google",
		Change: &tfjson.Change{
			Actions: tfjson.Actions{"delete"},
			Before: map[string]interface{}{
				"project": testProject,
				"name":    "test-disk",
				"type":    "pd-ssd",
				"zone":    "us-central1-a",
				"image":   "projects/debian-cloud/global/images/debian-8-jessie-v20170523",
				"labels": map[string]interface{}{
					"environment": "dev",
				},
				"physical_block_size_bytes": 4096,
			},
			After: nil,
		},
	}
	c, err := newTestConverter()
	assert.Nil(t, err)

	err = c.AddResourceChanges([]*tfjson.ResourceChange{&rc})
	assert.Nil(t, err)
	assert.EqualValues(t, map[string]Asset{}, c.assets)
}

func TestAddResourceChanges_createOrUpdateOrDeleteCreateProcessed(t *testing.T) {
	cases := []struct {
		name    string
		actions tfjson.Actions
	}{
		{
			name:    "Create",
			actions: tfjson.Actions{"create"},
		},
		{
			name:    "Update",
			actions: tfjson.Actions{"update"},
		},
		{
			name:    "DeleteCreate",
			actions: tfjson.Actions{"delete", "create"},
		},
	}
	for _, c := range cases {
		t.Run(c.name, func(t *testing.T) {
			rc := tfjson.ResourceChange{
				Address:      "whatever.google_compute_disk.foo",
				Mode:         "managed",
				Type:         "google_compute_disk",
				Name:         "foo",
				ProviderName: "google",
				Change: &tfjson.Change{
					Actions: c.actions,
					Before:  nil, // Ignore Before because it's unused
					After: map[string]interface{}{
						"project": testProject,
						"name":    "test-disk",
						"type":    "pd-ssd",
						"zone":    "us-central1-a",
						"image":   "projects/debian-cloud/global/images/debian-8-jessie-v20170523",
						"labels": map[string]interface{}{
							"environment": "dev",
						},
						"physical_block_size_bytes": 4096,
					},
				},
			}
			c, err := newTestConverter()
			assert.Nil(t, err)

			err = c.AddResourceChanges([]*tfjson.ResourceChange{&rc})
			assert.Nil(t, err)

			caiKey := "compute.googleapis.com/Disk//compute.googleapis.com/projects/test-project/zones/us-central1-a/disks/test-disk"
			assert.Contains(t, c.assets, caiKey)
		})
	}
}

func TestAddDuplicatedResources(t *testing.T) {
	rcb1 := tfjson.ResourceChange{
		Address:      "google_billing_budget.budget1",
		Mode:         "managed",
		Type:         "google_billing_budget",
		Name:         "budget1",
		ProviderName: "google",
		Change: &tfjson.Change{
			Actions: tfjson.Actions{"create"},
			Before:  nil,
			After: map[string]interface{}{
				"all_updates_rule": []map[string]interface{}{},
				"amount": []map[string]interface{}{
					{
						"last_period_amount": nil,
						"specified_amount": []map[string]interface{}{
							{
								"currency_code": "USD",
								"nanos":         nil,
								"units":         "100",
							},
						},
					},
				},
				"billing_account": "000000-000000-000000",
				"budget_filter": []map[string]interface{}{
					{
						"credit_types_treatment": "INCLUDE_ALL_CREDITS",
					},
				},
				"display_name": "Example Billing Budget 1",
				"threshold_rules": []map[string]interface{}{
					{
						"spend_basis":       "CURRENT_SPEND",
						"threshold_percent": 0.5,
					},
				},
				"timeouts": nil,
			},
		},
	}
	rcb2 := tfjson.ResourceChange{
		Address:      "google_billing_budget.budget2",
		Mode:         "managed",
		Type:         "google_billing_budget",
		Name:         "budget2",
		ProviderName: "google",
		Change: &tfjson.Change{
			Actions: tfjson.Actions{"create"},
			Before:  nil,
			After: map[string]interface{}{
				"all_updates_rule": []map[string]interface{}{},
				"amount": []map[string]interface{}{
					{
						"last_period_amount": nil,
						"specified_amount": []map[string]interface{}{
							{
								"currency_code": "USD",
								"nanos":         nil,
								"units":         "100",
							},
						},
					},
				},
				"billing_account": "000000-000000-000000",
				"budget_filter": []map[string]interface{}{
					{
						"credit_types_treatment": "INCLUDE_ALL_CREDITS",
					},
				},
				"display_name": "Example Billing Budget 2",
				"threshold_rules": []map[string]interface{}{
					{
						"spend_basis":       "CURRENT_SPEND",
						"threshold_percent": 0.5,
					},
				},
				"timeouts": nil,
			},
		},
	}
	rcp1 := tfjson.ResourceChange{
		Address:      "google_project.my_project1",
		Mode:         "managed",
		Type:         "google_project",
		Name:         "my_project1",
		ProviderName: "google",
		Change: &tfjson.Change{
			Actions: tfjson.Actions{"create"},
			Before:  nil,
			After: map[string]interface{}{
				"auto_create_network": true,
				"billing_account":     "000000-000000-000000",
				"labels":              nil,
				"name":                "My Project1",
				"org_id":              "00000000000000",
				"timeouts":            nil,
			},
		},
	}
	rcp2 := tfjson.ResourceChange{
		Address:      "google_project.my_project2",
		Mode:         "managed",
		Type:         "google_project",
		Name:         "my_project2",
		ProviderName: "google",
		Change: &tfjson.Change{
			Actions: tfjson.Actions{"create"},
			Before:  nil,
			After: map[string]interface{}{
				"auto_create_network": true,
				"billing_account":     "000000-000000-000000",
				"labels":              nil,
				"name":                "My Project2",
				"org_id":              "00000000000000",
				"timeouts":            nil,
			},
		},
	}
	c, err := newTestConverter()
	assert.Nil(t, err)

	err = c.AddResourceChanges([]*tfjson.ResourceChange{&rcb1, &rcb2, &rcp1, &rcp2})
	assert.Nil(t, err)

	caiKeyBilling := "cloudbilling.googleapis.com/ProjectBillingInfo//cloudbilling.googleapis.com/projects/test-project/billingInfo"
	assert.Contains(t, c.assets, caiKeyBilling)

	caiKeyProject := "cloudresourcemanager.googleapis.com/Project//cloudresourcemanager.googleapis.com/projects/test-project"
	assert.Contains(t, c.assets, caiKeyProject)
}
<commit_msg>add unit test for storage with module with unknown value<commit_after>// Copyright 2019 Google LLC
//
// 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 google

import (
	"context"
	"sort"
	"testing"

	"github.com/GoogleCloudPlatform/terraform-validator/ancestrymanager"
	tfjson "github.com/hashicorp/terraform-json"
	"github.com/pkg/errors"
	"github.com/stretchr/testify/assert"
)

const testProject = "test-project"

func newTestConverter() (*Converter, error) {
	ctx := context.Background()
	ancestry := ""
	project := testProject
	offline := true
	ancestryManager, err := ancestrymanager.New(context.Background(), project, ancestry, offline)
	if err != nil {
		return nil, errors.Wrap(err, "constructing resource manager client")
	}
	c, err := NewConverter(ctx, ancestryManager, project, "", offline)
	if err != nil {
		return nil, errors.Wrap(err, "building converter")
	}
	return c, nil
}

func TestSortByName(t *testing.T) {
	cases := []struct {
		name           string
		unsorted       []Asset
		expectedSorted []Asset
	}{
		{
			name:           "Empty",
			unsorted:       []Asset{},
			expectedSorted: []Asset{},
		},
		{
			name:           "BCAtoABC",
			unsorted:       []Asset{{Name: "b", Type: "b-type"}, {Name: "c", Type: "c-type"}, {Name: "a", Type: "a-type"}},
			expectedSorted: []Asset{{Name: "a", Type: "a-type"}, {Name: "b", Type: "b-type"}, {Name: "c", Type: "c-type"}},
		},
	}

	for _, c := range cases {
		t.Run(c.name, func(t *testing.T) {
			assets := c.unsorted
			sort.Sort(byName(assets))
			assert.EqualValues(t, c.expectedSorted, assets)
		})
	}
}

func TestAddResourceChanges_unknownResourceIgnored(t *testing.T) {
	rc := tfjson.ResourceChange{
		Address:      "whatever.google_unknown.foo",
		Mode:         "managed",
		Type:         "google_unknown",
		Name:         "foo",
		ProviderName: "google",
		Change: &tfjson.Change{
			Actions: tfjson.Actions{"change"},
			Before:  nil,
			After:   nil,
		},
	}
	c, err := newTestConverter()
	assert.Nil(t, err)
	err = c.AddResourceChanges([]*tfjson.ResourceChange{&rc})
	assert.Nil(t, err)
	assert.EqualValues(t, map[string]Asset{}, c.assets)
}

func TestAddResourceChanges_unsupportedResourceIgnored(t *testing.T) {
	rc := tfjson.ResourceChange{
		Address:      "whatever.google_unknown.foo",
		Mode:         "managed",
		Type:         "google_unsupported",
		Name:         "foo",
		ProviderName: "google",
		Change: &tfjson.Change{
			Actions: tfjson.Actions{"change"},
			Before:  nil,
			After:   nil,
		},
	}
	c, err := newTestConverter()
	assert.Nil(t, err)

	// fake that this resource is known to the provider; it will never be "supported" by the
	// converter.
	c.schema.ResourcesMap[rc.Type] = c.schema.ResourcesMap["google_compute_disk"]

	err = c.AddResourceChanges([]*tfjson.ResourceChange{&rc})
	assert.Nil(t, err)
	assert.EqualValues(t, map[string]Asset{}, c.assets)
}

func TestAddResourceChanges_noopIgnored(t *testing.T) {
	rc := tfjson.ResourceChange{
		Address:      "whatever.google_compute_disk.foo",
		Mode:         "managed",
		Type:         "google_compute_disk",
		Name:         "foo",
		ProviderName: "google",
		Change: &tfjson.Change{
			Actions: tfjson.Actions{"no-op"},
			Before:  nil,
			After:   nil,
		},
	}
	c, err := newTestConverter()
	assert.Nil(t, err)

	err = c.AddResourceChanges([]*tfjson.ResourceChange{&rc})
	assert.Nil(t, err)
	assert.EqualValues(t, map[string]Asset{}, c.assets)
}

func TestAddResourceChanges_deleteProcessed(t *testing.T) {
	rc := tfjson.ResourceChange{
		Address:      "whatever.google_compute_disk.foo",
		Mode:         "managed",
		Type:         "google_compute_disk",
		Name:         "foo",
		ProviderName: "google",
		Change: &tfjson.Change{
			Actions: tfjson.Actions{"delete"},
			Before: map[string]interface{}{
				"project": testProject,
				"name":    "test-disk",
				"type":    "pd-ssd",
				"zone":    "us-central1-a",
				"image":   "projects/debian-cloud/global/images/debian-8-jessie-v20170523",
				"labels": map[string]interface{}{
					"environment": "dev",
				},
				"physical_block_size_bytes": 4096,
			},
			After: nil,
		},
	}
	c, err := newTestConverter()
	assert.Nil(t, err)

	err = c.AddResourceChanges([]*tfjson.ResourceChange{&rc})
	assert.Nil(t, err)
	assert.EqualValues(t, map[string]Asset{}, c.assets)
}

func TestAddResourceChanges_createOrUpdateOrDeleteCreateProcessed(t *testing.T) {
	cases := []struct {
		name    string
		actions tfjson.Actions
	}{
		{
			name:    "Create",
			actions: tfjson.Actions{"create"},
		},
		{
			name:    "Update",
			actions: tfjson.Actions{"update"},
		},
		{
			name:    "DeleteCreate",
			actions: tfjson.Actions{"delete", "create"},
		},
	}
	for _, c := range cases {
		t.Run(c.name, func(t *testing.T) {
			rc := tfjson.ResourceChange{
				Address:      "whatever.google_compute_disk.foo",
				Mode:         "managed",
				Type:         "google_compute_disk",
				Name:         "foo",
				ProviderName: "google",
				Change: &tfjson.Change{
					Actions: c.actions,
					Before:  nil, // Ignore Before because it's unused
					After: map[string]interface{}{
						"project": testProject,
						"name":    "test-disk",
						"type":    "pd-ssd",
						"zone":    "us-central1-a",
						"image":   "projects/debian-cloud/global/images/debian-8-jessie-v20170523",
						"labels": map[string]interface{}{
							"environment": "dev",
						},
						"physical_block_size_bytes": 4096,
					},
				},
			}
			c, err := newTestConverter()
			assert.Nil(t, err)

			err = c.AddResourceChanges([]*tfjson.ResourceChange{&rc})
			assert.Nil(t, err)

			caiKey := "compute.googleapis.com/Disk//compute.googleapis.com/projects/test-project/zones/us-central1-a/disks/test-disk"
			assert.Contains(t, c.assets, caiKey)
		})
	}
}

func TestAddDuplicatedResources(t *testing.T) {
	rcb1 := tfjson.ResourceChange{
		Address:      "google_billing_budget.budget1",
		Mode:         "managed",
		Type:         "google_billing_budget",
		Name:         "budget1",
		ProviderName: "google",
		Change: &tfjson.Change{
			Actions: tfjson.Actions{"create"},
			Before:  nil,
			After: map[string]interface{}{
				"all_updates_rule": []map[string]interface{}{},
				"amount": []map[string]interface{}{
					{
						"last_period_amount": nil,
						"specified_amount": []map[string]interface{}{
							{
								"currency_code": "USD",
								"nanos":         nil,
								"units":         "100",
							},
						},
					},
				},
				"billing_account": "000000-000000-000000",
				"budget_filter": []map[string]interface{}{
					{
						"credit_types_treatment": "INCLUDE_ALL_CREDITS",
					},
				},
				"display_name": "Example Billing Budget 1",
				"threshold_rules": []map[string]interface{}{
					{
						"spend_basis":       "CURRENT_SPEND",
						"threshold_percent": 0.5,
					},
				},
				"timeouts": nil,
			},
		},
	}
	rcb2 := tfjson.ResourceChange{
		Address:      "google_billing_budget.budget2",
		Mode:         "managed",
		Type:         "google_billing_budget",
		Name:         "budget2",
		ProviderName: "google",
		Change: &tfjson.Change{
			Actions: tfjson.Actions{"create"},
			Before:  nil,
			After: map[string]interface{}{
				"all_updates_rule": []map[string]interface{}{},
				"amount": []map[string]interface{}{
					{
						"last_period_amount": nil,
						"specified_amount": []map[string]interface{}{
							{
								"currency_code": "USD",
								"nanos":         nil,
								"units":         "100",
							},
						},
					},
				},
				"billing_account": "000000-000000-000000",
				"budget_filter": []map[string]interface{}{
					{
						"credit_types_treatment": "INCLUDE_ALL_CREDITS",
					},
				},
				"display_name": "Example Billing Budget 2",
				"threshold_rules": []map[string]interface{}{
					{
						"spend_basis":       "CURRENT_SPEND",
						"threshold_percent": 0.5,
					},
				},
				"timeouts": nil,
			},
		},
	}
	rcp1 := tfjson.ResourceChange{
		Address:      "google_project.my_project1",
		Mode:         "managed",
		Type:         "google_project",
		Name:         "my_project1",
		ProviderName: "google",
		Change: &tfjson.Change{
			Actions: tfjson.Actions{"create"},
			Before:  nil,
			After: map[string]interface{}{
				"auto_create_network": true,
				"billing_account":     "000000-000000-000000",
				"labels":              nil,
				"name":                "My Project1",
				"org_id":              "00000000000000",
				"timeouts":            nil,
			},
		},
	}
	rcp2 := tfjson.ResourceChange{
		Address:      "google_project.my_project2",
		Mode:         "managed",
		Type:         "google_project",
		Name:         "my_project2",
		ProviderName: "google",
		Change: &tfjson.Change{
			Actions: tfjson.Actions{"create"},
			Before:  nil,
			After: map[string]interface{}{
				"auto_create_network": true,
				"billing_account":     "000000-000000-000000",
				"labels":              nil,
				"name":                "My Project2",
				"org_id":              "00000000000000",
				"timeouts":            nil,
			},
		},
	}
	c, err := newTestConverter()
	assert.Nil(t, err)

	err = c.AddResourceChanges([]*tfjson.ResourceChange{&rcb1, &rcb2, &rcp1, &rcp2})
	assert.Nil(t, err)

	caiKeyBilling := "cloudbilling.googleapis.com/ProjectBillingInfo//cloudbilling.googleapis.com/projects/test-project/billingInfo"
	assert.Contains(t, c.assets, caiKeyBilling)

	caiKeyProject := "cloudresourcemanager.googleapis.com/Project//cloudresourcemanager.googleapis.com/projects/test-project"
	assert.Contains(t, c.assets, caiKeyProject)
}

func TestAddStorageModuleAfterUnknown(t *testing.T) {
	var nilValue map[string]interface{} = nil
	rc := tfjson.ResourceChange{
		Address:       "module.gcs_buckets.google_storage_bucket.buckets[0]",
		ModuleAddress: "module.gcs_buckets",
		Mode:          "managed",
		Type:          "google_storage_bucket",
		Name:          "buckets",
		Index:         0,
		ProviderName:  "google",
		Change: &tfjson.Change{
			Actions: tfjson.Actions{"create"},
			Before:  nil,
			After: map[string]interface{}{
				"cors": []interface{}{
					nilValue,
				},
				"default_event_based_hold": nil,
				"encryption": []interface{}{
					nilValue,
				},
				"lifecycle_rule":   []interface{}{},
				"location":         "US",
				"logging":          []interface{}{},
				"project":          "test-project",
				"requester_pays":   nil,
				"retention_policy": []interface{}{},
				"storage_class":    "MULTI_REGIONAL",
				"versioning": []interface{}{
					nilValue,
				},
				"website": []interface{}{
					nilValue,
				},
			},
		},
	}
	c, err := newTestConverter()
	assert.Nil(t, err)

	err = c.AddResourceChanges([]*tfjson.ResourceChange{&rc})
	assert.Nil(t, err)
	assert.Len(t, c.assets, 1)
	for key := range c.assets {
		assert.EqualValues(t, c.assets[key].Type, "storage.googleapis.com/Bucket")
	}

}
<|endoftext|>


<commit_before>package suite

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"html/template"
	"time"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	"k8s.io/api/apps/v1beta1"
	apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
	apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/util/yaml"
	"k8s.io/apimachinery/pkg/watch"
	appsv1beta1 "k8s.io/client-go/kubernetes/typed/apps/v1beta1"
	"k8s.io/client-go/rest"
	"k8s.io/client-go/tools/cache"
	"k8s.io/client-go/util/workqueue"
)

var config *rest.Config

type Params struct {
	Image string
}

var deploymentTemplate = `
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: elasticsearch-operator
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: elasticsearch-operator
    spec:
      containers:
      - name: elasticsearch-operator
        image: {{.Image}}
`

// Setup registers the custom resource definition/s
func Setup(c *rest.Config, image string) error {

	config = c

	// TODO: Use CopyConfig when bumping client-go to >= 4.0

	apiextensionsclientset := apiextensionsclient.NewForConfigOrDie(CopyConfig(config))

	queue := workqueue.New()

	informer := cache.NewSharedIndexInformer(
		&cache.ListWatch{
			ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
				return apiextensionsclientset.ApiextensionsV1beta1().
					CustomResourceDefinitions().List(metav1.ListOptions{})
			},
			WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
				return apiextensionsclientset.ApiextensionsV1beta1().
					CustomResourceDefinitions().Watch(metav1.ListOptions{})
			},
		},
		&apiextensionsv1beta1.CustomResourceDefinition{},
		0,
		cache.Indexers{},
	)

	informer.AddEventHandler(cache.ResourceEventHandlerFuncs{
		AddFunc: func(obj interface{}) {
			if key, err := cache.MetaNamespaceKeyFunc(obj); err == nil {
				queue.Add(key)
			}
		},
		DeleteFunc: func(obj interface{}) {
			if key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj); err == nil {
				queue.Add(key)
			}
		},
	})

	ctx := context.Background()

	go informer.Run(ctx.Done())

	if !cache.WaitForCacheSync(ctx.Done(), informer.HasSynced) {
		return errors.New("Failed waiting for cache sync")
	}

	var deployment *v1beta1.Deployment

	BeforeSuite(func() {
		clientset := appsv1beta1.NewForConfigOrDie(CopyConfig(config))

		deploymentClient := clientset.Deployments(metav1.NamespaceDefault)

		buf := &bytes.Buffer{}
		p := &Params{
			image,
		}

		tmpl := template.Must(template.New("").Parse(deploymentTemplate))
		err := tmpl.Execute(buf, p)
		Expect(err).NotTo(HaveOccurred())

		deploymentJSON, err := yaml.ToJSON(buf.Bytes())
		Expect(err).NotTo(HaveOccurred())

		err = json.Unmarshal(deploymentJSON, &deployment)
		Expect(err).NotTo(HaveOccurred())

		deployment, err = deploymentClient.Create(deployment)
		Expect(err).NotTo(HaveOccurred())

		timeout := time.After(time.Second * 10)

		for {
			select {
			case <-timeout:
				Fail("Creating custom resource definition exceeded timeout")
			default:
				key, _ := queue.Get()
				defer queue.Done(key)

				_, exists, err := informer.GetIndexer().GetByKey(key.(string))
				if err != nil {
					Fail(err.Error())
				}

				if exists {
					return
				}
			}
		}
	})

	AfterSuite(func() {
		clientset := appsv1beta1.NewForConfigOrDie(CopyConfig(config))

		deploymentClient := clientset.Deployments(metav1.NamespaceDefault)

		deletePolicy := metav1.DeletePropagationForeground
		err := deploymentClient.Delete(deployment.Name, &metav1.DeleteOptions{
			PropagationPolicy: &deletePolicy,
		})
		Expect(err).NotTo(HaveOccurred())

		timeout := time.After(time.Second * 10)
		for {
			select {
			case <-timeout:
				Fail("Deleting custom resource definition exceeded time out.")
			default:
				key, _ := queue.Get()
				defer queue.Done(key)

				_, exists, err := informer.GetIndexer().GetByKey(key.(string))
				if err != nil {
					Fail(err.Error())
				}

				if !exists {
					queue.ShutDown()
					return
				}
			}
		}
	})

	return nil
}

func CopyConfig(config *rest.Config) *rest.Config {
	return &rest.Config{
		Host:          config.Host,
		APIPath:       config.APIPath,
		Prefix:        config.Prefix,
		ContentConfig: config.ContentConfig,
		Username:      config.Username,
		Password:      config.Password,
		BearerToken:   config.BearerToken,
		Impersonate: rest.ImpersonationConfig{
			Groups:   config.Impersonate.Groups,
			Extra:    config.Impersonate.Extra,
			UserName: config.Impersonate.UserName,
		},
		AuthProvider:        config.AuthProvider,
		AuthConfigPersister: config.AuthConfigPersister,
		TLSClientConfig: rest.TLSClientConfig{
			Insecure:   config.TLSClientConfig.Insecure,
			ServerName: config.TLSClientConfig.ServerName,
			CertFile:   config.TLSClientConfig.CertFile,
			KeyFile:    config.TLSClientConfig.KeyFile,
			CAFile:     config.TLSClientConfig.CAFile,
			CertData:   config.TLSClientConfig.CertData,
			KeyData:    config.TLSClientConfig.KeyData,
			CAData:     config.TLSClientConfig.CAData,
		},
		UserAgent:     config.UserAgent,
		Transport:     config.Transport,
		WrapTransport: config.WrapTransport,
		QPS:           config.QPS,
		Burst:         config.Burst,
		RateLimiter:   config.RateLimiter,
		Timeout:       config.Timeout,
	}
}
<commit_msg>e2e: stop informer before cluster is deleted<commit_after>package suite

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"html/template"
	"time"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	"k8s.io/api/apps/v1beta1"
	apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
	apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/util/yaml"
	"k8s.io/apimachinery/pkg/watch"
	appsv1beta1 "k8s.io/client-go/kubernetes/typed/apps/v1beta1"
	"k8s.io/client-go/rest"
	"k8s.io/client-go/tools/cache"
	"k8s.io/client-go/util/workqueue"
)

var config *rest.Config

type Params struct {
	Image string
}

var deploymentTemplate = `
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: elasticsearch-operator
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: elasticsearch-operator
    spec:
      containers:
      - name: elasticsearch-operator
        image: {{.Image}}
`

// Setup registers the custom resource definition/s
func Setup(c *rest.Config, image string) error {

	config = c

	// TODO: Use CopyConfig when bumping client-go to >= 4.0

	apiextensionsclientset := apiextensionsclient.NewForConfigOrDie(CopyConfig(config))

	queue := workqueue.New()

	informer := cache.NewSharedIndexInformer(
		&cache.ListWatch{
			ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
				return apiextensionsclientset.ApiextensionsV1beta1().
					CustomResourceDefinitions().List(metav1.ListOptions{})
			},
			WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
				return apiextensionsclientset.ApiextensionsV1beta1().
					CustomResourceDefinitions().Watch(metav1.ListOptions{})
			},
		},
		&apiextensionsv1beta1.CustomResourceDefinition{},
		0,
		cache.Indexers{},
	)

	informer.AddEventHandler(cache.ResourceEventHandlerFuncs{
		AddFunc: func(obj interface{}) {
			if key, err := cache.MetaNamespaceKeyFunc(obj); err == nil {
				queue.Add(key)
			}
		},
		DeleteFunc: func(obj interface{}) {
			if key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj); err == nil {
				queue.Add(key)
			}
		},
	})

	ctx, cancel := context.WithCancel(context.Background())

	go informer.Run(ctx.Done())

	if !cache.WaitForCacheSync(ctx.Done(), informer.HasSynced) {
		cancel()
		return errors.New("Failed waiting for cache sync")
	}

	var deployment *v1beta1.Deployment

	BeforeSuite(func() {
		clientset := appsv1beta1.NewForConfigOrDie(CopyConfig(config))

		deploymentClient := clientset.Deployments(metav1.NamespaceDefault)

		buf := &bytes.Buffer{}
		p := &Params{
			image,
		}

		tmpl := template.Must(template.New("").Parse(deploymentTemplate))
		err := tmpl.Execute(buf, p)
		Expect(err).NotTo(HaveOccurred())

		deploymentJSON, err := yaml.ToJSON(buf.Bytes())
		Expect(err).NotTo(HaveOccurred())

		err = json.Unmarshal(deploymentJSON, &deployment)
		Expect(err).NotTo(HaveOccurred())

		deployment, err = deploymentClient.Create(deployment)
		Expect(err).NotTo(HaveOccurred())

		timeout := time.After(time.Second * 10)

		for {
			select {
			case <-timeout:
				Fail("Creating custom resource definition exceeded timeout")
			default:
				key, _ := queue.Get()
				defer queue.Done(key)

				_, exists, err := informer.GetIndexer().GetByKey(key.(string))
				if err != nil {
					Fail(err.Error())
				}

				if exists {
					return
				}
			}
		}
	})

	AfterSuite(func() {
		clientset := appsv1beta1.NewForConfigOrDie(CopyConfig(config))

		deploymentClient := clientset.Deployments(metav1.NamespaceDefault)

		deletePolicy := metav1.DeletePropagationForeground
		err := deploymentClient.Delete(deployment.Name, &metav1.DeleteOptions{
			PropagationPolicy: &deletePolicy,
		})
		Expect(err).NotTo(HaveOccurred())

		timeout := time.After(time.Second * 10)
		for {
			select {
			case <-timeout:
				Fail("Deleting custom resource definition exceeded time out.")
			default:
				key, _ := queue.Get()
				defer queue.Done(key)

				_, exists, err := informer.GetIndexer().GetByKey(key.(string))
				if err != nil {
					Fail(err.Error())
				}

				if !exists {
					cancel()
					queue.ShutDown()
					return
				}
			}
		}
	})

	return nil
}

func CopyConfig(config *rest.Config) *rest.Config {
	return &rest.Config{
		Host:          config.Host,
		APIPath:       config.APIPath,
		Prefix:        config.Prefix,
		ContentConfig: config.ContentConfig,
		Username:      config.Username,
		Password:      config.Password,
		BearerToken:   config.BearerToken,
		Impersonate: rest.ImpersonationConfig{
			Groups:   config.Impersonate.Groups,
			Extra:    config.Impersonate.Extra,
			UserName: config.Impersonate.UserName,
		},
		AuthProvider:        config.AuthProvider,
		AuthConfigPersister: config.AuthConfigPersister,
		TLSClientConfig: rest.TLSClientConfig{
			Insecure:   config.TLSClientConfig.Insecure,
			ServerName: config.TLSClientConfig.ServerName,
			CertFile:   config.TLSClientConfig.CertFile,
			KeyFile:    config.TLSClientConfig.KeyFile,
			CAFile:     config.TLSClientConfig.CAFile,
			CertData:   config.TLSClientConfig.CertData,
			KeyData:    config.TLSClientConfig.KeyData,
			CAData:     config.TLSClientConfig.CAData,
		},
		UserAgent:     config.UserAgent,
		Transport:     config.Transport,
		WrapTransport: config.WrapTransport,
		QPS:           config.QPS,
		Burst:         config.Burst,
		RateLimiter:   config.RateLimiter,
		Timeout:       config.Timeout,
	}
}
<|endoftext|>


<commit_before>package registry

import (
	"errors"
	"fmt"
	"net/url"

	"github.com/astaxie/beego"
	manifestV2 "github.com/docker/distribution/manifest/schema2"
	"github.com/snagles/docker-registry-manager/app/models"
	"github.com/snagles/docker-registry-manager/app/models/dockerhub"
)

type ImagesController struct {
	beego.Controller
}

// GetImages returns the template for the images page
func (c *ImagesController) GetImages() {

	registryName := c.Ctx.Input.Param(":registryName")
	repositoryName, _ := url.QueryUnescape(c.Ctx.Input.Param(":splat"))
	repositoryNameEncode := url.QueryEscape(repositoryName)
	c.Data["tagName"] = c.Ctx.Input.Param(":tagName")

	registry, _ := manager.AllRegistries.Registries[registryName]
	c.Data["registry"] = registry

	tag, _ := registry.Repositories[repositoryName].Tags[c.Ctx.Input.Param(":tagName")]
	c.Data["tag"] = tag

	labels := make(map[string]manager.KeywordInfo)
	for _, h := range tag.History {
		// run each command through the keyword lookup
		for _, cmd := range h.Commands {
			for _, keyword := range cmd.Keywords {
				labels[keyword] = manager.KeywordMapping[keyword]
			}
		}
	}
	c.Data["labels"] = labels

	// build the js chart dataset
	type segmentInfo struct {
		Stage    int      `json:"stage"`
		Cmd      string   `json:"cmd"`
		Keywords []string `json:"keywords"`
		Size     string
	}

	type dataset struct {
		Label            string   `json:"label"`
		Data             []int64  `json:"data"`
		BackgroundColor  []string `json:"backgroundColor"`
		BorderColor      []string `json:"borderColor"`
		BorderWidth      int64    `json:"borderWidth"`
		CutoutPercentage int64    `json:"cutoutPercentage"`

		// Custom data fields
		Info []segmentInfo `json:"info"`
	}

	var chart []dataset
	colors := []string{"#43A19E", "#7B43A1", "#F2317A", "#FF9824", "#58CF6C"}
	for i, history := range tag.History {
		ds := dataset{}
		for _, cmd := range history.Commands {
			ds.Data = append(ds.Data, 10)
			color := colors[0]
			colors = append(colors[:0], colors[1:]...)
			ds.BackgroundColor = append(ds.BackgroundColor, color)
			// add stage tooltip info
			ds.Info = append(ds.Info, segmentInfo{Stage: i + 1, Keywords: cmd.Keywords, Cmd: cmd.Cmd})
			colors = append(colors, color)
			if len(history.Commands) != 1 {
				ds.BorderColor = []string{"#FFF"}
				ds.BorderWidth = 1
			}
		}
		chart = append(chart, ds)
	}

	for i := len(chart)/2 - 1; i >= 0; i-- {
		opp := len(chart) - 1 - i
		chart[i], chart[opp] = chart[opp], chart[i]
	}

	c.Data["chart"] = chart
	c.Data["registryName"] = registryName
	c.Data["repositoryNameEncode"] = repositoryNameEncode
	c.Data["repositoryName"] = repositoryName

	// Compare the two manifest layers
	c.TplName = "images.tpl"
	hubManifest, err := dockerhub.GetManifest(repositoryName, tag.Name)
	if hubManifest == nil || err != nil {
		c.Data["dockerHub"] = struct {
			Error    error
			ImageURL string
		}{
			errors.New("Unable to retrieve information from dockerhub"),
			"",
		}
		return
	} else if hubManifest.SchemaVersion == tag.SchemaVersion {
		diffLayers := make(map[string]struct{})
		var size int64
		if err == nil {
			for _, layer := range tag.DeserializedManifest.Layers {
				diffLayers[layer.Digest.String()] = struct{}{}
			}
			for _, layer := range hubManifest.Layers {
				size += layer.Size
				if _, ok := diffLayers[layer.Digest.String()]; ok {
					delete(diffLayers, layer.Digest.String())
				}
			}
		}

		c.Data["dockerHub"] = struct {
			DiffLayers map[string]struct{}
			Manifest   *manifestV2.DeserializedManifest
			ImageURL   string
			Error      error
			Size       int64
		}{
			diffLayers,
			hubManifest,
			fmt.Sprintf("https://hub.docker.com/r/library/%s/tags/%s/", repositoryName, tag.Name),
			err,
			size,
		}
	} else {
		c.Data["dockerHub"] = struct {
			Error    error
			ImageURL string
		}{
			errors.New("Different manifest scheme versions"),
			fmt.Sprintf("https://hub.docker.com/r/library/%s/tags/%s/", repositoryName, tag.Name),
		}
	}
}
<commit_msg>Remove dockerhub image links, /r/library/ubuntu/tags/ no longer resolves<commit_after>package registry

import (
	"errors"
	"fmt"
	"net/url"

	"github.com/astaxie/beego"
	manifestV2 "github.com/docker/distribution/manifest/schema2"
	"github.com/snagles/docker-registry-manager/app/models"
	"github.com/snagles/docker-registry-manager/app/models/dockerhub"
)

type ImagesController struct {
	beego.Controller
}

// GetImages returns the template for the images page
func (c *ImagesController) GetImages() {

	registryName := c.Ctx.Input.Param(":registryName")
	repositoryName, _ := url.QueryUnescape(c.Ctx.Input.Param(":splat"))
	repositoryNameEncode := url.QueryEscape(repositoryName)
	c.Data["tagName"] = c.Ctx.Input.Param(":tagName")

	registry, _ := manager.AllRegistries.Registries[registryName]
	c.Data["registry"] = registry

	tag, _ := registry.Repositories[repositoryName].Tags[c.Ctx.Input.Param(":tagName")]
	c.Data["tag"] = tag

	labels := make(map[string]manager.KeywordInfo)
	for _, h := range tag.History {
		// run each command through the keyword lookup
		for _, cmd := range h.Commands {
			for _, keyword := range cmd.Keywords {
				labels[keyword] = manager.KeywordMapping[keyword]
			}
		}
	}
	c.Data["labels"] = labels

	// build the js chart dataset
	type segmentInfo struct {
		Stage    int      `json:"stage"`
		Cmd      string   `json:"cmd"`
		Keywords []string `json:"keywords"`
		Size     string
	}

	type dataset struct {
		Label            string   `json:"label"`
		Data             []int64  `json:"data"`
		BackgroundColor  []string `json:"backgroundColor"`
		BorderColor      []string `json:"borderColor"`
		BorderWidth      int64    `json:"borderWidth"`
		CutoutPercentage int64    `json:"cutoutPercentage"`

		// Custom data fields
		Info []segmentInfo `json:"info"`
	}

	var chart []dataset
	colors := []string{"#43A19E", "#7B43A1", "#F2317A", "#FF9824", "#58CF6C"}
	for i, history := range tag.History {
		ds := dataset{}
		for _, cmd := range history.Commands {
			ds.Data = append(ds.Data, 10)
			color := colors[0]
			colors = append(colors[:0], colors[1:]...)
			ds.BackgroundColor = append(ds.BackgroundColor, color)
			// add stage tooltip info
			ds.Info = append(ds.Info, segmentInfo{Stage: i + 1, Keywords: cmd.Keywords, Cmd: cmd.Cmd})
			colors = append(colors, color)
			if len(history.Commands) != 1 {
				ds.BorderColor = []string{"#FFF"}
				ds.BorderWidth = 1
			}
		}
		chart = append(chart, ds)
	}

	for i := len(chart)/2 - 1; i >= 0; i-- {
		opp := len(chart) - 1 - i
		chart[i], chart[opp] = chart[opp], chart[i]
	}

	c.Data["chart"] = chart
	c.Data["registryName"] = registryName
	c.Data["repositoryNameEncode"] = repositoryNameEncode
	c.Data["repositoryName"] = repositoryName

	// Compare the two manifest layers
	c.TplName = "images.tpl"
	hubManifest, err := dockerhub.GetManifest(repositoryName, tag.Name)
	if hubManifest == nil || err != nil {
		c.Data["dockerHub"] = struct {
			Error    error
			ImageURL string
		}{
			errors.New("Unable to retrieve information from dockerhub"),
			"",
		}
		return
	} else if hubManifest.SchemaVersion == tag.SchemaVersion {
		diffLayers := make(map[string]struct{})
		var size int64
		if err == nil {
			for _, layer := range tag.DeserializedManifest.Layers {
				diffLayers[layer.Digest.String()] = struct{}{}
			}
			for _, layer := range hubManifest.Layers {
				size += layer.Size
				if _, ok := diffLayers[layer.Digest.String()]; ok {
					delete(diffLayers, layer.Digest.String())
				}
			}
		}

		c.Data["dockerHub"] = struct {
			DiffLayers map[string]struct{}
			Manifest   *manifestV2.DeserializedManifest
			ImageURL   string
			Error      error
			Size       int64
		}{
			diffLayers,
			hubManifest,
			fmt.Sprintf("https://hub.docker.com/r/library/%s/tags", repositoryName),
			err,
			size,
		}
	} else {
		c.Data["dockerHub"] = struct {
			Error    error
			ImageURL string
		}{
			errors.New("Different manifest scheme versions"),
			fmt.Sprintf("https://hub.docker.com/r/library/%s/tags", repositoryName),
		}
	}
}
<|endoftext|>


<commit_before>// Copyright 2014 The Serviced Authors.
// 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 elasticsearch

import (
	//	"errors"

	"github.com/control-center/serviced/coordinator/client"
	"github.com/control-center/serviced/dao"
	"github.com/control-center/serviced/datastore"
	"github.com/control-center/serviced/domain/servicestate"
	"github.com/control-center/serviced/zzk"
	zkservice "github.com/control-center/serviced/zzk/service"
	"github.com/zenoss/glog"
)

func (this *ControlPlaneDao) getPoolBasedConnection(serviceID string) (client.Connection, error) {
	poolID, err := this.facade.GetPoolForService(datastore.Get(), serviceID)
	if err != nil {
		glog.V(2).Infof("ControlPlaneDao.GetPoolForService service=%+v err=%s", serviceID, err)
		return nil, err
	}

	poolBasedConn, err := zzk.GetLocalConnection(zzk.GeneratePoolPath(poolID))
	if err != nil {
		glog.Errorf("Error in getting a connection based on pool %v: %v", poolID, err)
		return nil, err
	}
	return poolBasedConn, nil
}

func (this *ControlPlaneDao) GetServiceState(request dao.ServiceStateRequest, state *servicestate.ServiceState) error {
	glog.V(3).Infof("ControlPlaneDao.GetServiceState: request=%v", request)
	*state = servicestate.ServiceState{}

	poolBasedConn, err := this.getPoolBasedConnection(request.ServiceID)
	if err != nil {
		return err
	}
	err = zkservice.GetServiceState(poolBasedConn, state, request.ServiceID, request.ServiceStateID)
	if state == nil {
		*state = servicestate.ServiceState{}
	}
	return err
}

func (this *ControlPlaneDao) GetServiceStates(serviceId string, states *[]servicestate.ServiceState) error {
	glog.V(2).Infof("ControlPlaneDao.GetServiceStates: serviceId=%s", serviceId)
	*states = make([]servicestate.ServiceState, 0)

	poolBasedConn, err := this.getPoolBasedConnection(serviceId)
	if err != nil {
		return err
	}

	serviceStates, err := zkservice.GetServiceStates(poolBasedConn, serviceId)
	if serviceStates != nil {
		*states = serviceStates
	}
	return err
}

/* This method assumes that if a service instance exists, it has not yet been terminated */
func (this *ControlPlaneDao) getNonTerminatedServiceStates(serviceId string, serviceStates *[]servicestate.ServiceState) error {
	glog.V(2).Infof("ControlPlaneDao.getNonTerminatedServiceStates: serviceId=%s", serviceId)

	poolBasedConn, err := this.getPoolBasedConnection(serviceId)
	if err != nil {
		return err
	}

	*serviceStates, err = zkservice.GetServiceStates(poolBasedConn, serviceId)
	return err
}

// Update the current state of a service instance.
func (this *ControlPlaneDao) UpdateServiceState(state servicestate.ServiceState, unused *int) error {
	glog.V(2).Infoln("ControlPlaneDao.UpdateServiceState state=%+v", state)

	poolBasedConn, err := this.getPoolBasedConnection(state.ServiceID)
	if err != nil {
		return err
	}

	return zkservice.UpdateServiceState(poolBasedConn, &state)
}

func (this *ControlPlaneDao) StopRunningInstance(request dao.HostServiceRequest, unused *int) error {
	myHost, err := this.facade.GetHost(datastore.Get(), request.HostID)
	if err != nil {
		glog.Errorf("Unable to get host %v: %v", request.HostID, err)
		return err
	}

	poolBasedConn, err := zzk.GetLocalConnection(zzk.GeneratePoolPath(myHost.PoolID))
	if err != nil {
		glog.Errorf("Error in getting a connection based on pool %v: %v", myHost.PoolID, err)
		return err
	}

	if err := zkservice.StopServiceInstance(poolBasedConn, request.HostID, request.ServiceStateID); err != nil {
		glog.Errorf("zkservice.StopServiceInstance failed (conn: %+v hostID: %v serviceStateID: %v): %v", poolBasedConn, request.HostID, request.ServiceStateID, err)
		return err
	}

	return nil
}

func (this *ControlPlaneDao) GetServiceStatus(serviceID string, status *map[string]dao.ServiceStatus) error {
	*status = make(map[string]dao.ServiceStatus, 0)
	poolBasedConn, err := this.getPoolBasedConnection(serviceID)
	if err != nil {
		return err
	}

	st, err := zkservice.GetServiceStatus(poolBasedConn, serviceID)
	if err != nil {
		glog.Errorf("zkservice.GetServiceStatus failed (conn: %+v serviceID: %s): %s", poolBasedConn, serviceID, err)
		return err
	}

	if st != nil {
		*status = st
	}

	return nil
}
<commit_msg>CC-425: Panic when deleting instance under a nonexistent host<commit_after>// Copyright 2014 The Serviced Authors.
// 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 elasticsearch

import (
	//	"errors"

	"github.com/control-center/serviced/coordinator/client"
	"github.com/control-center/serviced/dao"
	"github.com/control-center/serviced/datastore"
	"github.com/control-center/serviced/domain/servicestate"
	"github.com/control-center/serviced/zzk"
	zkservice "github.com/control-center/serviced/zzk/service"
	"github.com/zenoss/glog"
	"fmt"
)

func (this *ControlPlaneDao) getPoolBasedConnection(serviceID string) (client.Connection, error) {
	poolID, err := this.facade.GetPoolForService(datastore.Get(), serviceID)
	if err != nil {
		glog.V(2).Infof("ControlPlaneDao.GetPoolForService service=%+v err=%s", serviceID, err)
		return nil, err
	}

	poolBasedConn, err := zzk.GetLocalConnection(zzk.GeneratePoolPath(poolID))
	if err != nil {
		glog.Errorf("Error in getting a connection based on pool %v: %v", poolID, err)
		return nil, err
	}
	return poolBasedConn, nil
}

func (this *ControlPlaneDao) GetServiceState(request dao.ServiceStateRequest, state *servicestate.ServiceState) error {
	glog.V(3).Infof("ControlPlaneDao.GetServiceState: request=%v", request)
	*state = servicestate.ServiceState{}

	poolBasedConn, err := this.getPoolBasedConnection(request.ServiceID)
	if err != nil {
		return err
	}
	err = zkservice.GetServiceState(poolBasedConn, state, request.ServiceID, request.ServiceStateID)
	if state == nil {
		*state = servicestate.ServiceState{}
	}
	return err
}

func (this *ControlPlaneDao) GetServiceStates(serviceId string, states *[]servicestate.ServiceState) error {
	glog.V(2).Infof("ControlPlaneDao.GetServiceStates: serviceId=%s", serviceId)
	*states = make([]servicestate.ServiceState, 0)

	poolBasedConn, err := this.getPoolBasedConnection(serviceId)
	if err != nil {
		return err
	}

	serviceStates, err := zkservice.GetServiceStates(poolBasedConn, serviceId)
	if serviceStates != nil {
		*states = serviceStates
	}
	return err
}

/* This method assumes that if a service instance exists, it has not yet been terminated */
func (this *ControlPlaneDao) getNonTerminatedServiceStates(serviceId string, serviceStates *[]servicestate.ServiceState) error {
	glog.V(2).Infof("ControlPlaneDao.getNonTerminatedServiceStates: serviceId=%s", serviceId)

	poolBasedConn, err := this.getPoolBasedConnection(serviceId)
	if err != nil {
		return err
	}

	*serviceStates, err = zkservice.GetServiceStates(poolBasedConn, serviceId)
	return err
}

// Update the current state of a service instance.
func (this *ControlPlaneDao) UpdateServiceState(state servicestate.ServiceState, unused *int) error {
	glog.V(2).Infoln("ControlPlaneDao.UpdateServiceState state=%+v", state)

	poolBasedConn, err := this.getPoolBasedConnection(state.ServiceID)
	if err != nil {
		return err
	}

	return zkservice.UpdateServiceState(poolBasedConn, &state)
}

func (this *ControlPlaneDao) StopRunningInstance(request dao.HostServiceRequest, unused *int) error {
	myHost, err := this.facade.GetHost(datastore.Get(), request.HostID)
	if err != nil {
		glog.Errorf("Unable to get host %v: %v", request.HostID, err)
		return err
	}
	if myHost == nil {
		return fmt.Errorf("Host %s does not exist", request.HostID)
	}
	poolBasedConn, err := zzk.GetLocalConnection(zzk.GeneratePoolPath(myHost.PoolID))
	if err != nil {
		glog.Errorf("Error in getting a connection based on pool %v: %v", myHost.PoolID, err)
		return err
	}

	if err := zkservice.StopServiceInstance(poolBasedConn, request.HostID, request.ServiceStateID); err != nil {
		glog.Errorf("zkservice.StopServiceInstance failed (conn: %+v hostID: %v serviceStateID: %v): %v", poolBasedConn, request.HostID, request.ServiceStateID, err)
		return err
	}

	return nil
}

func (this *ControlPlaneDao) GetServiceStatus(serviceID string, status *map[string]dao.ServiceStatus) error {
	*status = make(map[string]dao.ServiceStatus, 0)
	poolBasedConn, err := this.getPoolBasedConnection(serviceID)
	if err != nil {
		return err
	}

	st, err := zkservice.GetServiceStatus(poolBasedConn, serviceID)
	if err != nil {
		glog.Errorf("zkservice.GetServiceStatus failed (conn: %+v serviceID: %s): %s", poolBasedConn, serviceID, err)
		return err
	}

	if st != nil {
		*status = st
	}

	return nil
}
<|endoftext|>


<commit_before>/*

	debuganimations is a very simple debug "game" designed to allow us to
	exercise component animations very directly and purely, in order to build
	and debug that system.

*/
package debuganimations

import (
	"errors"
	"github.com/jkomoros/boardgame"
)

//go:generate autoreader

type gameDelegate struct {
	boardgame.DefaultGameDelegate
}

func (g *gameDelegate) Name() string {
	return "debuganimations"
}

func (g *gameDelegate) DisplayName() string {
	return "Animations Debugger"
}

func (g *gameDelegate) Description() string {
	return "A game type designed to test all of the stack animations in one place"
}

func (g *gameDelegate) DefaultNumPlayeres() int {
	return 2
}

func (g *gameDelegate) MinNumPlayers() int {
	return 2
}

func (g *gameDelegate) MaxNumPlayers() int {
	return 2
}

func (g *gameDelegate) GameStateConstructor() boardgame.ConfigurableSubState {
	return new(gameState)
}

func (g *gameDelegate) PlayerStateConstructor(playerIndex boardgame.PlayerIndex) boardgame.ConfigurablePlayerState {
	return &playerState{
		playerIndex: playerIndex,
	}
}

func (g *gameDelegate) DistributeComponentToStarterStack(state boardgame.State, c *boardgame.Component) (boardgame.Stack, error) {
	game, _ := concreteStates(state)

	if c.Deck.Name() == tokensDeckName {

		if game.TokensTo.NumComponents() < 9 {
			return game.TokensTo, nil
		}

		if game.SanitizedTokensFrom.NumComponents() < 10 {
			return game.SanitizedTokensFrom, nil
		}

		if game.SanitizedTokensTo.NumComponents() < 9 {
			return game.SanitizedTokensTo, nil
		}

		return game.TokensFrom, nil
	}

	if game.FirstShortStack.NumComponents() < 1 {
		return game.FirstShortStack, nil
	}

	if game.SecondShortStack.NumComponents() < 1 {
		return game.SecondShortStack, nil
	}

	if game.DiscardStack.NumComponents() < 2 {
		return game.DiscardStack, nil
	}

	if game.HiddenCard.NumComponents() < 1 {
		return game.HiddenCard, nil
	}

	if game.FanStack.NumComponents() < 6 {
		return game.FanStack, nil
	}

	if game.FanDiscard.NumComponents() < 3 {
		return game.FanDiscard, nil
	}

	if game.VisibleStack.NumComponents() < 5 {
		return game.VisibleStack, nil
	}

	if game.HiddenStack.NumComponents() < 4 {
		return game.HiddenStack, nil
	}

	return game.DrawStack, nil

}

func (g *gameDelegate) FinishSetUp(state boardgame.MutableState) error {
	game, _ := concreteStates(state)

	game.DrawStack.Shuffle()

	return nil

}

func (g *gameDelegate) Diagram(state boardgame.State) string {
	return "Not implemented"
}

func (g *gameDelegate) CheckGameFinished(state boardgame.State) (finished bool, winners []boardgame.PlayerIndex) {
	//This debug game is never finished
	return false, nil
}

func (g *gameDelegate) ConfigureMoves() *boardgame.MoveTypeConfigBundle {
	return boardgame.NewMoveTypeConfigBundle().AddMoves(
		&moveMoveCardBetweenShortStacksConfig,
		&moveMoveCardBetweenDrawAndDiscardStacksConfig,
		&moveFlipHiddenCardConfig,
		&moveMoveCardBetweenFanStacksConfig,
		&moveVisibleShuffleCardsConfig,
		&moveMoveBetweenHiddenConfig,
		&moveMoveBetweenHiddenConfig,
		&moveMoveTokenConfig,
		&moveMoveTokenSanitizedConfig,
	)
}

func NewManager(storage boardgame.StorageManager) (*boardgame.GameManager, error) {
	chest := boardgame.NewComponentChest(nil)

	cards := boardgame.NewDeck()

	for _, val := range cardNames {
		cards.AddComponentMulti(&cardValue{
			Type: val,
		}, 3)
	}

	cards.SetShadowValues(&cardValue{
		Type: "<hidden>",
	})

	if err := chest.AddDeck(cardsDeckName, cards); err != nil {
		return nil, errors.New("Couldn't add deck: " + err.Error())
	}

	tokens := boardgame.NewDeck()

	tokens.AddComponentMulti(nil, 38)

	if err := chest.AddDeck(tokensDeckName, tokens); err != nil {
		return nil, errors.New("Couldnt add deck: " + err.Error())
	}

	return boardgame.NewGameManager(&gameDelegate{}, chest, storage)

}
<commit_msg>Oops, normal shuffle move was missing in debuganimations. Part of #398.<commit_after>/*

	debuganimations is a very simple debug "game" designed to allow us to
	exercise component animations very directly and purely, in order to build
	and debug that system.

*/
package debuganimations

import (
	"errors"
	"github.com/jkomoros/boardgame"
)

//go:generate autoreader

type gameDelegate struct {
	boardgame.DefaultGameDelegate
}

func (g *gameDelegate) Name() string {
	return "debuganimations"
}

func (g *gameDelegate) DisplayName() string {
	return "Animations Debugger"
}

func (g *gameDelegate) Description() string {
	return "A game type designed to test all of the stack animations in one place"
}

func (g *gameDelegate) DefaultNumPlayeres() int {
	return 2
}

func (g *gameDelegate) MinNumPlayers() int {
	return 2
}

func (g *gameDelegate) MaxNumPlayers() int {
	return 2
}

func (g *gameDelegate) GameStateConstructor() boardgame.ConfigurableSubState {
	return new(gameState)
}

func (g *gameDelegate) PlayerStateConstructor(playerIndex boardgame.PlayerIndex) boardgame.ConfigurablePlayerState {
	return &playerState{
		playerIndex: playerIndex,
	}
}

func (g *gameDelegate) DistributeComponentToStarterStack(state boardgame.State, c *boardgame.Component) (boardgame.Stack, error) {
	game, _ := concreteStates(state)

	if c.Deck.Name() == tokensDeckName {

		if game.TokensTo.NumComponents() < 9 {
			return game.TokensTo, nil
		}

		if game.SanitizedTokensFrom.NumComponents() < 10 {
			return game.SanitizedTokensFrom, nil
		}

		if game.SanitizedTokensTo.NumComponents() < 9 {
			return game.SanitizedTokensTo, nil
		}

		return game.TokensFrom, nil
	}

	if game.FirstShortStack.NumComponents() < 1 {
		return game.FirstShortStack, nil
	}

	if game.SecondShortStack.NumComponents() < 1 {
		return game.SecondShortStack, nil
	}

	if game.DiscardStack.NumComponents() < 2 {
		return game.DiscardStack, nil
	}

	if game.HiddenCard.NumComponents() < 1 {
		return game.HiddenCard, nil
	}

	if game.FanStack.NumComponents() < 6 {
		return game.FanStack, nil
	}

	if game.FanDiscard.NumComponents() < 3 {
		return game.FanDiscard, nil
	}

	if game.VisibleStack.NumComponents() < 5 {
		return game.VisibleStack, nil
	}

	if game.HiddenStack.NumComponents() < 4 {
		return game.HiddenStack, nil
	}

	return game.DrawStack, nil

}

func (g *gameDelegate) FinishSetUp(state boardgame.MutableState) error {
	game, _ := concreteStates(state)

	game.DrawStack.Shuffle()

	return nil

}

func (g *gameDelegate) Diagram(state boardgame.State) string {
	return "Not implemented"
}

func (g *gameDelegate) CheckGameFinished(state boardgame.State) (finished bool, winners []boardgame.PlayerIndex) {
	//This debug game is never finished
	return false, nil
}

func (g *gameDelegate) ConfigureMoves() *boardgame.MoveTypeConfigBundle {
	return boardgame.NewMoveTypeConfigBundle().AddMoves(
		&moveMoveCardBetweenShortStacksConfig,
		&moveMoveCardBetweenDrawAndDiscardStacksConfig,
		&moveFlipHiddenCardConfig,
		&moveMoveCardBetweenFanStacksConfig,
		&moveVisibleShuffleCardsConfig,
		&moveShuffleCardsConfig,
		&moveMoveBetweenHiddenConfig,
		&moveMoveBetweenHiddenConfig,
		&moveMoveTokenConfig,
		&moveMoveTokenSanitizedConfig,
	)
}

func NewManager(storage boardgame.StorageManager) (*boardgame.GameManager, error) {
	chest := boardgame.NewComponentChest(nil)

	cards := boardgame.NewDeck()

	for _, val := range cardNames {
		cards.AddComponentMulti(&cardValue{
			Type: val,
		}, 3)
	}

	cards.SetShadowValues(&cardValue{
		Type: "<hidden>",
	})

	if err := chest.AddDeck(cardsDeckName, cards); err != nil {
		return nil, errors.New("Couldn't add deck: " + err.Error())
	}

	tokens := boardgame.NewDeck()

	tokens.AddComponentMulti(nil, 38)

	if err := chest.AddDeck(tokensDeckName, tokens); err != nil {
		return nil, errors.New("Couldnt add deck: " + err.Error())
	}

	return boardgame.NewGameManager(&gameDelegate{}, chest, storage)

}
<|endoftext|>


<commit_before>package describe

import (
"fmt"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/cloudformation"
"github.com/aws/aws-sdk-go/aws/session"
)

func Cloudformation(svc *cloudformation.CloudFormation) (cloudformations *cloudformation.DescribeStacksOutput){

  params := &cloudformation.DescribeStacksInput{}
  resp, err := svc.DescribeStacks(params)

  if err != nil {
      // Print the error, cast err to awserr.Error to get the Code and
      // Message from an error.
      fmt.Println(err.Error())
      return
  }

  // Pretty-print the response data.
  cloudformations = resp
  return
}

func Account(svc *ec2.EC2) (attributes *ec2.DescribeAccountAttributesOutput){

  params := &ec2.DescribeAccountAttributesInput{
    AttributeNames: []*string{
      aws.String("supported-platforms"),
      aws.String("default-vpc"),
      aws.String("max-instances"),
      aws.String("vpc-max-security-groups-per-interface"),
      aws.String("max-elastic-ips"),
      aws.String("vpc-max-elastic-ips"),
      },
      DryRun: aws.Bool(false),
      }
      resp, err := svc.DescribeAccountAttributes(params)

      if err != nil {
        // Print the error, cast err to awserr.Error to get the Code and
        // Message from an error.
        fmt.Println(err.Error())
        return
      }

  // Pretty-print the response data.
  attributes = resp
  return
}

func Acl(svc *ec2.EC2) (acls *ec2.DescribeNetworkAclsOutput){
	params := &ec2.DescribeNetworkAclsInput{
		DryRun: aws.Bool(false),
	}
	resp, err := svc.DescribeNetworkAcls(params)

	if err != nil {
		// Print the error, cast err to awserr.Error to get the Code and
		// Message from an error.
		fmt.Println(err.Error())
		return
	}

	// Pretty-print the response data.
	acls = resp
  return
}

func Az(svc *ec2.EC2) (azs *ec2.DescribeAvailabilityZonesOutput){

	params := &ec2.DescribeAvailabilityZonesInput{
		DryRun: aws.Bool(false),
	}
	resp, err := svc.DescribeAvailabilityZones(params)

	if err != nil {
	    // Print the error, cast err to awserr.Error to get the Code and
	    // Message from an error.
		fmt.Println(err.Error())
		return
	}

	// Pretty-print the response data.
	azs = resp
  return
}

func Customer_gateway(svc *ec2.EC2) (customer_gateways *ec2.DescribeCustomerGatewaysOutput){

  params := &ec2.DescribeCustomerGatewaysInput{
    DryRun: aws.Bool(false),
  }
  resp, err := svc.DescribeCustomerGateways(params)

  if err != nil {
    // Print the error, cast err to awserr.Error to get the Code and
    // Message from an error.
    fmt.Println(err.Error())
    return
  }

  // Pretty-print the response data.
  customer_gateways = resp
  return
}

func Dhcp(svc *ec2.EC2) (dhcps *ec2.DescribeDhcpOptionsOutput){

  params := &ec2.DescribeDhcpOptionsInput{
    DryRun: aws.Bool(false),
  }
  resp, err := svc.DescribeDhcpOptions(params)

  if err != nil {
    // Print the error, cast err to awserr.Error to get the Code and
    // Message from an error.
    fmt.Println(err.Error())
    return
  }

  // Pretty-print the response data.
  dhcps = resp
  return
}

func Eip(svc *ec2.EC2) (eips *ec2.DescribeAddressesOutput){

  params := &ec2.DescribeAddressesInput{
    DryRun: aws.Bool(false),
  }
  resp, err := svc.DescribeAddresses(params)

  if err != nil {
      // Print the error, cast err to awserr.Error to get the Code and
      // Message from an error.
    fmt.Println(err.Error())
    return
  }

  // Pretty-print the response data.
  eips = resp
  return
}

func Flowlog(svc *ec2.EC2) (flowlogs *ec2.DescribeFlowLogsOutput){

  params := &ec2.DescribeFlowLogsInput{
      MaxResults: aws.Int64(10),
  }
  resp, err := svc.DescribeFlowLogs(params)

  if err != nil {
      // Print the error, cast err to awserr.Error to get the Code and
      // Message from an error.
      fmt.Println(err.Error())
      return
  }

  // Pretty-print the response data.
  flowlogs = resp
  return
}

func Igw(svc *ec2.EC2) (igws *ec2.DescribeInternetGatewaysOutput){

	params := &ec2.DescribeInternetGatewaysInput{
	  DryRun: aws.Bool(false),
	}
	resp, err := svc.DescribeInternetGateways(params)

	if err != nil {
	  // Print the error, cast err to awserr.Error to get the Code and
	  // Message from an error.
	  fmt.Println(err.Error())
	  return
	}

	// Pretty-print the response data.
	igws = resp
  return
}

func Image(svc *ec2.EC2, owner string) (images *ec2.DescribeImagesOutput){

  params := &ec2.DescribeImagesInput{
    DryRun: aws.Bool(false),
    Owners: []*string{
      aws.String(owner),
    },
  }
  resp, err := svc.DescribeImages(params)

  if err != nil {
    // Print the error, cast err to awserr.Error to get the Code and
    // Message from an error.
    fmt.Println(err.Error())
    return
  }

  // Pretty-print the response data.
  images = resp
  return
}

func Instance(svc *ec2.EC2) (instances *ec2.DescribeInstancesOutput){

	params := &ec2.DescribeInstancesInput{
	  DryRun: aws.Bool(false),
	  MaxResults: aws.Int64(100),
    Filters: []*ec2.Filter{
        &ec2.Filter{
            Name: aws.String("instance-state-name"),
            Values: []*string{
                aws.String("running"),
                aws.String("pending"),
            },
        },
    },
	}
	resp, err := svc.DescribeInstances(params)

	if err != nil {
	  // Print the error, cast err to awserr.Error to get the Code and
	  // Message from an error.
	  fmt.Println(err.Error())
	  return
	}

	// Pretty-print the response data.
	instances = resp
  return
}

func Nat(svc *ec2.EC2) (nats *ec2.DescribeNatGatewaysOutput){

	params := &ec2.DescribeNatGatewaysInput{
		MaxResults: aws.Int64(100),
	}
	resp, err := svc.DescribeNatGateways(params)

	if err != nil {
		// Print the error, cast err to awserr.Error to get the Code and
		// Message from an error.
		fmt.Println(err.Error())
		return
	}

	// Pretty-print the response data.
	nats = resp
  return
}

func Nic(svc *ec2.EC2) (nics *ec2.DescribeNetworkInterfacesOutput){

	params := &ec2.DescribeNetworkInterfacesInput{
		DryRun: aws.Bool(false),
	}
	resp, err := svc.DescribeNetworkInterfaces(params)

	if err != nil {
		// Print the error, cast err to awserr.Error to get the Code and
		// Message from an error.
		fmt.Println(err.Error())
		return
	}

	// Pretty-print the response data.
	nics = resp
  return
}

func Placement_group(svc *ec2.EC2) (placement_groups *ec2.DescribePlacementGroupsOutput){

  params := &ec2.DescribePlacementGroupsInput{
    DryRun: aws.Bool(false),
  }
  resp, err := svc.DescribePlacementGroups(params)

  if err != nil {
    // Print the error, cast err to awserr.Error to get the Code and
    // Message from an error.
    fmt.Println(err.Error())
    return
  }

  // Pretty-print the response data.
  placement_groups = resp
  return
}

func Region() (regions *ec2.DescribeRegionsOutput){

  sess, err := session.NewSession(&aws.Config{Region: aws.String(`us-west-2`)})
  if err != nil {
    fmt.Println("failed to create session,", err)
    return
  }

  svc := ec2.New(sess)

	params := &ec2.DescribeRegionsInput{
	  DryRun: aws.Bool(false),
	}
	resp, err := svc.DescribeRegions(params)

	if err != nil {
		// Print the error, cast err to awserr.Error to get the Code and
		// Message from an error.
		fmt.Println(err.Error())
		return
	}

	// Pretty-print the response data.
	regions = resp
  return
}

func Route_table(svc *ec2.EC2) (route_tables *ec2.DescribeRouteTablesOutput){

	params := &ec2.DescribeRouteTablesInput{
	  DryRun: aws.Bool(false),
	}
	resp, err := svc.DescribeRouteTables(params)

	if err != nil {
	  // Print the error, cast err to awserr.Error to get the Code and
	  // Message from an error.
	  fmt.Println(err.Error())
	  return
	}

	// Pretty-print the response data.
	route_tables = resp
  return
}

func Security_group(svc *ec2.EC2) (security_groups *ec2.DescribeSecurityGroupsOutput){

	params := &ec2.DescribeSecurityGroupsInput{
	  DryRun: aws.Bool(false),
	}
	resp, err := svc.DescribeSecurityGroups(params)

	if err != nil {
	  // Print the error, cast err to awserr.Error to get the Code and
	  // Message from an error.
	  fmt.Println(err.Error())
	  return
	}

	// Pretty-print the response data.
	security_groups = resp
  return
}

func Snapshot(svc *ec2.EC2) (snapshots *ec2.DescribeSnapshotsOutput){

	params := &ec2.DescribeSnapshotsInput{
	  DryRun: aws.Bool(false),
	}
	resp, err := svc.DescribeSnapshots(params)

	if err != nil {
	  // Print the error, cast err to awserr.Error to get the Code and
	  // Message from an error.
	  fmt.Println(err.Error())
	  return
	}

	// Pretty-print the response data.
	snapshots = resp
  return
}

func Spot_price(svc *ec2.EC2) (spot_prices *ec2.DescribeSpotPriceHistoryOutput){

	params := &ec2.DescribeSpotPriceHistoryInput{
	  DryRun: aws.Bool(false),
	  MaxResults: aws.Int64(100),
	}
	resp, err := svc.DescribeSpotPriceHistory(params)

	if err != nil {
	  // Print the error, cast err to awserr.Error to get the Code and
	  // Message from an error.
	  fmt.Println(err.Error())
	  return
	}

	// Pretty-print the response data.
	spot_prices = resp
  return
}

func Volume(svc *ec2.EC2) (volumes *ec2.DescribeVolumesOutput){

	params := &ec2.DescribeVolumesInput{
	  DryRun: aws.Bool(false),
	  MaxResults: aws.Int64(100),
	}
	resp, err := svc.DescribeVolumes(params)

	if err != nil {
	  // Print the error, cast err to awserr.Error to get the Code and
	  // Message from an error.
	  fmt.Println(err.Error())
	  return
	}

	// Pretty-print the response data.
	volumes = resp
  return
}

func Subnet(svc *ec2.EC2) (subnets *ec2.DescribeSubnetsOutput){

	params := &ec2.DescribeSubnetsInput{
	  DryRun: aws.Bool(false),
	}
	resp, err := svc.DescribeSubnets(params)

	if err != nil {
	  // Print the error, cast err to awserr.Error to get the Code and
	  // Message from an error.
	  fmt.Println(err.Error())
	  return
	}

	// Pretty-print the response data.
	subnets = resp
  return
}

func Tag(svc *ec2.EC2) (tags *ec2.DescribeTagsOutput){

	params := &ec2.DescribeTagsInput{
	  DryRun: aws.Bool(false),
	  MaxResults: aws.Int64(100),
	}
	resp, err := svc.DescribeTags(params)

	if err != nil {
	  // Print the error, cast err to awserr.Error to get the Code and
	  // Message from an error.
	  fmt.Println(err.Error())
	  return
	}

	// Pretty-print the response data.
	tags = resp
  return
}

func Vpn_gateway(svc *ec2.EC2) (vpn_gateways *ec2.DescribeVpnGatewaysOutput){

	params := &ec2.DescribeVpnGatewaysInput{
	  DryRun: aws.Bool(false),
	}
	resp, err := svc.DescribeVpnGateways(params)

	if err != nil {
	  // Print the error, cast err to awserr.Error to get the Code and
	  // Message from an error.
	  fmt.Println(err.Error())
	  return
	}

	// Pretty-print the response data.
	vpn_gateways = resp
  return
}

func Vpn_connection(svc *ec2.EC2) (vpn_connections *ec2.DescribeVpnConnectionsOutput){

	params := &ec2.DescribeVpnConnectionsInput{
	  DryRun: aws.Bool(false),
	}
	resp, err := svc.DescribeVpnConnections(params)

	if err != nil {
	  // Print the error, cast err to awserr.Error to get the Code and
	  // Message from an error.
	  fmt.Println(err.Error())
	  return
	}

	// Pretty-print the response data.
	vpn_connections = resp
  return
}

func Vpc_peer(svc *ec2.EC2) (vpc_peers *ec2.DescribeVpcPeeringConnectionsOutput){

	params := &ec2.DescribeVpcPeeringConnectionsInput{
	  DryRun: aws.Bool(false),
	}
	resp, err := svc.DescribeVpcPeeringConnections(params)

	if err != nil {
	  // Print the error, cast err to awserr.Error to get the Code and
	  // Message from an error.
	  fmt.Println(err.Error())
	  return
	}

	// Pretty-print the response data.
	vpc_peers = resp
  return
}

func Vpc(svc *ec2.EC2) (vpcs *ec2.DescribeVpcsOutput){

	params := &ec2.DescribeVpcsInput{
	  DryRun: aws.Bool(false),
	}
	resp, err := svc.DescribeVpcs(params)

	if err != nil {
	  // Print the error, cast err to awserr.Error to get the Code and
	  // Message from an error.
	  fmt.Println(err.Error())
	  return
	}

	// Pretty-print the response data.
	vpcs = resp
  return
}

<commit_msg>adds describe for cloudformation<commit_after>package describe

import (
"fmt"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/cloudformation"
"github.com/aws/aws-sdk-go/aws/session"
)

func Cloudformation(svc *cloudformation.CloudFormation) (cloudformations *cloudformation.DescribeStacksOutput){

  params := &cloudformation.DescribeStacksInput{}
  resp, err := svc.DescribeStacks(params)

  if err != nil {
      // Print the error, cast err to awserr.Error to get the Code and
      // Message from an error.
      fmt.Println(err.Error())
      return
  }

  // Pretty-print the response data.
  cloudformations = resp
  return
}

func Account(svc *ec2.EC2) (attributes *ec2.DescribeAccountAttributesOutput){

  params := &ec2.DescribeAccountAttributesInput{
    AttributeNames: []*string{
      aws.String("supported-platforms"),
      aws.String("default-vpc"),
      aws.String("max-instances"),
      aws.String("vpc-max-security-groups-per-interface"),
      aws.String("max-elastic-ips"),
      aws.String("vpc-max-elastic-ips"),
      },
      DryRun: aws.Bool(false),
      }
      resp, err := svc.DescribeAccountAttributes(params)

      if err != nil {
        fmt.Println(err.Error())
        return
      }

  attributes = resp
  return
}

func Acl(svc *ec2.EC2) (acls *ec2.DescribeNetworkAclsOutput){
	params := &ec2.DescribeNetworkAclsInput{
		DryRun: aws.Bool(false),
	}
	resp, err := svc.DescribeNetworkAcls(params)

	if err != nil {
		fmt.Println(err.Error())
		return
	}

	acls = resp
  return
}

func Az(svc *ec2.EC2) (azs *ec2.DescribeAvailabilityZonesOutput){

	params := &ec2.DescribeAvailabilityZonesInput{
		DryRun: aws.Bool(false),
	}
	resp, err := svc.DescribeAvailabilityZones(params)

	if err != nil {
		fmt.Println(err.Error())
		return
	}

	azs = resp
  return
}

func Customer_gateway(svc *ec2.EC2) (customer_gateways *ec2.DescribeCustomerGatewaysOutput){

  params := &ec2.DescribeCustomerGatewaysInput{
    DryRun: aws.Bool(false),
  }
  resp, err := svc.DescribeCustomerGateways(params)

  if err != nil {
    fmt.Println(err.Error())
    return
  }

  customer_gateways = resp
  return
}

func Dhcp(svc *ec2.EC2) (dhcps *ec2.DescribeDhcpOptionsOutput){

  params := &ec2.DescribeDhcpOptionsInput{
    DryRun: aws.Bool(false),
  }
  resp, err := svc.DescribeDhcpOptions(params)

  if err != nil {
    fmt.Println(err.Error())
    return
  }

  dhcps = resp
  return
}

func Eip(svc *ec2.EC2) (eips *ec2.DescribeAddressesOutput){

  params := &ec2.DescribeAddressesInput{
    DryRun: aws.Bool(false),
  }
  resp, err := svc.DescribeAddresses(params)

  if err != nil {
    fmt.Println(err.Error())
    return
  }

  eips = resp
  return
}

func Flowlog(svc *ec2.EC2) (flowlogs *ec2.DescribeFlowLogsOutput){

  params := &ec2.DescribeFlowLogsInput{
      MaxResults: aws.Int64(10),
  }
  resp, err := svc.DescribeFlowLogs(params)

  if err != nil {
      fmt.Println(err.Error())
      return
  }

  flowlogs = resp
  return
}

func Igw(svc *ec2.EC2) (igws *ec2.DescribeInternetGatewaysOutput){

	params := &ec2.DescribeInternetGatewaysInput{
	  DryRun: aws.Bool(false),
	}
	resp, err := svc.DescribeInternetGateways(params)

	if err != nil {
	  fmt.Println(err.Error())
	  return
	}

	igws = resp
  return
}

func Image(svc *ec2.EC2, owner string) (images *ec2.DescribeImagesOutput){

  params := &ec2.DescribeImagesInput{
    DryRun: aws.Bool(false),
    Owners: []*string{
      aws.String(owner),
    },
  }
  resp, err := svc.DescribeImages(params)

  if err != nil {
    fmt.Println(err.Error())
    return
  }

  images = resp
  return
}

func Instance(svc *ec2.EC2) (instances *ec2.DescribeInstancesOutput){

	params := &ec2.DescribeInstancesInput{
	  DryRun: aws.Bool(false),
	  MaxResults: aws.Int64(100),
    Filters: []*ec2.Filter{
        &ec2.Filter{
            Name: aws.String("instance-state-name"),
            Values: []*string{
                aws.String("running"),
                aws.String("pending"),
            },
        },
    },
	}
	resp, err := svc.DescribeInstances(params)

	if err != nil {
	  fmt.Println(err.Error())
	  return
	}

	instances = resp
  return
}

func Nat(svc *ec2.EC2) (nats *ec2.DescribeNatGatewaysOutput){

	params := &ec2.DescribeNatGatewaysInput{
		MaxResults: aws.Int64(100),
	}
	resp, err := svc.DescribeNatGateways(params)

	if err != nil {
		fmt.Println(err.Error())
		return
	}

	nats = resp
  return
}

func Nic(svc *ec2.EC2) (nics *ec2.DescribeNetworkInterfacesOutput){

	params := &ec2.DescribeNetworkInterfacesInput{
		DryRun: aws.Bool(false),
	}
	resp, err := svc.DescribeNetworkInterfaces(params)

	if err != nil {
		fmt.Println(err.Error())
		return
	}

	nics = resp
  return
}

func Placement_group(svc *ec2.EC2) (placement_groups *ec2.DescribePlacementGroupsOutput){

  params := &ec2.DescribePlacementGroupsInput{
    DryRun: aws.Bool(false),
  }
  resp, err := svc.DescribePlacementGroups(params)

  if err != nil {
    fmt.Println(err.Error())
    return
  }

  placement_groups = resp
  return
}

func Region() (regions *ec2.DescribeRegionsOutput){

<<<<<<< HEAD
  sess, err := session.NewSession(&aws.Config{Region: aws.String(`us-west-2`)})
=======
  sess, err := session.NewSession()
>>>>>>> b3d36fafb8044bd8b74830377c77d217ac409831
  if err != nil {
    fmt.Println("failed to create session,", err)
    return
  }

  svc := ec2.New(sess)

	params := &ec2.DescribeRegionsInput{
	  DryRun: aws.Bool(false),
	}
	resp, err := svc.DescribeRegions(params)

	if err != nil {
		fmt.Println(err.Error())
		return
	}

	regions = resp
  return
}

func Route_table(svc *ec2.EC2) (route_tables *ec2.DescribeRouteTablesOutput){

	params := &ec2.DescribeRouteTablesInput{
	  DryRun: aws.Bool(false),
	}
	resp, err := svc.DescribeRouteTables(params)

	if err != nil {
	  fmt.Println(err.Error())
	  return
	}

	route_tables = resp
  return
}

func Security_group(svc *ec2.EC2) (security_groups *ec2.DescribeSecurityGroupsOutput){

	params := &ec2.DescribeSecurityGroupsInput{
	  DryRun: aws.Bool(false),
	}
	resp, err := svc.DescribeSecurityGroups(params)

	if err != nil {
	  fmt.Println(err.Error())
	  return
	}

	security_groups = resp
  return
}

func Snapshot(svc *ec2.EC2) (snapshots *ec2.DescribeSnapshotsOutput){

	params := &ec2.DescribeSnapshotsInput{
	  DryRun: aws.Bool(false),
	}
	resp, err := svc.DescribeSnapshots(params)

	if err != nil {
	  fmt.Println(err.Error())
	  return
	}

	snapshots = resp
  return
}

func Spot_price(svc *ec2.EC2) (spot_prices *ec2.DescribeSpotPriceHistoryOutput){

	params := &ec2.DescribeSpotPriceHistoryInput{
	  DryRun: aws.Bool(false),
	  MaxResults: aws.Int64(100),
	}
	resp, err := svc.DescribeSpotPriceHistory(params)

	if err != nil {
	  fmt.Println(err.Error())
	  return
	}

	spot_prices = resp
  return
}

func Volume(svc *ec2.EC2) (volumes *ec2.DescribeVolumesOutput){

	params := &ec2.DescribeVolumesInput{
	  DryRun: aws.Bool(false),
	  MaxResults: aws.Int64(100),
	}
	resp, err := svc.DescribeVolumes(params)

	if err != nil {
	  fmt.Println(err.Error())
	  return
	}

	volumes = resp
  return
}

func Subnet(svc *ec2.EC2) (subnets *ec2.DescribeSubnetsOutput){

	params := &ec2.DescribeSubnetsInput{
	  DryRun: aws.Bool(false),
	}
	resp, err := svc.DescribeSubnets(params)

	if err != nil {
	  fmt.Println(err.Error())
	  return
	}

	subnets = resp
  return
}

func Tag(svc *ec2.EC2) (tags *ec2.DescribeTagsOutput){

	params := &ec2.DescribeTagsInput{
	  DryRun: aws.Bool(false),
	  MaxResults: aws.Int64(100),
	}
	resp, err := svc.DescribeTags(params)

	if err != nil {
	  fmt.Println(err.Error())
	  return
	}

	tags = resp
  return
}

func Vpn_gateway(svc *ec2.EC2) (vpn_gateways *ec2.DescribeVpnGatewaysOutput){

	params := &ec2.DescribeVpnGatewaysInput{
	  DryRun: aws.Bool(false),
	}
	resp, err := svc.DescribeVpnGateways(params)

	if err != nil {
	  fmt.Println(err.Error())
	  return
	}

	vpn_gateways = resp
  return
}

func Vpn_connection(svc *ec2.EC2) (vpn_connections *ec2.DescribeVpnConnectionsOutput){

	params := &ec2.DescribeVpnConnectionsInput{
	  DryRun: aws.Bool(false),
	}
	resp, err := svc.DescribeVpnConnections(params)

	if err != nil {
	  fmt.Println(err.Error())
	  return
	}

	vpn_connections = resp
  return
}

func Vpc_peer(svc *ec2.EC2) (vpc_peers *ec2.DescribeVpcPeeringConnectionsOutput){

	params := &ec2.DescribeVpcPeeringConnectionsInput{
	  DryRun: aws.Bool(false),
	}
	resp, err := svc.DescribeVpcPeeringConnections(params)

	if err != nil {
	  fmt.Println(err.Error())
	  return
	}

	vpc_peers = resp
  return
}

func Vpc(svc *ec2.EC2) (vpcs *ec2.DescribeVpcsOutput){

	params := &ec2.DescribeVpcsInput{
	  DryRun: aws.Bool(false),
	}
	resp, err := svc.DescribeVpcs(params)

	if err != nil {
	  fmt.Println(err.Error())
	  return
	}

	vpcs = resp
  return
}
<|endoftext|>


<commit_before>
package server

import (

    "fmt"
    "time"
    "net/http"

    "github.com/gin-gonic/gin"
    "github.com/gorilla/websocket"
)

const (
	// Time allowed to write a message to the peer.
	writeWait = 10 * time.Second
	// Time allowed to read the next pong message from the peer.
	pongWait = 60 * time.Second
	// Send pings to peer with this period. Must be less than pongWait.
	pingPeriod = (pongWait * 9) / 10
	// Maximum message size allowed from peer.
	maxMessageSize = 512
)

var upgrader = websocket.Upgrader {
    ReadBufferSize:  1024,
    WriteBufferSize: 1024,
}

type WebSocket struct {}

func (ws *WebSocket) Handler(w http.ResponseWriter, r *http.Request) {
    conn, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        fmt.Println("Failed to set websocket upgrade:", err)
    } else {
        c := &Connection{send: make(chan []byte, 256), ws: conn}
        ag.register <- c
        go c.writePump()
        c.readPump()
    }
}

func (ws *WebSocket) Bind(app *App) {
    app.Engine.GET("/sync", func(c *gin.Context) {
        ws.Handler(c.Writer, c.Request)
    });
}

type Connection struct {
	// The websocket connection.
	ws *websocket.Conn
	// Buffered channel of outbound messages.
	send chan []byte
}

func (c *Connection) readPump() {
    defer func() {
		ag.unregister <- c
		c.ws.Close()
	}()
    c.ws.SetReadLimit(maxMessageSize)
	c.ws.SetReadDeadline(time.Now().Add(pongWait))
	c.ws.SetPongHandler(func(string) error { c.ws.SetReadDeadline(time.Now().Add(pongWait)); return nil })
	for {
		_, message, err := c.ws.ReadMessage()
		if err != nil {
			break
		}
		ag.broadcast <- message
	}
}

func (c *Connection) write(mt int, payload []byte) error {
    c.ws.SetWriteDeadline(time.Now().Add(writeWait))
    return c.ws.WriteMessage(mt, payload)
}

func (c *Connection) writePump() {
	ticker := time.NewTicker(pingPeriod)
	defer func() {
		ticker.Stop()
		c.ws.Close()
	}()
	for {
		select {
		case message, ok := <-c.send:
			if !ok {
				c.write(websocket.CloseMessage, []byte{})
				return
			}
			if err := c.write(websocket.TextMessage, message); err != nil {
				return
			}
		case <-ticker.C:
			if err := c.write(websocket.PingMessage, []byte{}); err != nil {
				return
			}
		}
	}
}

type Agent struct {
    // Registered connections.
	connections map[*Connection]bool
	// Inbound messages from the connections.
	broadcast chan []byte
	// Register requests from the connections.
	register chan *Connection
	// Unregister requests from connections.
	unregister chan *Connection
}

var ag = Agent {
    broadcast:   make(chan []byte),
	register:    make(chan *Connection),
	unregister:  make(chan *Connection),
	connections: make(map[*Connection]bool),
}

func (ag *Agent) run() {
	for {
		select {
		case c := <-ag.register:
			ag.connections[c] = true
		case c := <-ag.unregister:
			if _, ok := ag.connections[c]; ok {
				delete(ag.connections, c)
				close(c.send)
			}
		case m := <-ag.broadcast:
			for c := range ag.connections {
				select {
				case c.send <- m:
				default:
					close(c.send)
					delete(ag.connections, c)
				}
			}
		}
	}
}

<commit_msg>update websocket class to support session and sessions<commit_after>
package server

import (

    "fmt"
    "time"
    "net/http"

    "github.com/gin-gonic/gin"
    "github.com/gorilla/websocket"
)

const (
	// Time allowed to write a message to the peer.
	writeWait = 10 * time.Second
	// Time allowed to read the next pong message from the peer.
	pongWait = 60 * time.Second
	// Send pings to peer with this period. Must be less than pongWait.
	pingPeriod = (pongWait * 9) / 10
	// Maximum message size allowed from peer.
	maxMessageSize = 512
)

type WebSocket struct {
    Upgrader websocket.Upgrader
    Sessions *Sessions
}

func NewWebSocket() *WebSocket {
    sessions := CreateSessionsDB()
    ws := &WebSocket {
        Upgrader: websocket.Upgrader {
            ReadBufferSize:  1024,
            WriteBufferSize: 1024,
        },
        Sessions: sessions,
    }
    return ws
}

func (ws *WebSocket) Handler(w http.ResponseWriter, r *http.Request) {
    conn, err := ws.Upgrader.Upgrade(w, r, nil)
    if err != nil {
        fmt.Println("Failed to set websocket upgrade:", err)
    } else {
        s := ws.Sessions
        defer func() {
            s.UnBind(conn)
        }()
        s.Bind(conn).ReadMessages()
    }
}

func (ws *WebSocket) Bind(app *App) {
    app.Engine.GET("/sync", func(c *gin.Context) {
        ws.Handler(c.Writer, c.Request)
    });
}

<|endoftext|>


<commit_before>package gst

/*
#include <stdlib.h>
#include <gst/gst.h>
*/
import "C"

import (
	"github.com/lidouf/glib"
	"unsafe"
)

type ElementFactory struct {
	GstObj
}

func (f *ElementFactory) g() *C.GstElementFactory {
	return (*C.GstElementFactory)(f.GetPtr())
}

func (e *ElementFactory) AsElementFactory() *ElementFactory {
	return e
}

func (f *ElementFactory) Create(name string) *Element {
	n := (*C.gchar)(C.CString(name))
	defer C.free(unsafe.Pointer(n))

	ge := C.gst_element_factory_create(f.g(), n)
	if ge == nil {
		return nil
	}
	e := new(Element)
	e.SetPtr(glib.Pointer(ge))
	return e
}

/**
Get metadata from ElementFactory
*/
func (f *ElementFactory) GetMetadataKeys() []string {
	k := C.gst_element_factory_get_metadata_keys(f.g())
	if k == nil {
		return []string{}
	}
	defer C.free(unsafe.Pointer(k))

	return convertToGoSlice(k, 6)
}

func (f *ElementFactory) GetLongName() string {
	return C.GoString((*C.char)(C.gst_element_factory_get_metadata(f.g(), (*C.gchar)(C.CString(ELEMENT_METADATA_LONGNAME)))))
}

func (f *ElementFactory) GetKlass() string {
	return C.GoString((*C.char)(C.gst_element_factory_get_metadata(f.g(), (*C.gchar)(C.CString(ELEMENT_METADATA_KLASS)))))
}

func (f *ElementFactory) GetDescription() string {
	return C.GoString((*C.char)(C.gst_element_factory_get_metadata(f.g(), (*C.gchar)(C.CString(ELEMENT_METADATA_DESCRIPTION)))))
}

func (f *ElementFactory) GetAuthor() string {
	return C.GoString((*C.char)(C.gst_element_factory_get_metadata(f.g(), (*C.gchar)(C.CString(ELEMENT_METADATA_AUTHOR)))))
}

func (f *ElementFactory) GetDocumentationUri() string {
	return C.GoString((*C.char)(C.gst_element_factory_get_metadata(f.g(), (*C.gchar)(C.CString(ELEMENT_METADATA_DOC_URI)))))
}

func (f *ElementFactory) GetIconName() string {
	return C.GoString((*C.char)(C.gst_element_factory_get_metadata(f.g(), (*C.gchar)(C.CString(ELEMENT_METADATA_ICON_NAME)))))
}

func ElementFactoryMake(factory_name, name string) *Element {
	fn := (*C.gchar)(C.CString(factory_name))
	defer C.free(unsafe.Pointer(fn))
	n := (*C.gchar)(C.CString(name))
	defer C.free(unsafe.Pointer(n))
	ge := C.gst_element_factory_make(fn, n)
	if ge == nil {
		return nil
	}
	e := new(Element)
	e.SetPtr(glib.Pointer(ge))
	return e
}

func ElementFactoryFind(name string) *ElementFactory {
	n := (*C.gchar)(C.CString(name))
	defer C.free(unsafe.Pointer(n))

	gf := C.gst_element_factory_find(n)
	if gf == nil {
		return nil
	}

	f := new(ElementFactory)
	f.SetPtr(glib.Pointer(gf))

	return f
}
<commit_msg>add ElementFactory's GetNumPadTemplates implementation<commit_after>package gst

/*
#include <stdlib.h>
#include <gst/gst.h>
*/
import "C"

import (
	"github.com/lidouf/glib"
	"unsafe"
)

type ElementFactory struct {
	GstObj
}

func (f *ElementFactory) g() *C.GstElementFactory {
	return (*C.GstElementFactory)(f.GetPtr())
}

func (e *ElementFactory) AsElementFactory() *ElementFactory {
	return e
}

func (f *ElementFactory) Create(name string) *Element {
	n := (*C.gchar)(C.CString(name))
	defer C.free(unsafe.Pointer(n))

	ge := C.gst_element_factory_create(f.g(), n)
	if ge == nil {
		return nil
	}
	e := new(Element)
	e.SetPtr(glib.Pointer(ge))
	return e
}

/**
Get metadata from ElementFactory
*/
func (f *ElementFactory) GetMetadataKeys() []string {
	k := C.gst_element_factory_get_metadata_keys(f.g())
	if k == nil {
		return []string{}
	}
	defer C.free(unsafe.Pointer(k))

	return convertToGoSlice(k, 6)
}

func (f *ElementFactory) GetLongName() string {
	return C.GoString((*C.char)(C.gst_element_factory_get_metadata(f.g(), (*C.gchar)(C.CString(ELEMENT_METADATA_LONGNAME)))))
}

func (f *ElementFactory) GetKlass() string {
	return C.GoString((*C.char)(C.gst_element_factory_get_metadata(f.g(), (*C.gchar)(C.CString(ELEMENT_METADATA_KLASS)))))
}

func (f *ElementFactory) GetDescription() string {
	return C.GoString((*C.char)(C.gst_element_factory_get_metadata(f.g(), (*C.gchar)(C.CString(ELEMENT_METADATA_DESCRIPTION)))))
}

func (f *ElementFactory) GetAuthor() string {
	return C.GoString((*C.char)(C.gst_element_factory_get_metadata(f.g(), (*C.gchar)(C.CString(ELEMENT_METADATA_AUTHOR)))))
}

func (f *ElementFactory) GetDocumentationUri() string {
	return C.GoString((*C.char)(C.gst_element_factory_get_metadata(f.g(), (*C.gchar)(C.CString(ELEMENT_METADATA_DOC_URI)))))
}

func (f *ElementFactory) GetIconName() string {
	return C.GoString((*C.char)(C.gst_element_factory_get_metadata(f.g(), (*C.gchar)(C.CString(ELEMENT_METADATA_ICON_NAME)))))
}

func (f *ElementFactory) GetNumPadTemplates() uint {
	return uint(C.gst_element_factory_get_num_pad_templates(f.g()))
}

func ElementFactoryMake(factory_name, name string) *Element {
	fn := (*C.gchar)(C.CString(factory_name))
	defer C.free(unsafe.Pointer(fn))
	n := (*C.gchar)(C.CString(name))
	defer C.free(unsafe.Pointer(n))
	ge := C.gst_element_factory_make(fn, n)
	if ge == nil {
		return nil
	}
	e := new(Element)
	e.SetPtr(glib.Pointer(ge))
	return e
}

func ElementFactoryFind(name string) *ElementFactory {
	n := (*C.gchar)(C.CString(name))
	defer C.free(unsafe.Pointer(n))

	gf := C.gst_element_factory_find(n)
	if gf == nil {
		return nil
	}

	f := new(ElementFactory)
	f.SetPtr(glib.Pointer(gf))

	return f
}
<|endoftext|>