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
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);
}
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();
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
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);
}
Hi Chris,
Thats great. Its just what I'm looking for. It would have taken me ages to figure that out.
Cheers
Steve
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?
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);
}
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
Cheers for that. It may make life a bit simpler.