Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

liqoctl: add create VirtualNode command #1944

Merged
merged 1 commit into from
Aug 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions cmd/liqoctl/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,19 @@ import (
"k8s.io/klog/v2"
"k8s.io/kubectl/pkg/cmd/util"

"github.com/liqotech/liqo/pkg/liqoctl/create"
"github.com/liqotech/liqo/pkg/liqoctl/delete"
"github.com/liqotech/liqo/pkg/liqoctl/factory"
"github.com/liqotech/liqo/pkg/liqoctl/rest"
"github.com/liqotech/liqo/pkg/liqoctl/rest/virtualnode"
)

var liqoctl string

var liqoResources = []rest.APIProvider{
virtualnode.VirtualNode,
}

func init() {
liqoctl = os.Args[0]

Expand Down Expand Up @@ -117,6 +125,8 @@ func NewRootCommand(ctx context.Context) *cobra.Command {
cmd.AddCommand(newMoveCommand(ctx, f))
cmd.AddCommand(newVersionCommand(ctx, f))
cmd.AddCommand(newDocsCommand(ctx))
cmd.AddCommand(create.NewCreateCommand(ctx, liqoResources, f))
cmd.AddCommand(delete.NewDeleteCommand(ctx, liqoResources, f))
return cmd
}

Expand Down
2 changes: 2 additions & 0 deletions cmd/liqoctl/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
netv1alpha1 "github.com/liqotech/liqo/apis/net/v1alpha1"
offloadingv1alpha1 "github.com/liqotech/liqo/apis/offloading/v1alpha1"
sharingv1alpha1 "github.com/liqotech/liqo/apis/sharing/v1alpha1"
virtualkubeletv1alpha1 "github.com/liqotech/liqo/apis/virtualkubelet/v1alpha1"
liqocmd "github.com/liqotech/liqo/cmd/liqoctl/cmd"
)

Expand All @@ -36,6 +37,7 @@ func init() {
utilruntime.Must(netv1alpha1.AddToScheme(scheme.Scheme))
utilruntime.Must(offloadingv1alpha1.AddToScheme(scheme.Scheme))
utilruntime.Must(sharingv1alpha1.AddToScheme(scheme.Scheme))
utilruntime.Must(virtualkubeletv1alpha1.AddToScheme(scheme.Scheme))
}

func main() {
Expand Down
2 changes: 1 addition & 1 deletion pkg/identityManager/certificate.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func (certManager *identityManager) StoreIdentity(ctx context.Context, remoteClu
Labels: map[string]string{
localIdentitySecretLabel: "true",
discovery.ClusterIDLabel: remoteCluster.ClusterID,
certificateAvailableLabel: "true",
CertificateAvailableLabel: "true",
},
Annotations: map[string]string{
// one year starting from now
Expand Down
7 changes: 4 additions & 3 deletions pkg/identityManager/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ package identitymanager
const defaultOrganization = "liqo.io"

const (
localIdentitySecretLabel = "discovery.liqo.io/local-identity"
remoteTenantCSRLabel = "discovery.liqo.io/remote-tenant-csr"
certificateAvailableLabel = "discovery.liqo.io/certificate-available"
localIdentitySecretLabel = "discovery.liqo.io/local-identity"
remoteTenantCSRLabel = "discovery.liqo.io/remote-tenant-csr"
// CertificateAvailableLabel is the label used to identify the secrets containing a certificate.
CertificateAvailableLabel = "discovery.liqo.io/certificate-available"
)

const (
Expand Down
2 changes: 1 addition & 1 deletion pkg/identityManager/identityManager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ var _ = Describe("IdentityManager", func() {
commonSecretChecks := func(secret *v1.Secret) {
Expect(secret.Namespace).To(Equal(namespace.Name))
Expect(secret.GetLabels()).To(HaveKeyWithValue(localIdentitySecretLabel, "true"))
Expect(secret.GetLabels()).To(HaveKeyWithValue(certificateAvailableLabel, "true"))
Expect(secret.GetLabels()).To(HaveKeyWithValue(CertificateAvailableLabel, "true"))
Expect(secret.GetLabels()).To(HaveKeyWithValue(discovery.ClusterIDLabel, remoteCluster.ClusterID))
Expect(secret.GetAnnotations()).To(HaveKey(certificateExpireTimeAnnotation))
Expect(secret.Data[privateKeySecretKey]).To(Equal(key))
Expand Down
78 changes: 78 additions & 0 deletions pkg/liqoctl/completion/completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import (

discoveryv1alpha1 "github.com/liqotech/liqo/apis/discovery/v1alpha1"
offloadingv1alpha1 "github.com/liqotech/liqo/apis/offloading/v1alpha1"
virtualkubeletv1alpha1 "github.com/liqotech/liqo/apis/virtualkubelet/v1alpha1"
identitymanager "github.com/liqotech/liqo/pkg/identityManager"
"github.com/liqotech/liqo/pkg/liqoctl/factory"
"github.com/liqotech/liqo/pkg/utils/slice"
)
Expand Down Expand Up @@ -123,6 +125,24 @@ func Nodes(ctx context.Context, f *factory.Factory, argsLimit int) FnType {
return common(ctx, f, argsLimit, retriever)
}

// VirtualNodes returns a function to autocomplete virtual node names.
func VirtualNodes(ctx context.Context, f *factory.Factory, argsLimit int) FnType {
retriever := func(ctx context.Context, f *factory.Factory) ([]string, error) {
var virtualNodes virtualkubeletv1alpha1.VirtualNodeList
if err := f.CRClient.List(ctx, &virtualNodes, client.InNamespace(f.Namespace)); err != nil {
return nil, err
}

var names []string
for i := range virtualNodes.Items {
names = append(names, virtualNodes.Items[i].Name)
}
return names, nil
}

return common(ctx, f, argsLimit, retriever)
}

// ForeignClusters returns a function to autocomplete ForeignCluster names.
func ForeignClusters(ctx context.Context, f *factory.Factory, argsLimit int) FnType {
retriever := func(ctx context.Context, f *factory.Factory) ([]string, error) {
Expand All @@ -141,6 +161,64 @@ func ForeignClusters(ctx context.Context, f *factory.Factory, argsLimit int) FnT
return common(ctx, f, argsLimit, retriever)
}

// ClusterIDs returns a function to autocomplete ForeignCluster cluster IDs.
func ClusterIDs(ctx context.Context, f *factory.Factory, argsLimit int) FnType {
retriever := func(ctx context.Context, f *factory.Factory) ([]string, error) {
var foreignClusters discoveryv1alpha1.ForeignClusterList
if err := f.CRClient.List(ctx, &foreignClusters); err != nil {
return nil, err
}

var ids []string
for i := range foreignClusters.Items {
ids = append(ids, foreignClusters.Items[i].Spec.ClusterIdentity.ClusterID)
}
return ids, nil
}

return common(ctx, f, argsLimit, retriever)
}

// ClusterNames returns a function to autocomplete ForeignCluster cluster names.
func ClusterNames(ctx context.Context, f *factory.Factory, argsLimit int) FnType {
retriever := func(ctx context.Context, f *factory.Factory) ([]string, error) {
var foreignClusters discoveryv1alpha1.ForeignClusterList
if err := f.CRClient.List(ctx, &foreignClusters); err != nil {
return nil, err
}

var names []string
for i := range foreignClusters.Items {
names = append(names, foreignClusters.Items[i].Spec.ClusterIdentity.ClusterName)
}
return names, nil
}

return common(ctx, f, argsLimit, retriever)
}

// KubeconfigSecretNames returns a function to autocomplete kubeconfig secret names.
func KubeconfigSecretNames(ctx context.Context, f *factory.Factory, argsLimit int) FnType {
retriever := func(ctx context.Context, f *factory.Factory) ([]string, error) {
matchingLabels := client.MatchingLabels{
identitymanager.CertificateAvailableLabel: "true",
}

var secrets corev1.SecretList
if err := f.CRClient.List(ctx, &secrets, client.InNamespace(f.Namespace), matchingLabels); err != nil {
return nil, err
}

var names []string
for i := range secrets.Items {
names = append(names, secrets.Items[i].Name)
}
return names, nil
}

return common(ctx, f, argsLimit, retriever)
}

// PVCs returns a function to autocomplete PVC names.
func PVCs(ctx context.Context, f *factory.Factory, argsLimit int) FnType {
retriever := func(ctx context.Context, f *factory.Factory) ([]string, error) {
Expand Down
16 changes: 16 additions & 0 deletions pkg/liqoctl/create/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright 2019-2023 The Liqo 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 create contains the implementation of the 'create' command
package create
51 changes: 51 additions & 0 deletions pkg/liqoctl/create/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright 2019-2023 The Liqo 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 create

import (
"context"

"github.com/spf13/cobra"

"github.com/liqotech/liqo/pkg/liqoctl/factory"
"github.com/liqotech/liqo/pkg/liqoctl/rest"
)

// NewCreateCommand returns the cobra command for the create subcommand.
func NewCreateCommand(ctx context.Context, liqoResources []rest.APIProvider, f *factory.Factory) *cobra.Command {
options := &rest.CreateOptions{
Factory: f,
}

cmd := &cobra.Command{
Use: "create",
Short: "Create Liqo resources",
Long: "Create Liqo resources.",
Args: cobra.NoArgs,
}

f.AddNamespaceFlag(cmd.PersistentFlags())

for _, r := range liqoResources {
api := r()

apiOptions := api.APIOptions()
if apiOptions.EnableCreate {
cmd.AddCommand(api.Create(ctx, options))
}
}

return cmd
}
16 changes: 16 additions & 0 deletions pkg/liqoctl/delete/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright 2019-2023 The Liqo 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 delete contains the implementation of the 'delete' command
package delete
51 changes: 51 additions & 0 deletions pkg/liqoctl/delete/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright 2019-2023 The Liqo 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 delete

import (
"context"

"github.com/spf13/cobra"

"github.com/liqotech/liqo/pkg/liqoctl/factory"
"github.com/liqotech/liqo/pkg/liqoctl/rest"
)

// NewDeleteCommand returns the cobra command for the delete subcommand.
func NewDeleteCommand(ctx context.Context, liqoResources []rest.APIProvider, f *factory.Factory) *cobra.Command {
options := &rest.DeleteOptions{
Factory: f,
}

cmd := &cobra.Command{
Use: "delete",
Short: "Delete Liqo resources",
Long: "Delete Liqo resources.",
Args: cobra.NoArgs,
}

f.AddNamespaceFlag(cmd.PersistentFlags())

for _, r := range liqoResources {
api := r()

apiOptions := api.APIOptions()
if apiOptions.EnableDelete {
cmd.AddCommand(api.Delete(ctx, options))
}
}

return cmd
}
16 changes: 16 additions & 0 deletions pkg/liqoctl/rest/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright 2019-2023 The Liqo 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 rest contains the types and interfaces to interact with the Liqo API.
package rest
68 changes: 68 additions & 0 deletions pkg/liqoctl/rest/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright 2019-2023 The Liqo 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 rest

import (
"context"

"github.com/spf13/cobra"

"github.com/liqotech/liqo/pkg/liqoctl/factory"
)

// APIOptions contains the options for the API.
type APIOptions struct {
EnableCreate bool
EnableDelete bool
EnableGet bool
EnableUpdate bool
}

// CreateOptions contains the options for the create API.
type CreateOptions struct {
*factory.Factory

OutputFormat string
Name string
}

// DeleteOptions contains the options for the delete API.
type DeleteOptions struct {
*factory.Factory

Name string
}

// GetOptions contains the options for the get API.
type GetOptions struct {
*factory.Factory
}

// UpdateOptions contains the options for the update API.
type UpdateOptions struct {
*factory.Factory
}

// API is the interface that must be implemented by the API.
type API interface {
APIOptions() *APIOptions
Create(ctx context.Context, options *CreateOptions) *cobra.Command
Delete(ctx context.Context, options *DeleteOptions) *cobra.Command
Get(ctx context.Context, options *GetOptions) *cobra.Command
Update(ctx context.Context, options *UpdateOptions) *cobra.Command
}

// APIProvider is the function that returns the API.
type APIProvider func() API
Loading