VMware {code} Community
sjc84
Contributor
Contributor
Jump to solution

Replicating Folder Structure using Vi Perl Toolkit

Hi,

I am currently working in an environment that has two datacenters under one VC. We have a series of folders setup under the first datacenter to help manage the VMs in the environment.

What I'm trying to do is find a way to traverse the folder structure in the first datacenter and then replicate this structure under the second datacenter.

So far the code I've got lists all the folders in VC, but in no particular order, which makes recreating the structure a bit difficult.

my $datacenter_views = Vim::find_entity_views(view_type => 'Datacenter', filter => { name => "^$datacenter\$" });

foreach (@$datacenter_views) {

my $dc = $_->name;

my $folder_views = Vim::find_entity_views(view_type => 'Folder',

begin_entity => $_);

foreach (@$folder_views) {

printf '%-36.36s', "Folder Name: " . $_->name;

push @folder, $_->name;

if (defined($_->parent)){

my $parent = Vim::get_view(mo_ref => $_->parent);

push @fparent, $parent->name;

print "Parent Folder: " . $parent->name . "\n";

}

else

{

print "Parent Folder: RootFolder\n";

push @fparent, "RootFolder";

}

}

}

Does anyone have any ideas?

Cheers

Steve

0 Kudos
1 Solution

Accepted Solutions
kri-2
Hot Shot
Hot Shot
Jump to solution

Hi,

did you get it working? If not here is a litte sub which should do it.

Just call it at the end of the main, giving a ref to @dcstruct with it:

sub createmyfolders{

my $ref_dcstruct = $_[0];

my $dc = "datacenter2";

my $datacenter_view = Vim::find_entity_view(view_type => 'Datacenter', filter=>\{name=>$dc});

foreach my $entry (@\{$ref_dcstruct}){

my $cnt = 0;

my $folder_view = Vim::find_entity_view(view_type => 'Folder', begin_entity => $datacenter_view);

foreach my $foldername (@\{$entry}){

$cnt++;

next if $cnt<4; #skip the vmware internal folders (Datacenters, host and the datacenter itself, not nice but works)

print "$cnt: Creating $foldername\n";

eval{

$folder_view = $folder_view->CreateFolder(name => \[$foldername]);

$folder_view = Vim::find_entity_view(view_type => 'Folder', begin_entity => $folder_view);

};

if ($@) {

if($@->detail =~ /DuplicateName/){

print "$foldername allready exists, getting view of the existing one\n";

$folder_view = Vim::find_entity_view(view_type => 'Folder', begin_entity => $@->\{detail}->\{object});

}

}

}

}

}

sub main{

.....

createmyfolders(\@dcstruct);

}

View solution in original post

0 Kudos
8 Replies
kri-2
Hot Shot
Hot Shot
Jump to solution

Hi,

maby you can start with this one.

In the getfolders sub I first get all folders having no childs (these are the last folders in the tree). From these i am starting recursing to top getting all parents...

Hope this helps!

Chris

sub getparent{

my ($folder,$tab) = @_;

my $newfolder = $folder->\{parent};

my $parent = Vim::get_view(mo_ref => $newfolder);

unshift(@\{$tab}, $parent->\{name});

if($parent->\{parent}){

getparent($parent, $tab);

}

}

sub getfolders{

my $dc = $_[0];

my @dcstruct;

my $folder_views = Vim::find_entity_views(view_type => 'Folder', begin_entity => $dc);

foreach my $folder (@$folder_views){

if(!$folder->\{childEntity}){

my $tab = qw();

unshift(@\{$tab}, $folder->\{name});

getparent($folder, $tab, 0);

push(@dcstruct, $tab);

}

}

return @dcstruct;

}

sub main);

my @dcstruct = getfolders($datacenter_views);

foreach my $entry (@dcstruct){

my $cnt=0;

foreach(@\{$entry}){

$cnt++;

print "\n|" . "\_"x$cnt. "_".$_;

}

print "\n";

}

}

main();

sjc84
Contributor
Contributor
Jump to solution

Cheers for that.

Its tidier than my recursive version.

All I need to do now is figure out how to recreate it at the other datacenter.

Steve

0 Kudos
kri-2
Hot Shot
Hot Shot
Jump to solution

Hi,

did you get it working? If not here is a litte sub which should do it.

Just call it at the end of the main, giving a ref to @dcstruct with it:

sub createmyfolders{

my $ref_dcstruct = $_[0];

my $dc = "datacenter2";

my $datacenter_view = Vim::find_entity_view(view_type => 'Datacenter', filter=>\{name=>$dc});

foreach my $entry (@\{$ref_dcstruct}){

my $cnt = 0;

my $folder_view = Vim::find_entity_view(view_type => 'Folder', begin_entity => $datacenter_view);

foreach my $foldername (@\{$entry}){

$cnt++;

next if $cnt<4; #skip the vmware internal folders (Datacenters, host and the datacenter itself, not nice but works)

print "$cnt: Creating $foldername\n";

eval{

$folder_view = $folder_view->CreateFolder(name => \[$foldername]);

$folder_view = Vim::find_entity_view(view_type => 'Folder', begin_entity => $folder_view);

};

if ($@) {

if($@->detail =~ /DuplicateName/){

print "$foldername allready exists, getting view of the existing one\n";

$folder_view = Vim::find_entity_view(view_type => 'Folder', begin_entity => $@->\{detail}->\{object});

}

}

}

}

}

sub main{

.....

createmyfolders(\@dcstruct);

}

0 Kudos
sjc84
Contributor
Contributor
Jump to solution

Hi Chris,

Thats great. Its just what I'm looking for. It would have taken me ages to figure that out.

Cheers

Steve

0 Kudos
sjc84
Contributor
Contributor
Jump to solution

Hi Chris,

Just a quick follow up. When I run the code it creates the folders in the Hosts & Cluster view, do you know how I can get it to create them in the VM & Templates view?

0 Kudos
kri-2
Hot Shot
Hot Shot
Jump to solution

hm good question, I didn't care on this yet...

Message was edited by:

kri-2

At least I found the property which differs them...

with the "next if" we can skip other types, unfortunately I didnt get the property set while creating the directory...

if(!$folder->\{childEntity}){

my $tab = qw();

next if $folder->\{childType}[1] ne "ComputeResource"; #!skip other views

unshift(@\{$tab}, $folder->\{name});

getparent($folder, $tab, 0);

push(@dcstruct, $tab);

}

0 Kudos
hrobinson
VMware Employee
VMware Employee
Jump to solution

Another possible implementation is simply to

my $folders = Vim::find_entity_views (view_type => 'Folder');

foreach my $folder (@\{$folders}) {

my $path = Util::get_inventory_path ($folder);

print $folder->name, " ", $path, "\n";

}

You then have a structure that has a path for each folder. You can rebuild based on that structure.

get_inventory_path is a not very well documented feature that was introduced in beta-2. Maybe easier than tracing through children.

H

H

sjc84
Contributor
Contributor
Jump to solution

Cheers for that. It may make life a bit simpler.

0 Kudos